gpt4 book ai didi

swift - swift 中的重写类扩展中的方法受限于协议(protocol)

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

我正在尝试将默认实现添加到 UIViewController touches begin to all controllers conforming through a protocol extension.触摸将被发送到所有实现此协议(protocol)的 Controller 都具有的自定义 View 。

这是初始状态:

protocol WithView {
var insideView: UIView! { get }
}

class Controller1: UIViewController, WithView {

var insideView: UIView!

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
insideView.touchesBegan(touches, with: event)
}

/* Functionality of Controller 1 */
}

class Controller2: UIViewController, WithView {

var insideView: UIView!

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
insideView.touchesBegan(touches, with: event)
}

/* Functionality of Controller 2 */
}

我想要完成的是这样一种情况,即所有 UIViewController 都将触摸转发到 insideView,而无需以相同的方式为每个 Controller 指定触摸。像这样:

protocol WithView {
var insideView: UIView! { get }
}

extension UIViewController where Self: WithView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
insideView.touchesBegan(touches, with: event)
}
}

class Controller1: UIViewController, WithView {

var insideView: UIView!

/* Functionality of Controller 1 */
}

class Controller2: UIViewController, WithView {

var insideView: UIView!

/* Functionality of Controller 2 */
}

但这不会编译,说'Trailing where clause for extension of non-generic type UIViewController'

我试着反过来定义它,像这样:

extension WithView where Self: UIViewController {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
insideView.touchesBegan(touches, with: event)
}
}

虽然扩展格式正确,但编译器会提示,因为它无法“覆盖”协议(protocol)扩展中的内容。

我想要的是一个受协议(protocol)约束的类扩展,比如我可以覆盖这个方法,而不是被迫在我实现这个协议(protocol)的所有 Controller 中复制粘贴代码。

编辑:根据建议的解决方案

我也想出了这个解决方案:

protocol WithView {
var insideView: UIView! { get }
}

extension UIViewController {
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let viewSelf = (self as? WithView) else {
super.touchesBegan(touches, with: event)
return
}
viewSelf.insideView.touchesBegan(touches, with: event)
}
}

class Controller1: UIViewController, WithView {

var insideView: UIView!

/* Functionality of Controller 1 */
}

class Controller2: UIViewController, WithView {

var insideView: UIView!

/* Functionality of Controller 2 */
}

它做了我想要的,但感觉有点乱,因为所有的 UIViewControllers 都会继承这个行为,并且会覆盖它的代码,检查它们是否实现了协议(protocol)。

最佳答案

您可以为所有 View Controller 定义自己的父类(super class),并检查 self 是否符合特定协议(protocol)(在您的情况下为 WithView)以决定是否应转发触摸事件到任何其他 View 。

class MyViewController: UIViewController {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let selfWithView = self as? WithView {
selfWithView.insideView.touchesBegan(touches, with: event)
} else {
super.touchesBegan(touches, with: event)
}
}
}

这是一种更灵活的方法,您不必在每个 View Controller 子类中都存储 insideView 属性。

关于swift - swift 中的重写类扩展中的方法受限于协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43104040/

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