ios - Swift 协议(protocol)中 IBAction 的更好策略是什么?

标签 ios swift protocols ibaction swift-protocols

我正在创建一个 Swift 项目,我想定义一个强制其他组件实现 animate 方法的特定协议(protocol):

protocol AnimatableBehavior {
    @IBAction func animate()
}

问题是我希望这个方法是一个 IBAction,但是我从 XCode 得到这个错误:

Only instance methods can be declared 'IBAction'

我的问题是,您将如何实现这样的事情?

我考虑过:

  1. 删除@IBAction,但我需要记住在每个实现的类中添加它。不是很优雅且容易出错。
  2. 创建一个基类而不是协议(protocol),但随后我强制所有组件继承我的基类而不是它们自己选择的基类,因此这不是一个有效的选项。

还有其他想法吗?


编辑:对以下评论的回应。

IBAction 协议(protocol)的想法是因为在项目中会有许多不同的开发人员实现小的 UI 组件,所有这些组件都有 animate 方法。组件可以通过编程方式或通过 Interface Builder 添加,它们始终是 IBAction 非常方便,因为我计划从 IB 文件中组合它们以简化 View Controller 在最大程度上(这显然是一个仅查看任务)。

因此,下面提出的解决方案是在controller中添加一个只调用组件的animate的方法,这样的解决方案并不好,因为它是冗余代码,并且使您的Controller更加依赖于您的View。

让开发人员记住在方法上添加 IBAction 关键字的想法是可行的,但正如我所说,它很容易出错(我的意思是会有一些人忘记它),并且我想确保它始终可以从 IB 访问。它还增加了额外的认知负担,因为我需要记录协议(protocol)中缺少 IBAction 的情况,并要求实现者手动添加它。

我知道这不是在 iOS 和 UIKit 中工作的常见方式,但这就是我发布问题的原因,也许有人有其他想法。

最佳答案

在协议(protocol)中使用@IBAction 没有任何意义。 @IBAction 只不过是 Interface Builder 的关键字,当您从 Interface Builder 控制并拖动到您的实际源代码时,它有一个钩子(Hook)。

这只是对 @IBAction 的实际含义和作用的简单误解。

  1. 方法不必标记为 @IBAction 即可使其成为 UI 元素操作的目标。您可以使用 UI 元素具有的 addTarget 方法集以编程方式将任何方法连接到任何操作。该方法不必标记为 @IBAction 即可执行此操作。

  2. 无论协议(protocol)是否将方法定义为@IBAction,符合协议(protocol)的类都可以添加它(并且仍然符合协议(protocol)。

    protocol FooProtocol {
        func doSomething()
    }
    
    class ViewControllerA: UIViewController, FooProtocol {
        @IBAction func doSomething() {
            // do something
        }
    } 
    
    class ViewControllerB: UIViewController, FooProtocol {
        func doSomething() {
            // do something
        }
    }
    

    这两个 View Controller 子类都符合协议(protocol),并且如果您打算从界面构建器连接一个 Action ,则只有需要@IBAction !


最后,无论您尝试做什么,如果您认为 @IBAction 在您的协议(protocol)中是必需的,我认为您采取了错误的方法。在不了解您实际正在做的事情的更多细节的情况下很难说什么是正确的方法,但是 @IBAction 属于协议(protocol)是没有意义的。

对我来说,您的协议(protocol)强制执行的方法似乎根本不应该与 @IBAction 方法相关联。相反,无论用户交互应触发动画,都应依次调用 animate 方法。例如,如果我们不讨论协议(protocol),我的建议是这种设置:

class ViewController: UIViewController {
    @IBAction func buttonThatStartsAnimation {
        self.animate()
    }

    func animate {
        // code that does all the animation
    }
}

因此,对于协议(protocol),我们应该在实际启动动画代码的方法(在协议(protocol)的情况下,这显然是其他一些外部类)和 animate< 之间采取相同的职责分离 方法应该只处理相关动画。

重要的是,作为一般规则,您不应该直接从定义它们的类外部直接引用您的@IBAction 方法或您的@IBOutlet 变量.

关于ios - Swift 协议(protocol)中 IBAction 的更好策略是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29576408/

相关文章:

objective-c - verseGeocodeLocation 存储为 NSString 产生错误

iphone - OpenCV CvCamera 预览

ios - 在应用程序生命周期的另一个时间请求远程通知授权?

swift - 一旦谷歌表单在 WebView 中完成,我如何执行函数?

outlook - Outlook 支持哪些协议(protocol)进行双向日历同步?

Swift 泛型扩展到多个类

ios - 在 Swift 3 中的文本中的某个字符串之前放置一个字符串

ios - Alamofire/Swiftyjson - 将 JSON 类型传递给 Objc 协议(protocol)委托(delegate)

ios - @IBDesignables - "the agent crashed"但应用程序仍然有效(大部分时间)

sockets - 1个端口如何同时监听http和websocket