gpt4 book ai didi

ios - 尝试使用协议(protocol)使 View 可拖动时应用程序崩溃

转载 作者:行者123 更新时间:2023-11-28 06:26:56 25 4
gpt4 key购买 nike

所以我编写了一个协议(protocol),使任何符合它的 UIView 都可以拖动。但是,当我在模拟器中对此进行测试时,当我尝试拖动 View 时它会崩溃。并将其显示在日志中

libc++abi.dylib: terminating with uncaught exception of type NSException

协议(protocol):

protocol Draggable {}

extension Draggable where Self: UIView {

func wasDragged (gestrue: UIPanGestureRecognizer) {

let translation = gestrue.translation(in: UIScreen.main.focusedView)
if let label = gestrue.view {

label.center = CGPoint(x: label.center.x + translation.x, y: label.center.y + translation.y)

}
gestrue.setTranslation(CGPoint.zero, in: UIScreen.main.focusedView)



}

func setGesture () {

let gesture = UIPanGestureRecognizer(target: UIScreen.main, action: Selector(("wasDragged:")))
self.addGestureRecognizer(gesture)
self.isUserInteractionEnabled = true
}

}

在自定义标签类中,我符合它:

class DraggableLabel: UILabel, Draggable {
}

然后我在 View Controller 的viewDidLoad中调用了setGesutre函数:

override func viewDidLoad() {
super.viewDidLoad()

draggableLabel.setGesture()
}

好吧,我承认我真的不知道自己在做什么。

最佳答案

操作 wasDragged(gesture:) 需要可访问,以便通过 Objective-C 运行时进行消息分发。使用 @objc 注释使方法可用于消息分发。 NSObject 子类的方法自动是 @objc 方法。

坏消息是这只适用于 Objective-C 兼容的类或扩展。像您这样的协议(protocol)扩展不兼容,因此您不能将操作方法​​放入这些扩展中。

您的选择是将此功能添加到子类或普通类扩展:

extension DraggableLabel {

func wasDragged (gesture: UIPanGestureRecognizer) {

let translation = gesture.translation(in: UIScreen.main.focusedView)
center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
gesture.setTranslation(CGPoint.zero, in: UIScreen.main.focusedView)
}

func setGesture () {
let gesture = UIPanGestureRecognizer(target: self,
action: #selector(wasDragged(sender:)))
self.addGestureRecognizer(gesture)
self.isUserInteractionEnabled = true
}
}

(请注意,我还将手势识别器的目标更改为 View 而不是主屏幕。您是否打算使用响应者链将事件传播到正确的 View ?)

与面向协议(protocol)的方法相比,明显的缺点是灵 active 降低。如果那是一个问题,我会研究类(class)组成。创建一个封装手势识别器及其操作方法的类。给它一个 View 属性并在设置该属性时配置所有内容:

class DraggingBehavior: NSObject {
@IBOutlet var view: UIView? {
didSet {
guard let view = view else { return }
let gesture = UIPanGestureRecognizer(target: self, action: #selector(wasDragged(sender:)))
view.addGestureRecognizer(gesture)
view.isUserInteractionEnabled = true
}
}

func wasDragged(sender: UIGestureRecognizer) {
print("Was dragged")
// put the view translation code here.
}
}

@IBOutlet 使此类与 Interface Builder 兼容。拖入自定义对象,将其类设置为 DraggingBehavior,将 View 导出连接到您希望使其可拖动的 View 。

关于ios - 尝试使用协议(protocol)使 View 可拖动时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41581245/

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