我用 UIBezierPath 和 CAShapeLayer 制作的箭头如何指向 UILabel 的确切中心?
How can an arrow that I make with UIBezierPath and CAShapeLayer point to exact center of a UILabel?
我使用 UIBezierPath 和 CAShapeLayer 绘制了一个矩形视图,箭头指向视图上方的标签。
我希望箭头指向“P”标签的确切中心,并且 iPhone11 模拟器显示我想要的结果。但是,当我在 iPhone8 模拟器上 运行 时,箭头没有指向标签的中心。
为什么箭头指向 iPhone8 模拟器上的标签右侧有点偏?
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel! //horizontally and vertically aligned
@IBOutlet weak var pointingView: UIView! // leading & trailing constraints: 0, height:200
override func viewDidLoad() {
super.viewDidLoad()
drawPointingView()
}
private func drawPointingView() {
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 0, y: pointingView.frame.height))
path.addLine(to: CGPoint(x: pointingView.frame.width, y: pointingView.frame.height))
path.addLine(to: CGPoint(x: pointingView.frame.width, y: 0))
//draw an arrow pointing out to the center cordinate of the label.
path.addLine(to: CGPoint(x: label.center.x + 15, y: 0))
path.addLine(to: CGPoint(x: label.center.x, y: -18))
path.addLine(to: CGPoint(x: label.center.x - 15, y: 0))
path.close()
let shape = CAShapeLayer()
shape.fillColor = UIColor.blue.cgColor
shape.path = path.cgPath
shape.strokeColor = UIColor.lightGray.cgColor
shape.lineWidth = 1
pointingView.layer.addSublayer(shape)
}
}
iPhone11模拟器
iPhone8模拟器
因为你在viewDidLoad
画画,viewDidLoad
太早了。您所依赖的所有这些值,例如 pointingView.frame.width
,尚不为人所知。你必须等到 after 他们才知道。否则你只会在错误的地方画画(事实上你就是这样)。
类似的东西是布局的结果,所以你必须等到 viewDidLayoutSubviews
第一次被调用之后。
我使用 UIBezierPath 和 CAShapeLayer 绘制了一个矩形视图,箭头指向视图上方的标签。
我希望箭头指向“P”标签的确切中心,并且 iPhone11 模拟器显示我想要的结果。但是,当我在 iPhone8 模拟器上 运行 时,箭头没有指向标签的中心。
为什么箭头指向 iPhone8 模拟器上的标签右侧有点偏?
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel! //horizontally and vertically aligned
@IBOutlet weak var pointingView: UIView! // leading & trailing constraints: 0, height:200
override func viewDidLoad() {
super.viewDidLoad()
drawPointingView()
}
private func drawPointingView() {
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 0, y: pointingView.frame.height))
path.addLine(to: CGPoint(x: pointingView.frame.width, y: pointingView.frame.height))
path.addLine(to: CGPoint(x: pointingView.frame.width, y: 0))
//draw an arrow pointing out to the center cordinate of the label.
path.addLine(to: CGPoint(x: label.center.x + 15, y: 0))
path.addLine(to: CGPoint(x: label.center.x, y: -18))
path.addLine(to: CGPoint(x: label.center.x - 15, y: 0))
path.close()
let shape = CAShapeLayer()
shape.fillColor = UIColor.blue.cgColor
shape.path = path.cgPath
shape.strokeColor = UIColor.lightGray.cgColor
shape.lineWidth = 1
pointingView.layer.addSublayer(shape)
}
}
iPhone11模拟器
iPhone8模拟器
因为你在viewDidLoad
画画,viewDidLoad
太早了。您所依赖的所有这些值,例如 pointingView.frame.width
,尚不为人所知。你必须等到 after 他们才知道。否则你只会在错误的地方画画(事实上你就是这样)。
类似的东西是布局的结果,所以你必须等到 viewDidLayoutSubviews
第一次被调用之后。