我想要一个球跟踪我的手指,因为我沿着圆形轨迹将它拖动到iPhone或iPad上的每个允许的设备方向。当设备旋转时,视图看起来正确居中,但球不会停留在圆周上,并且当我拖动它时似乎会到达任何位置。当我将UIPanGestureRecognizer和自动布局结合起来时,我的UIViews弄脏了
EDIT
Martin R's answer现在显示此需要。我唯一的额外的代码改变是消除不必要的声明var shapeLayer = CAShapeLayer()
,直到我试图约束两个球轨迹视图的中心,并添加球的中心坐标为this example的数学非常有意义运行时偏移。我跟着these recommendations on how to constrain a view。
有三件事我不明白。
首先,计算从两个变量的圆的周长trackRadius
和角度theta
和使用sin
和theta
cos
找到x
和y
坐标将不把球在合适的位置。
二,用atan
找到观察中心,碰到点之间的角度theta
,并使用trackRadius
与theta
找到x
和y
坐标将不放置或移动球沿圆周一个新的地方。第三,无论何时拖动球,调试区域中的消息都表示Xcode is Unable to simultaneously satisfy constraints
,尽管在拖动它之前没有报告约束问题。
这里可能有多个问题。我的大脑开始受到伤害,如果有人能指出我做错了什么,我会很感激。
这是我的代码。
import UIKit
class ViewController: UIViewController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .all }
var shapeLayer = CAShapeLayer()
let track = ShapeView()
var ball = ShapeView()
var theta = CGFloat()
private let trackRadius: CGFloat = 125
private let ballRadius: CGFloat = 10
override func viewDidLoad() {
super.viewDidLoad()
createTrack()
createBall()
}
private func createTrack() {
track.translatesAutoresizingMaskIntoConstraints = false
track.shapeLayer.path = UIBezierPath(ovalIn: CGRect(x: -trackRadius, y: -trackRadius, width: 2 * trackRadius, height: 2 * trackRadius)).cgPath
track.shapeLayer.fillColor = UIColor.clear.cgColor
track.shapeLayer.strokeColor = UIColor.red.cgColor
view.addSubview(track)
track.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
track.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
private func createBall() {
let offset = placeBallOnCircumference()
drawBall()
constrainBall(offset: offset)
let touch = UIPanGestureRecognizer(target: self, action:#selector(dragBall(recognizer:)))
view.addGestureRecognizer(touch)
}
private func placeBallOnCircumference() -> CGPoint {
let theta: Double = 0 // at 0 radians
let x = CGFloat(cos(theta)) * trackRadius // find x and y coords on
let y = CGFloat(sin(theta)) * trackRadius // circle circumference
return CGPoint(x: x, y: y)
}
func dragBall(recognizer: UIPanGestureRecognizer) {
var offset = CGPoint()
let finger : CGPoint = recognizer.location(in: self.view)
theta = CGFloat(atan2(Double(finger.x), Double(finger.y))) // get angle from finger tip to centre
offset.x = CGFloat(cos(theta)) * trackRadius // use angle and radius to get x and
offset.y = CGFloat(sin(theta)) * trackRadius // y coords on circle circumference
drawBall()
constrainBall(offset: offset)
}
private func drawBall() {
ball.shapeLayer.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 2 * ballRadius, height: 2 * ballRadius)).cgPath
ball.shapeLayer.fillColor = UIColor.cyan.cgColor
ball.shapeLayer.strokeColor = UIColor.black.cgColor
view.addSubview(ball)
}
private func constrainBall(offset: CGPoint) {
ball.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
ball.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: offset.x),
ball.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: offset.y),
ball.widthAnchor.constraint(equalToConstant: trackRadius),
ball.heightAnchor.constraint(equalToConstant: trackRadius)
])
}
}
一个良好的夜间睡眠后,什么是快乐是意识到了这个!你钉住了我试过的所有东西,并使Swift代码在这个过程中更加自我解释。它必须是被接受的答案。 – Greg