Ios 为什么UIView在旋转时不保持在中心位置?
我试图校准UIView,使其在旋转时保持在中心位置。这是根据问题的最佳答案确定的问题的后续步骤。此后,我根据建议使用Ios 为什么UIView在旋转时不保持在中心位置?,ios,swift,uiview,Ios,Swift,Uiview,我试图校准UIView,使其在旋转时保持在中心位置。这是根据问题的最佳答案确定的问题的后续步骤。此后,我根据建议使用viewwillbeen或viewdilayoutsubviews而不是viewdiload设计了代码 由于我是Swift新手,我不得不重新阅读Swift教程,以实现一个自定义控件。我的代码可以使用以下三个函数中的任意一个来绘制圆:viewwillbeen、viewdilayoutsubviews或viewdiload 然而,当我渲染代码时,当屏幕旋转时,圆圈并不总是保持在中心。下
viewwillbeen
或viewdilayoutsubviews
而不是viewdiload
设计了代码
由于我是Swift新手,我不得不重新阅读Swift教程,以实现一个自定义控件。我的代码可以使用以下三个函数中的任意一个来绘制圆:viewwillbeen
、viewdilayoutsubviews
或viewdiload
然而,当我渲染代码时,当屏幕旋转时,圆圈并不总是保持在中心。下面是使用viewdiload
或viewwillshould
在纵向屏幕上启动应用程序时发生的连续旋转。第一次旋转后,无论向左或向右,问题都会立即出现。如果以横向方向发射,如果没有尝试至少四次连续旋转,则可能会错过一个问题
下面是使用viewdilayoutsubviews
进行的连续旋转,其中旋转偶尔会导致同心圆与偏心圆重叠。这可能在多次旋转后发生,但必须至少完成四次旋转才能注意到问题
下面是CircleView
的代码-我试图创建UIView的子类
import UIKit
class CircleView: UIView {
let radius = CGFloat(200)
let x: CGFloat = 0
let y: CGFloat = 0
// MARK: Initialization
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
func setup() {
// Create a CAShapeLayer
let shapeLayer = CAShapeLayer()
// The Bezier path that we made needs to be converted
// to a CGPath before it can be used on a layer.
shapeLayer.path = createBezierPath().cgPath
// apply other properties related to the path
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.lineWidth = 8.0
// add the new layer to our custom view
self.layer.addSublayer(shapeLayer)
}
func createBezierPath() -> UIBezierPath {
// create a new path
let path = UIBezierPath(arcCenter: CGPoint(x: x, y: y),
radius: radius,
startAngle: CGFloat(M_PI * -0.5),
endAngle:CGFloat(M_PI * 1.5),
clockwise: true)
path.fill()
path.stroke()
return path
}
}
下面是ViewController的代码
import UIKit
class ViewController: UIViewController {
var circle: CircleView?
var x: CGFloat?
var y: CGFloat?
override func viewDidLoad() {
super.viewDidLoad()
let centre = centreCircle()
// create a new UIView and add it to the view controller
let circleView = CircleView()
circleView.frame = CGRect(x: centre.x, y: centre.y, width: 0, height: 0)
view.addSubview(circleView)
}
func centreCircle() -> CGPoint {
circle?.bounds = UIScreen.main.bounds
return CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY)
}
}
下面是UIScreen扩展的代码,它返回屏幕的中心点
import UIKit
extension UIScreen {
var centre: CGPoint {
return CGPoint(x: bounds.midX, y: bounds.midY)
}
}
为了产生上述旋转,我将viewdiload
函数替换为viewwillbeen
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let centre = centreCircle()
// create a new UIView and add it to the view controller
let circleView = CircleView()
circleView.frame = CGRect(x: centre.x, y: centre.y, width: 0, height: 0)
view.addSubview(circleView)
}
或viewdilayoutsubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let centre = centreCircle()
// create a new UIView and add it to the view controller
let circleView = CircleView()
circleView.frame = CGRect(x: centre.x, y: centre.y, width: 0, height: 0)
view.addSubview(circleView)
}
有人能在我的代码中看到可能停止旋转的问题吗?您必须将
frame.bounds
替换为frame.center
才能正确计算中心。首先,视图在viewdidload和ViewWillDisplay中布局不正确,并且您使用值显式定义了框架,作为一个新的程序员,我感到非常沮丧。当涉及到调整标签的大小时,它仍然让我非常恼火。因此,将视图和主屏幕的centreX和centreY放在一起,意味着旋转时视图将停留在该点上
通过学习自动布局来解决这个问题。一开始很糟糕,但最终会让你的生活更轻松。看看这个扩展中的方法。当我想将一个视图居中到另一个视图时,我会使用它
extension UIView {
func constrainAndCenter(in view: UIView, withRelativeHeight: CGFloat, withRelativeWidth: CGFloat) -> [NSLayoutConstraint] {
self.translatesAutoresizingMaskIntoConstraints = false
let x = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0)
let w = NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: withRelativeWidth, constant: 0)
let h = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: withRelativeHeight, constant: 0)
let y = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0)
return ([x,w,h,y])
}
}
// then in viewdidload or whereever
let circleView = CircleView()
let circleViewConstraints = circleView.constrainAndCenter(in: view,....)
view.addSubview(circleView)
NSLayoutConstraint.activate(circleViewConstraints)
那会把它钉在中间。您也可以在interface builder中执行此操作。circleView.ConstraintandCenter可能是提供circleView中缺少的参数的方法。现在我将检查NSLayoutConstraint,这可能需要一些时间。我可能错了,但我认为CGPoint中的.midX和.midY值(x:UIScreen.main.bounds.midX,y:UIScreen.main.bounds.midY)将给出中心点