使用 UIPanGestureRecognizer 缩放和移动 UIView
Scale and move an UIView using UIPanGestureRecognizer
我有一个 UIView A。我在视图 A 上放置了一个图标,并尝试使用平移手势来缩放和移动此视图 A。
我尝试了很多解决方案,但我做不到。
请建议帮助我?
更多详情:
我会添加更多细节。
我有视图 A,在自己的视图上添加子视图。我希望当我在视图 A 上绘制 panGestureRegonizer 时,视图 A 将跟随绘制移动。
并且在移动视图 A 时会缩放。当视图移动到屏幕的 top/left/bottom/right 时,视图 A 将缩放到较小,当视图移动到屏幕中心时,视图 A 将缩放到更大。
假设您有 vc - ViewController
并且您的 UIView A
是 vc
的子视图。您可以将 UIPanGestureRecognizer
添加到 A
。然后将 panGestureRegonizer 拖到您的 vc
作为一个动作:
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
//your code here
}
从 sender
您可以检查操作的 view
、 location
和 state
。 state
在某些情况下可能会影响您的代码,具体取决于您要实现的目标。
那你需要把action修改成这样:
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
UIView.animateKeyframes(withDuration: 0.1, delay: 0, options: UIViewKeyframeAnimationOptions.calculationModeLinear, animations: {
let location = sender.location(in: sender.view?.superview)
sender.view?.center = location
})
}
这里 sender.view?.superview
等于 vc.view
。此代码片段将检测平移手势,然后移动 A
,以便 A.center
匹配手势的位置。请注意,持续时间 0.1 为运动提供了平滑的动画效果。
这将为您提供 "move" 平移手势功能。
EDIT 缩放:
逻辑:您的坐标系 (CS) 为 center
、x
和 y
。当用户使用平移手势时,he/she 在 CS 中生成点序列。所以我们的任务是测量 CS 中心和用户点之间的距离。当距离最远时,我们可以计算缩放视图的比例因子。
var center: CGPoint! //center of the CS
let maxSize: CGSize = CGSize.init(width: 100, height: 100) // maximum size of our scaling view
var maxLengthToCenter: CGFloat! //maximum distance from the center of the CS to the furthest point in the CS
private func prepareForScaling() {
self.center = self.view.center //we set the center of our CS to equal the center of the VC's view
let frame = self.view.frame
//the furthest distance in the CS is the diagonal, and we calculate it using pythagoras theorem
self.maxLengthToCenter = (frame.width*frame.width + frame.height*frame.height).squareRoot()
}
然后我们需要调用我们的设置函数让我们的数据准备好缩放功能 - 我们可以在 viewDidLoad
:
中执行此操作
override func viewDidLoad() {
super.viewDidLoad()
self.prepareForScaling()
}
然后我们需要一个辅助函数来计算我们视图的缩放大小,用于用户在屏幕上的平移手势当前位置。
private func scaledSize(for location: CGPoint) -> CGSize {
//calculate location x,y differences from the center
let xDifference = location.x - self.center.x
let yDifference = location.y - self.center.y
//calculate the scale factor - note that this factor will be between 0.0(center) and 0.5(diagonal - furthest point)
//It is due our measurement - from center to view's edge. Consider multiplying this factor with your custom constant.
let scaleFactor = (xDifference*xDifference + yDifference*yDifference).squareRoot()/maxLengthToCenter
//create scaled size with maxSize and current scale factor
let scaledSize = CGSize.init(width: maxSize.width*(1-scaleFactor), height: maxSize.height*(1-scaleFactor))
return scaledSize
}
最后,我们需要修改平移手势动作来改变A
的大小:
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
UIView.animateKeyframes(withDuration: 0.1, delay: 0, options: UIViewKeyframeAnimationOptions.calculationModeLinear, animations: {
let location = sender.location(in: sender.view?.superview)
sender.view?.frame = CGRect.init(origin: CGPoint.init(x: 0, y: 0), size: self.scaledSize(for: location))
sender.view?.center = location
})
}
我有一个 UIView A。我在视图 A 上放置了一个图标,并尝试使用平移手势来缩放和移动此视图 A。
我尝试了很多解决方案,但我做不到。
请建议帮助我?
更多详情:
我会添加更多细节。
我有视图 A,在自己的视图上添加子视图。我希望当我在视图 A 上绘制 panGestureRegonizer 时,视图 A 将跟随绘制移动。
并且在移动视图 A 时会缩放。当视图移动到屏幕的 top/left/bottom/right 时,视图 A 将缩放到较小,当视图移动到屏幕中心时,视图 A 将缩放到更大。
假设您有 vc - ViewController
并且您的 UIView A
是 vc
的子视图。您可以将 UIPanGestureRecognizer
添加到 A
。然后将 panGestureRegonizer 拖到您的 vc
作为一个动作:
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
//your code here
}
从 sender
您可以检查操作的 view
、 location
和 state
。 state
在某些情况下可能会影响您的代码,具体取决于您要实现的目标。
那你需要把action修改成这样:
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
UIView.animateKeyframes(withDuration: 0.1, delay: 0, options: UIViewKeyframeAnimationOptions.calculationModeLinear, animations: {
let location = sender.location(in: sender.view?.superview)
sender.view?.center = location
})
}
这里 sender.view?.superview
等于 vc.view
。此代码片段将检测平移手势,然后移动 A
,以便 A.center
匹配手势的位置。请注意,持续时间 0.1 为运动提供了平滑的动画效果。
这将为您提供 "move" 平移手势功能。
EDIT 缩放:
逻辑:您的坐标系 (CS) 为 center
、x
和 y
。当用户使用平移手势时,he/she 在 CS 中生成点序列。所以我们的任务是测量 CS 中心和用户点之间的距离。当距离最远时,我们可以计算缩放视图的比例因子。
var center: CGPoint! //center of the CS
let maxSize: CGSize = CGSize.init(width: 100, height: 100) // maximum size of our scaling view
var maxLengthToCenter: CGFloat! //maximum distance from the center of the CS to the furthest point in the CS
private func prepareForScaling() {
self.center = self.view.center //we set the center of our CS to equal the center of the VC's view
let frame = self.view.frame
//the furthest distance in the CS is the diagonal, and we calculate it using pythagoras theorem
self.maxLengthToCenter = (frame.width*frame.width + frame.height*frame.height).squareRoot()
}
然后我们需要调用我们的设置函数让我们的数据准备好缩放功能 - 我们可以在 viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
self.prepareForScaling()
}
然后我们需要一个辅助函数来计算我们视图的缩放大小,用于用户在屏幕上的平移手势当前位置。
private func scaledSize(for location: CGPoint) -> CGSize {
//calculate location x,y differences from the center
let xDifference = location.x - self.center.x
let yDifference = location.y - self.center.y
//calculate the scale factor - note that this factor will be between 0.0(center) and 0.5(diagonal - furthest point)
//It is due our measurement - from center to view's edge. Consider multiplying this factor with your custom constant.
let scaleFactor = (xDifference*xDifference + yDifference*yDifference).squareRoot()/maxLengthToCenter
//create scaled size with maxSize and current scale factor
let scaledSize = CGSize.init(width: maxSize.width*(1-scaleFactor), height: maxSize.height*(1-scaleFactor))
return scaledSize
}
最后,我们需要修改平移手势动作来改变A
的大小:
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
UIView.animateKeyframes(withDuration: 0.1, delay: 0, options: UIViewKeyframeAnimationOptions.calculationModeLinear, animations: {
let location = sender.location(in: sender.view?.superview)
sender.view?.frame = CGRect.init(origin: CGPoint.init(x: 0, y: 0), size: self.scaledSize(for: location))
sender.view?.center = location
})
}