无法将围绕 imageView 的圆形图层放在不同的 iPhone 设备上
Can't put circular layer that surrounds imageView on different iPhone devices
我该如何解决这个问题?
图像在故事板中设置了约束;另一个圆圈是用这些代码行设置的:
let centerY = profileImage.center.y+20+(self.navigationController?.navigationBar.frame.size.height)!
let centerX = profileImage.center.x
let center = CGPoint(x: centerX, y: centerY)
let trackLayer = CAShapeLayer()
let circularPath = UIBezierPath(arcCenter: center, radius: (profileImage.frame.width/2)+2, startAngle: -CGFloat.pi-CGFloat.pi/2, endAngle: CGFloat.pi/2, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = Functions.hexStringToUIColor(hex: "#3859B9").cgColor
trackLayer.lineWidth = 3
trackLayer.lineCap = kCALineCapRound
trackLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(trackLayer)
上iPhone7(右边那个)好像是对的。
对导航栏或状态栏的高度使用固定值会导致此类错误。您应该根据图像视图定位图层。为此,您可以简单地将图像视图的框架分配给您的图层:
trackLayer.frame = profileImage.frame
由于布局可能会因多种原因而改变(例如设备旋转),您应该在视图控制器的 viewDidLayoutSubviews
中执行此操作。
由于图层的框架现在比您的示例中的要小,因此您应该使用以下方法创建中心:
let center = CGPoint(x: profileImage.bounds.midX, y: profileImage.bounds.midY)
override func viewDidLayoutSubviews() {
let centerY = profileImage.center.y+20+(self.navigationController?.navigationBar.frame.size.height)!
let centerX = profileImage.center.x
let center = CGPoint(x: centerX, y: centerY)
let trackLayer = CAShapeLayer()
let circularPath = UIBezierPath(arcCenter: center, radius: (profileImage.frame.width/2)+2, startAngle: -CGFloat.pi-CGFloat.pi/2, endAngle: CGFloat.pi/2, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = Functions.hexStringToUIColor(hex: "#3859B9").cgColor
trackLayer.lineWidth = 3
trackLayer.lineCap = kCALineCapRound
trackLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(trackLayer)
}
或者直接在 viewDidAppear 中编写代码
这将解决问题。
- 将
layer
添加到 profileImage.layer
。
trackLayer.frame = profileImage.bounds
完整代码应该是这样的:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let center = CGPoint(x: profileImage.bounds.midX,
y: profileImage.bounds.midY)
let trackLayer = CAShapeLayer()
trackLayer.frame = profileImage.frame
let circularPath = UIBezierPath(arcCenter: center,
radius: (profileImage.frame.width / 2) + 2,
startAngle: -CGFloat.pi - CGFloat.pi / 2,
endAngle: CGFloat.pi / 2, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = Functions.hexStringToUIColor(hex: "#3859B9").cgColor
trackLayer.lineWidth = 3
trackLayer.lineCap = kCALineCapRound
trackLayer.fillColor = UIColor.clear.cgColor
profileImage.layer.addSublayer(trackLayer)
}
使用界面生成器:
- 将 UIView 拖放到图像视图上方
- 将视图自定义 class 更改为 CirculerProgressView
- 使用图像视图中心设置中心 X 和 Y 约束
设置高度和宽度限制(大于 imageView 高度和宽度)
@IBDesignable class CirculerProgressView: UIView {
override class var layerClass: AnyClass {
return CAShapeLayer.self
}
override func draw(_ rect: CGRect) {
super.draw(rect)
setupLayer()
}
private func setupLayer() {
let trackLayer = layer as! CAShapeLayer
let center = CGPoint(x: frame.width/2, y: frame.height/2)
let circularPath = UIBezierPath(arcCenter: center, radius: frame.width/2, startAngle: -CGFloat.pi-CGFloat.pi/2, endAngle: CGFloat.pi/2, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = UIColor.blue.cgColor
trackLayer.lineWidth = 3
trackLayer.lineCap = kCALineCapRound
trackLayer.fillColor = UIColor.clear.cgColor
}}
我该如何解决这个问题? 图像在故事板中设置了约束;另一个圆圈是用这些代码行设置的:
let centerY = profileImage.center.y+20+(self.navigationController?.navigationBar.frame.size.height)!
let centerX = profileImage.center.x
let center = CGPoint(x: centerX, y: centerY)
let trackLayer = CAShapeLayer()
let circularPath = UIBezierPath(arcCenter: center, radius: (profileImage.frame.width/2)+2, startAngle: -CGFloat.pi-CGFloat.pi/2, endAngle: CGFloat.pi/2, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = Functions.hexStringToUIColor(hex: "#3859B9").cgColor
trackLayer.lineWidth = 3
trackLayer.lineCap = kCALineCapRound
trackLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(trackLayer)
上iPhone7(右边那个)好像是对的。
对导航栏或状态栏的高度使用固定值会导致此类错误。您应该根据图像视图定位图层。为此,您可以简单地将图像视图的框架分配给您的图层:
trackLayer.frame = profileImage.frame
由于布局可能会因多种原因而改变(例如设备旋转),您应该在视图控制器的 viewDidLayoutSubviews
中执行此操作。
由于图层的框架现在比您的示例中的要小,因此您应该使用以下方法创建中心:
let center = CGPoint(x: profileImage.bounds.midX, y: profileImage.bounds.midY)
override func viewDidLayoutSubviews() {
let centerY = profileImage.center.y+20+(self.navigationController?.navigationBar.frame.size.height)!
let centerX = profileImage.center.x
let center = CGPoint(x: centerX, y: centerY)
let trackLayer = CAShapeLayer()
let circularPath = UIBezierPath(arcCenter: center, radius: (profileImage.frame.width/2)+2, startAngle: -CGFloat.pi-CGFloat.pi/2, endAngle: CGFloat.pi/2, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = Functions.hexStringToUIColor(hex: "#3859B9").cgColor
trackLayer.lineWidth = 3
trackLayer.lineCap = kCALineCapRound
trackLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(trackLayer)
}
或者直接在 viewDidAppear 中编写代码
这将解决问题。
- 将
layer
添加到profileImage.layer
。 trackLayer.frame = profileImage.bounds
完整代码应该是这样的:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let center = CGPoint(x: profileImage.bounds.midX,
y: profileImage.bounds.midY)
let trackLayer = CAShapeLayer()
trackLayer.frame = profileImage.frame
let circularPath = UIBezierPath(arcCenter: center,
radius: (profileImage.frame.width / 2) + 2,
startAngle: -CGFloat.pi - CGFloat.pi / 2,
endAngle: CGFloat.pi / 2, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = Functions.hexStringToUIColor(hex: "#3859B9").cgColor
trackLayer.lineWidth = 3
trackLayer.lineCap = kCALineCapRound
trackLayer.fillColor = UIColor.clear.cgColor
profileImage.layer.addSublayer(trackLayer)
}
使用界面生成器:
- 将 UIView 拖放到图像视图上方
- 将视图自定义 class 更改为 CirculerProgressView
- 使用图像视图中心设置中心 X 和 Y 约束
设置高度和宽度限制(大于 imageView 高度和宽度)
@IBDesignable class CirculerProgressView: UIView { override class var layerClass: AnyClass { return CAShapeLayer.self } override func draw(_ rect: CGRect) { super.draw(rect) setupLayer() } private func setupLayer() { let trackLayer = layer as! CAShapeLayer let center = CGPoint(x: frame.width/2, y: frame.height/2) let circularPath = UIBezierPath(arcCenter: center, radius: frame.width/2, startAngle: -CGFloat.pi-CGFloat.pi/2, endAngle: CGFloat.pi/2, clockwise: true) trackLayer.path = circularPath.cgPath trackLayer.strokeColor = UIColor.blue.cgColor trackLayer.lineWidth = 3 trackLayer.lineCap = kCALineCapRound trackLayer.fillColor = UIColor.clear.cgColor }}