是否可以将UIEvent子类化以嵌入一些其他信息? 我尝试了但是不断获得异常,并且无法找到关于子类化UIEvent的任何内容。
class CustomEvent: UIEvent {
let payload: CustomData
override init(payload: CustomData) {
super.init()
self.payload = payload
}
}
017-03-30 08:51:17.504497 StealingTouches[1041:778674] -[StealingTouches.TouchEvent _firstTouchForView:]: unrecognized selector sent to instance 0x170053950
2017-03-30 08:51:17.505470 StealingTouches[1041:778674] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[StealingTouches.TouchEvent _firstTouchForView:]: unrecognized selector sent to instance 0x170053950'
*** First throw call stack:
(0x18bf991b8 0x18a9d055c 0x18bfa0268 0x18bf9d270 0x18be9680c 0x191e8494c 0x100026278 0x100026550 0x100026fc4 0x100027214 0x191e7be98 0x191e77328 0x191e47da0 0x19263175c 0x19262b130 0x18bf46b5c 0x18bf464a4 0x18bf440a4 0x18be722b8 0x18d926198 0x191eb27fc 0x191ead534 0x100029418 0x18ae555b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
我在超级视图中嵌套了3个级别的视图集合。我希望深度嵌套的视图向事件添加一些自定义数据,并将此数据转发到最外面的视图。
见图片。绿色视图应处理事件,执行适当的计算,将数据保存到事件中,并将数据转发到红色视图。只有绿色视图才会响应事件,但只有红色视图知道如何处理该事件。
绿色视图处理触摸......
class GreenView: UIControl {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
//do some complicated calculation then save in custom event
let customEvent = CustomEvent.init(payload: calculations)
if let nextRespoonder = self.next {
nextRespoonder.touchesBegan(touches, with: customEvent)
}
}
}
然后转发到黄色视图......
class YellowView: UIControl {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let nextRespoonder = self.next {
nextRespoonder.touchesBegan(touches, with: event)
}
}
}
最后,红色视图可以提取事件有效负载并执行它需要做的事情......
class RedView: UIControl {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let customEvent = event as? CustomEvent {
let payload = customEvent.payload
//do something with the payload
}
}
}
另一种选择是在绿色视图中本地存储有效载荷数据,然后红色视图唯一需要做的是识别启动事件的绿色视图。这对于命中测试来说相当简单,但是我有超过一百个这样的绿色视图,并且由于有时绿色视图相互重叠,因此可以相当复杂地找出哪一个基于命中测试。
答案 0 :(得分:0)
我了解到这种模式是处理这种情况的错误方法。最好的办法是使用委托。将redView指定为greenView的委托,然后只传递信息。
protocol GreenViewDelegate {
func onTouchesBegan(greenView: GreenView)
}
class GreenView: UIControl {
var delegate: GreenViewDelegate?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
self.delegate?.onTouchesBegan(greenView: self)
}
}
class RedView: UIControl, GreenViewDelegate {
init() {
greenView.delegate = self
}
func onTochesBegan(greenView: GreenView) {
//extract whatever data you want
}
}