Reputation: 2412
On button click, I want to create tooltip. and now I am getting a rectangle.
How do I add a pointer as below image?
Following is the code where I am trying to create tooltip like view
var ToolTipView = UIView()
func tooltip(){
for view in self.ToolTipView.subviews {
view.removeFromSuperview()
}
ToolTipView.removeFromSuperview()
ToolTipView.frame = CGRect(x:50, y:self.view.bounds.height-150, width:100, height:50)
ToolTipView.backgroundColor = UIColor(red:0, green:0, blue:0, alpha:0.7)
ToolTipView.layer.cornerRadius = 5.0
let txtLabel = UILabel(frame: CGRect(x:0, y:2, width:100, height:50))
txtLabel.text = "Click"
txtLabel.textAlignment = NSTextAlignment.Center
txtLabel.textColor = UIColor(red:1, green:1, blue:1, alpha:1)
txtLabel.font = UIFont(name:"HelveticaNeue", size: 16)
self.ToolTipView.addSubview(txtLabel)
self.view.addSubview(ToolTipView)
self.view.bringSubviewToFront(ToolTipView)
}
Upvotes: 1
Views: 15782
Reputation: 51
class MyViewController: UIViewController, UIPopoverPresentationControllerDelegate {
@objc func expandClicked(sender: UIButton!) {
let vc = UIViewController()
vc.view.backgroundColor = .white
display(viewcontroller: vc, size: CGSize(width: 150, height: 40), sender: sender)
}
func display(viewcontroller: UIViewController, size: CGSize, sender: UIView) {
let controller = viewcontroller
controller.modalPresentationStyle = .popover
controller.popoverPresentationController?.delegate = self
controller.preferredContentSize = size
let presentationController = controller.popoverPresentationController!
presentationController.sourceView = sender
presentationController.sourceRect = sender.bounds
presentationController.backgroundColor = .white
let buttonPosition = CGPoint(x: sender.bounds.minX, y: sender.bounds.maxY)
let p = sender.convert(buttonPosition, to: transactionTableView)
if (transactionTableView.bounds.maxY - p.y) > 70 {
presentationController.permittedArrowDirections = .up
} else {
presentationController.permittedArrowDirections = .down
}
self.present(controller, animated: true)
}
public func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.none
}
}
Upvotes: 0
Reputation: 201
How about this?
extension UIView {
func displayTooltip(_ message: String, completion: (() -> Void)? = nil) {
let tooltipBottomPadding: CGFloat = 12
let tooltipCornerRadius: CGFloat = 6
let tooltipAlpha: CGFloat = 0.95
let pointerBaseWidth: CGFloat = 14
let pointerHeight: CGFloat = 8
let padding = CGPoint(x: 18, y: 12)
let tooltip = UIView()
let tooltipLabel = UILabel()
tooltipLabel.text = " \(message) "
tooltipLabel.font = UIFont.systemFont(ofSize: 12)
tooltipLabel.contentMode = .center
tooltipLabel.textColor = .white
tooltipLabel.layer.backgroundColor = UIColor(red: 44 / 255, green: 44 / 255, blue: 44 / 255, alpha: 1).cgColor
tooltipLabel.layer.cornerRadius = tooltipCornerRadius
tooltip.addSubview(tooltipLabel)
tooltipLabel.translatesAutoresizingMaskIntoConstraints = false
tooltipLabel.bottomAnchor.constraint(equalTo: tooltip.bottomAnchor, constant: -pointerHeight).isActive = true
tooltipLabel.topAnchor.constraint(equalTo: tooltip.topAnchor).isActive = true
tooltipLabel.leadingAnchor.constraint(equalTo: tooltip.leadingAnchor).isActive = true
tooltipLabel.trailingAnchor.constraint(equalTo: tooltip.trailingAnchor).isActive = true
let labelHeight = message.height(withWidth: .greatestFiniteMagnitude, font: UIFont.systemFont(ofSize: 12)) + padding.y
let labelWidth = message.width(withHeight: .zero, font: UIFont.systemFont(ofSize: 12)) + padding.x
let pointerTip = CGPoint(x: labelWidth / 2, y: labelHeight + pointerHeight)
let pointerBaseLeft = CGPoint(x: labelWidth / 2 - pointerBaseWidth / 2, y: labelHeight)
let pointerBaseRight = CGPoint(x: labelWidth / 2 + pointerBaseWidth / 2, y: labelHeight)
let pointerPath = UIBezierPath()
pointerPath.move(to: pointerBaseLeft)
pointerPath.addLine(to: pointerTip)
pointerPath.addLine(to: pointerBaseRight)
pointerPath.close()
let pointer = CAShapeLayer()
pointer.path = pointerPath.cgPath
pointer.fillColor = UIColor(red: 44 / 255, green: 44 / 255, blue: 44 / 255, alpha: 1).cgColor
tooltip.layer.addSublayer(pointer)
(superview ?? self).addSubview(tooltip)
tooltip.translatesAutoresizingMaskIntoConstraints = false
tooltip.bottomAnchor.constraint(equalTo: topAnchor, constant: -tooltipBottomPadding + pointerHeight).isActive = true
tooltip.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
tooltip.heightAnchor.constraint(equalToConstant: labelHeight + pointerHeight).isActive = true
tooltip.widthAnchor.constraint(equalToConstant: labelWidth).isActive = true
tooltip.alpha = 0
UIView.animate(withDuration: 0.2, animations: {
tooltip.alpha = tooltipAlpha
}, completion: { _ in
UIView.animate(withDuration: 0.5, delay: 0.5, animations: {
tooltip.alpha = 0
}, completion: { _ in
tooltip.removeFromSuperview()
completion?()
})
})
}
}
with String extensions:
extension String {
func width(withHeight constrainedHeight: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: constrainedHeight)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
return ceil(boundingBox.width)
}
func height(withWidth constrainedWidth: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: constrainedWidth, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
return ceil(boundingBox.height)
}
}
Usage:
clickMeButton.displayTooltip("Clicked!")
Result: Dark gray tooltip with text shown over button
Upvotes: 1
Reputation: 8947
Try CocoaControls for a list of libraries developed for you. Simply search your query and there will be a list of controls. Chose one of them, and select download source. It will take to Github, download or use pod for that control and enjoy :)
Here is link to your desired query as example.
Upvotes: 1