gpt4 book ai didi

ios - 如何使用 UIPanGestureRecognizer 设置拖动控件的边界?

转载 作者:搜寻专家 更新时间:2023-11-01 06:53:30 25 4
gpt4 key购买 nike

我有一个 View ,我在其中添加了一个标签,然后我尝试使用 PanGesture 设置移动标签的边界。下面是我的代码:

@objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self)
if let view = gestureRecognizer.view {

if (view.frame.origin.x + translation.x >= 0) && (view.frame.origin.y + translation.y >= 0) && (view.frame.origin.x + translation.x <= view.frame.width) && (view.frame.origin.y + translation.y <= view.frame.height)
{
view.center = CGPoint(x:view.center.x + translation.x,
y:view.center.y + translation.y)
}
}
gestureRecognizer.setTranslation(CGPoint.zero, in: self)
}

}

我引用了这个答案:https://stackoverflow.com/a/49008808/9970928

但它不起作用,谁能告诉我在这种情况下缺少什么?

最佳答案

代码不是最直观的,但假设其他一切正常,问题是它只在右侧和底部超出范围。看看你的情况:

(view.frame.origin.x + translation.x <= view.frame.width)
(view.frame.origin.y + translation.y <= view.frame.height)

所以它说原点可能不会大于边界的大小你想要做的是检查内部 View 的最大值:

(view.frame.maxX + translation.x <= view.frame.width)
(view.frame.maxY + translation.y <= view.frame.height)

但这个过程通常可能会产生问题。想象一下,用户向右快速滑动。并且最大 center.x 可以是 100。当前 center.x50 并且用户将它拖到一个框架中到 200。您的条件将失败,您的标签将保持在 50 而不是 100。我会选择将框架固定到边界。

像下面这样的事情应该做:

func clampFrame(_ frame: CGRect, inBounds bounds: CGRect) -> CGRect {
let center: CGPoint = CGPoint(x: max(bounds.minX + frame.width*0.5, min(frame.midX, bounds.maxX - frame.width*0.5)),
y: max(bounds.minY + frame.height*0.5, min(frame.midY, bounds.maxY - frame.height*0.5)))
return CGRect(x: center.x-frame.width*0.5, y: center.y-frame.height*0.5, width: frame.width, height: frame.height)
}

func moveFrame(_ frame: CGRect, by translation: CGPoint, constrainedTo bounds: CGRect) -> CGRect {
var newFrame = frame
newFrame.origin.x += translation.x
newFrame.origin.y += translation.y
return clampFrame(newFrame, inBounds: bounds)
}

使用“翻译”过程可能还有其他问题。我会去寻找一个可见的位置。请参阅以下工作示例:

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let myView = MyView(frame: CGRect(x: 100.0, y: 100.0, width: 200.0, height: 200.0))
myView.backgroundColor = UIColor.green
view.addSubview(myView)
let label = UILabel(frame: .zero)
label.backgroundColor = UIColor.blue.withAlphaComponent(0.2)
label.font = UIFont.systemFont(ofSize: 50.0)
label.text = "Hi!"
label.sizeToFit()
myView.addSubview(label)
label.addGestureRecognizer(UIPanGestureRecognizer(target: myView, action: #selector(MyView.handlePan)))
label.isUserInteractionEnabled = true
}


}

class MyView: UIView {

func clampFrame(_ frame: CGRect, inBounds bounds: CGRect) -> CGRect {
let center: CGPoint = CGPoint(x: max(bounds.minX + frame.width*0.5, min(frame.midX, bounds.maxX - frame.width*0.5)),
y: max(bounds.minY + frame.height*0.5, min(frame.midY, bounds.maxY - frame.height*0.5)))
return CGRect(x: center.x-frame.width*0.5, y: center.y-frame.height*0.5, width: frame.width, height: frame.height)
}

func moveFrame(_ frame: CGRect, by translation: CGPoint, constrainedTo bounds: CGRect) -> CGRect {
var newFrame = frame
newFrame.origin.x += translation.x
newFrame.origin.y += translation.y
return clampFrame(newFrame, inBounds: bounds)
}

private var startLocation: CGPoint = .zero
private var startFrame: CGRect = .zero

@objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
guard let label = gestureRecognizer.view else { return }

if gestureRecognizer.state == .began {
startLocation = gestureRecognizer.location(in: self)
startFrame = label.frame
} else if gestureRecognizer.state == .changed {
let newLocation = gestureRecognizer.location(in: self)
let translation = CGPoint(x: newLocation.x-startLocation.x, y: newLocation.y-startLocation.y)

label.frame = moveFrame(startFrame, by: translation, constrainedTo: self.bounds)
}

}

}

关于ios - 如何使用 UIPanGestureRecognizer 设置拖动控件的边界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55488511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com