[英]Quadratic curve not rendered correctly on different devices
我正在尝试绘制一条中间有二次曲线的贝塞尔曲线。 该曲线在 iPhone 8 和 XS 上运行良好,但在其他设备上没有响应(即未正确呈现)。
下面是 iPhone XS 中的曲线图(正确)
和 iPhone XR(不正确)
我试图使用视图的约束来获取行的中间值,但不知何故它仍然无法正常工作
这是我绘制路径的代码:
//self.viewTabBorder is the grey line, which is a uiview with 1 pixel height
override func viewWillAppear(_ animated: Bool) {
let path = UIBezierPath()
path.move(to: CGPoint(x: self.viewTabBorder.center.x - self.btnHome.frame.width + 20, y: 0))
path.addQuadCurve(to: CGPoint(x: self.viewTabBorder.center.x + self.btnHome.frame.size.width - 20, y: 0), controlPoint: CGPoint(x: self.viewTabBorder.center.x, y: self.btnHome.frame.height + 5))
path.addLine(to: CGPoint(x: self.viewTabBorder.center.x + self.btnHome.frame.size.width - 20, y: 0))
let line = CAShapeLayer()
line.path = path.cgPath
line.strokeColor = UIColor(red: 224, green: 224, blue: 224).cgColor
line.fillColor = UIColor.white.cgColor
self.view.layer.addSublayer(line)
self.viewTabBorder.layer.addSublayer(line)
}
谁能告诉我我错过了什么? 非常感谢您提前!
几个观察:
您正在定义子图层到视图的路径。 在viewWillAppear
这样做还为时过早。 布局引擎可能没有完成应用约束,将视图放置在它们的最终位置。 在viewDidLayoutSubviews
定义路径,而不是在viewWillAppear
(也不是viewDidLoad
,也不是viewWillLayoutSubviews
)中。
这也有一个优点,如果您更改应用程序以支持多个方向或进行任何影响视图中约束的更改,我们将再次调用此viewDidLayoutSubviews
,以便根据需要正确更新这些子层。 如果您使用viewWillAppear
您的应用程序将不支持对您的视图进行动态更改(如果您需要的话)。
话虽如此,请注意可以多次调用viewDidLayoutSubviews
。 所以,你可以,例如,添加的子层viewDidLoad
的,但更新他们的路径viewDidLayoutSubviews
。
这在这里可能不是问题,但我建议您在为子图层定义路径时避免使用frame
或center
。 请记住,这两个属性是在其父视图的坐标系中定义的。 我建议您在尝试为子图层定义路径时,始终使用视图的bounds
(在视图自己的坐标系中定义),而不是其frame
(在其超级视图的坐标系中定义)。 例如,如果您想在定义子图层路径时使用视图的水平中心,请使用bounds.midX
而不是center.x
。
有时这无关紧要(如果视图在其父视图中是边到边的),但是 (a) 它表明对不同坐标系的误解; (b) 如果您添加安全区域或以其他方式调整视图的位置,使用frame
/ center
会给您带来麻烦。
一个稍微高级一点的概念:一旦你解决了眼前的问题,你可能会考虑将子视图的这个配置移动到UIView
子类中(使用它的layoutSubviews
方法),甚至可能使它成为一个@IBDesignable
类,这样你就可以看到它在界面中呈现建设者。 或者,另一种方法是将其包装在容器视图控制器中。 但无论哪种方式,这都有助于防止视图控制器“膨胀”。 这可能有点超出了这个问题的范围,但在你前进的过程中需要考虑一些事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.