【问题标题】:Can I use @IBOutlets in Protocols (Swift)我可以在协议中使用@IBOutlets (Swift)
【发布时间】:2017-12-14 16:56:12
【问题描述】:

我有一个按以下方式定义的小协议:

import UIKit

protocol HasMeterAnimation {
    func animateMeter(scrollableView: UIScrollView)
}

它的实现需要使用 IBOutlets:

func animateMeter(scrollableView: UIScrollView) {

    let maxYPosTableview = scrollableView.frame.height + scrollableView.frame.origin.y
    let progressBarRect = self.progressBar.frame
    let rectOfProgressBarInParentView =  self.convert(progressBarRect, to: scrollableView.superview)
    let maxYPosMeter = rectOfProgressBarInParentView.origin.y + progressBarRect.height

    if maxYPosTableview > maxYPosMeter {
        if progressBar.isHidden == false {
            progressBar.animateProgressBar()
            model.shouldMeterAnimate = false
        }
    }
}

我想知道是否有一种方法可以让我使用 IBOutlets 在协议扩展中编写此实现......像这样:

    protocol HasMeterAnimation {

        @IBOutlet var progressBar:AnimatedProgressBar! { get set }
        var model: ListItem! { get set }

        func animateMeter(scrollableView: UIScrollView)
    }

extension HasMeterAnimation {

            func animateMeter(scrollableView: UIScrollView) {

                let maxYPosTableview = scrollableView.frame.height + scrollableView.frame.origin.y
                let progressBarRect = self.progressBar.frame
                let rectOfProgressBarInParentView =  self.convert(progressBarRect, to: scrollableView.superview)
                let maxYPosMeter = rectOfProgressBarInParentView.origin.y + progressBarRect.height

                if maxYPosTableview > maxYPosMeter {
                    if progressBar.isHidden == false {
                        progressBar.animateProgressBar()
                        model.shouldMeterAnimate = false
                    }
                }
            }

我尝试了很多方法,但总是给我错误。谢谢

【问题讨论】:

  • 删除@IBOutlet是否有错误?在这里帮不上忙。您收到什么错误?
  • 我解决了。公认的答案是正确的...... IBOutlets 在协议中毫无意义。我只是在协议中定义了一个属性,并在控制器中作为 IbOutlet 实现。

标签: swift protocols iboutlet


【解决方案1】:

IBOutlet 只是一个关键字,让界面构建器知道您想在类中引用界面构建器中的对象,例如在您的 ViewController、View 等中。在任何其他上下文中,IBOutlet 没有任何意义。当您在协议中定义属性时,您也不会将它们标记为强制展开。当您没有将属性显式标记为可选时,该属性必须在运行时具有值,否则您无法编译代码。接口构建器将其 outlet 标记为强制解包,因为它们在编译时没有值并且在运行时被解析。

【讨论】:

  • 虽然完全正确,但我认为问题的答案实际上只是前两句话。任何 IBOutlet 都属于视图或视图控制器(恰好是类)——属于其他任何东西的 IBOutlet 没有意义。
  • @ok404 所以如果我在我的协议中定义了一个属性...我可以在我的控制器中将它用作 iboutlet 吗??...会告诉我协议是否满足?
  • 值得注意的是,在 ObjC 中,IBOutlet 实际上是一个 #define 宏,它被替换为空(它实际上是空的)。 Swift 做不到(没有预处理器),所以它需要一个属性,但概念是一样的。 唯一的目的是让 Xcode 知道您希望将 UI 元素连接到使用鼠标。它对系统根本没有编译时或运行时影响(这在 Swift 中可能不是 100% 正确;我认为它可能会自动注入 @objc)。但这绝对不会影响协议一致性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
相关资源
最近更新 更多