[英]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.