【问题标题】:Swift - IBOutletCollection equivalentSwift - IBOutletCollection 等价物
【发布时间】:2014-06-05 05:43:17
【问题描述】:

我正在尝试在 Swift 的 iTunesU 中复制“为 iphone 和 ipad 开发 ios7 应用程序”中的斯坦福 Matchismo 游戏。

在第三讲 slides 的第 77 页上,它显示使用 IBOutletCollection,这不是 Swift 的选项。 Swift doc 示例显示了一个示例,它有一个 IBOutlet 数组,但我不知道如何让 Interface Builder 将多个出口连接到同一个 IBOutlet/IBOutlet 数组。

有没有人知道如何做到这一点?

我知道我可以创建 12 个插座并以这种方式处理它,但我想让这项工作尽可能接近讲座幻灯片中的示例。

【问题讨论】:

  • Xcode 不像 @IBOutlet@IBAction 那样突出显示 @IBOutletCollection 的语法,并且在谈论后两者的 Apple docs page 中没有提到它。好像还没到,或者还没来。
  • 归档为错误:17200892
  • @Alcanzar 有关于该错误的更新吗?
  • 我的被标记为“Duplicate of 15607242 (Open)”所以一定是一个真正的问题。
  • 未在 Xcode beta2 中修复,供任何人跟踪。

标签: swift interface-builder iboutlet iboutletcollection


【解决方案1】:

更新:这在 Xcode 中现在可以正常工作了 - “Outlet Collection”是 Interface Builder 中的连接选项之一,它创建的东西看起来像:

@IBOutlet var labelCollection: [UILabel]!

在我们等待修复时,您可以使用计算属性来近似此问题。假设我的视图中有五个我想要在集合中的UILabels。我仍然必须声明每一个,但随后我还声明了一个收集它们的计算属性:

class MyViewController {
    @IBOutlet var label1 : UILabel
    @IBOutlet var label2 : UILabel
    @IBOutlet var label3 : UILabel
    @IBOutlet var label4 : UILabel
    @IBOutlet var label5 : UILabel
    var labels: UILabel![] { return [label1, label2, label3, label4, label5] }

有点烦人,但从那时起,我们可以将labels 属性视为IBOutletCollection,并且在修复错误后无需更改其余代码:

override func viewDidLoad() {
    super.viewDidLoad()

    for (index, item) in enumerate(self.labels) {
        item.text = "Label #\(index)"
    }
}

【讨论】:

  • 乍一看,这似乎可行,但实际上并没有。它确实比我的UILabel[] 尝试更好,因为我可以从 IBOutlet 拖动到特定按钮,如果我尝试添加第二个按钮,它会替换第一个按钮。此外,如果我尝试将其仅连接到一个按钮来运行,则 swift 将无法启动(Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254 )
  • 这不起作用。它仍然只允许您连接一个视图
  • 天哪。这意味着 matchismo 项目只有 30 行变量定义......我想这就是你尝试用一种向公众开放不到一个月的语言编写代码时得到的结果。
  • 这就是为什么他们称之为前沿技术。
  • 我要说的是,尽管您可能确实为少量组件提供了修复,但当应用于 Matchismo 项目时,它似乎在尝试编译时崩溃。
【解决方案2】:

用途:

@IBOutlet var lineFields: [UITextField]!

然后按顺序从 UITextField 元素控制拖动到lineFields

【讨论】:

    【解决方案3】:
    @IBOutlet var buttons : [UIView]!
    

    然后将其从界面构建器中的连接检查器或您通常使用的任何方法中拖动

    【讨论】:

      【解决方案4】:

      编辑

      这已在 Swift 的后续 Beta 版本中得到修复 - 现在在 界面生成器中的 IBCollection 选项。


      对于 Swift 的早期 Beta 版本:

      我遇到了同样的问题:在 Beta 2 的发行说明中,您可以找到以下声明:

      Interface Builder 不支持在 Swift 类中声明插座集合

      我通过以下方式解决了这个问题(易于定制):

      class CardGameViewController: UIViewController {
        @lazy var cardButtons : UIButton[] = {
          var tempBtn: UIButton[] = []
          for v:AnyObject in self.view.subviews {
            if v is UIButton {
              tempBtn.append(v as UIButton)
            }
          }
          return tempBtn
        }()
      ...
      

      基本上,它会遍历所有子视图并检查其中一个是否为 UIButton。在这种情况下,它会被添加到临时数组中。然后使用这个临时数组来延迟实例化 cardButtons 数组。详情请查看:Matchismo: Objective-C to Swift

      【讨论】:

        【解决方案5】:

        按照步骤创建插座阵列并将其与 IB 元素连接:

        • 创建一个 IBOutlets 数组
        • 在 Storyboard ViewController 界面中添加多个 UIElement(视图)(如下图所示)
        • 选择 ViewController(在故事板中)并打开连接检查器
        • 连接检查器中有“Outlet Collections”选项(您将在那里看到一系列插座)
        • 与您的界面元素连接

        -

        class ViewController2: UIViewController {
        
        
            @IBOutlet var collection:[UIView]!
        
        
            override func viewDidLoad() {
                super.viewDidLoad()
            }
        }
        

        【讨论】:

          【解决方案6】:

          我使用这种语法在 Xcode 种子 3 中工作

          @IBOutlet strong var views: NSArray?
          

          在这里查看我的讨论:https://stackoverflow.com/a/24686602/341994

          【讨论】:

            【解决方案7】:

            @machine 所说的似乎是 iOS 9 绑定的当前状态(XCode 7.1)。 关键是按顺序拖动它们。 使用第一项控制+拖动到控制器代码中,然后将 Outlet 类型更改为集合。从控制器代码文件中将出口点按顺序一一拖到每个屏幕控件上(如@machine所说)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-07-23
              • 2014-11-23
              • 2021-07-17
              • 2016-03-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多