【问题标题】:@IBDesignable crashing agent@IBDesignable 崩溃代理
【发布时间】:2015-09-24 18:48:48
【问题描述】:

当我编写自己的UIButton-extended 类并使其成为@IBDesignable 时,我在Interface Builder 中收到两个错误,即:

  • Main.storyboard:错误:IB Designables:无法更新自动布局状态:代理因 fd 关闭而崩溃
  • Main.storyboard:错误:IB Designables:无法呈现 RandjeUIButton 实例:代理崩溃

这是我的代码:

import UIKit

@IBDesignable
class RandjeUIButton: UIButton {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.backgroundColor = UIColor.blackColor()
    }
}

我在 OS X 10.11 beta 2 上使用 Xcode 7 beta 2。(在 VM 中运行)

【问题讨论】:

  • 你还需要覆盖init(frame: CGRect)
  • 我已经这样做了,关于代理的错误现在被解除了。在身份检查器中选择标签时,我现在仍然在 Interface Builder 中看到构建失败?
  • @EricQian 我还覆盖了 override init(frame : CGRect) 和所需的 init?(coder aDecoder: NSCoder) 方法。仍然有同样的错误。

标签: ios xcode swift interface-builder


【解决方案1】:

Xcode 的 Interface Builder 要求您为 @IBDesignable 类实现 bothboth 初始化程序以在 IB 中正确呈现。

如果您实现required init(coder aDecoder: NSCoder),您还需要覆盖init(frame: CGRect),否则“代理将崩溃”,如 Xcode 抛出的错误所示。

为此,将以下代码添加到您的类中:

override init(frame: CGRect) {
    super.init(frame: frame)
}

【讨论】:

  • 我不认为这就是原因。我有两种方法,我在 7.2。它仍在崩溃。
  • 这是我的原因,我删除了init(frame: CGRect),因为我只是从情节提要中初始化它。
  • @mathielo 我还覆盖了 override init(frame : CGRect) 和所需的 init?(coder aDecoder: NSCoder) 方法。仍然有同样的错误
  • 这对我来说是一个非常艰巨的调试挑战。我正在对另一个框架(Pod)中存在的类进行子类化。父类具有没有公共范围的 init 方法之一(默认为内部)。因此,init 方法在我的源代码中不可见。最后,弄清楚了这一点,并在我的项目源代码中复制了父类。非常感谢!
  • 这两个 init 可能还不够。以 UISegmentedControl 为例,你还应该实现 override init(items: [Any]?)
【解决方案2】:

我遇到了同样的问题,用这种方法解决了:

  1. 问题:

错误:IB Designables:无法更新自动布局状态:代理崩溃

  1. 在检查文件中找到调试按钮并点击。

  1. 然后 Xcode 会告诉你问题在哪里。 就我而言,我在上课前放弃了IBDesignable

  2. 然后我清理并重建它,错误消失了

【讨论】:

  • 嗨@Azure,我也面临这个问题。当我单击“调试”按钮时,Xcode(7.3)没有将我移动到导致问题的代码行,因为您在添加的图像上很好地显示了这一点。是 Xcode 的 bug 吗?
  • 嗨~你的问题现在解决了吗?我也使用 Xcode(7.3)。请确保选择导致崩溃的视图并单击调试按钮。
  • 不要忘记在单击“调试”按钮之前创建一个“所有异常”断点,这样调试器将在崩溃后停止几条指令,您可以在堆栈跟踪列表中单击您的代码,或者直接在导致崩溃的指令处单击。
【解决方案3】:

有无数的问题会导致这种情况。启动控制台,查找崩溃报告IBDesignablesCocoaTouch...

我刚刚解决了一个与 valueForKey 语义有关的第 3 方可设计问题。

【讨论】:

    【解决方案4】:

    在 Xcode 7.3 中,上述解决方案均不适用于我,但对这个问题的公认答案是:Failed to render instance of IB Designables

    1. 清除项目的 Xcode 派生数据。它们位于 ~/Library/Developer/Xcode/DerivedData
    2. 按 ⌘⇧K 清除当前版本
    3. 构建您的项目
    4. 在情节提要中,转到编辑器菜单并刷新所有视图;等待构建完成,错误应该消失

    我不需要执行第 4 步来解决问题(并让我的 PaintCode-drawRect'd UIView 在情节提要中进行绘制),以防万一。

    感谢@Mojtaba 和@WeZZard

    【讨论】:

      【解决方案5】:

      对我来说,不是使用#if !TARGET_INTERFACE_BUILDER 让我着迷。基本上我有一些代码会导致访问我的 Bundle 中的路径...

      Bundle.main.path(forResource: "Foo", ofType: "plist")
      

      问题在于,当在 IB(而不是您的应用程序)中运行时,Bundle.main 不是您的应用程序...

      (lldb) po Bundle.main
      NSBundle </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays> (loaded)
      

      因此,这个问题的答案就是仔细检查您的 @IBDesignable UIView 代码,并将 #if !TARGET_INTERFACE_BUILDER 用于在设计时运行时没有意义的任何事情(例如,在我的情况下调用 CoreLocation)。

      我是如何调试和发现的

      这是您在故事板中选择 @IBDesignable UIView 时使用 Editor -&gt; Debug Selected View 时看到的内容:

      然后你会在正确的位置崩溃

      在我的例子中,您可以看到 initXXXX 正在执行 assert,它在设计时崩溃,因为它在设计时在我的 Bundle 中寻找文件中的值 - 这是 Xcode。

      【讨论】:

      • 如果我们必须使用@IBDesignable 有什么意义> #if !TARGET_INTERFACE_BUILDER
      【解决方案6】:

      在任何标记为@IBDesignable 的类中使用UIImage 时,我发现了一些非常重要的东西。 经典的 UIImage 初始化会使代理崩溃:

      let myImage = UIImage(named: String) // crash the agent
      

      解决方法是使用UIImage的这个init方法:

      let myImage = UIImage(named: String, in: Bundle, compatibleWith: UITraitCollection)
      

      工作代码示例:

      let appBundle = Bundle(for: type(of: self))
      let myImage = UIImage(named: "myImage", in: bundle, compatibleWith: self.traitCollection))
      

      self 是带有@IBDesignable 关键字的类。 Xcode 9.4,斯威夫特 4.1

      【讨论】:

        【解决方案7】:

        XCode 10、Swift 4.2

        我找到了答案here

        解决方案很简单 - 在我的自定义视图类的 required init?(coder aDecoder: NSCoder) 方法中更改捆绑包的解析方式。

            Bundle.main.loadNibNamed(String(describing: TestView.self), owner: self, options: nil)
        

        需要改成

        let bundle = Bundle(for: TestView.self)
        bundle.loadNibNamed(String(describing: TestView.self), owner: self, options: nil)
        

        【讨论】:

          【解决方案8】:

          这就是我解决这个问题的方法:

          • 确保插座已正确初始化
          • @IBInspectable 属性将被正确初始化
          • 在 xib 文件中,单击文件的所有者占位符,转到身份检查器,确保它没有任何默认值

          import UIKit
          
          @IBDesignable class TestView: UIView {
              
              @IBOutlet weak var label: UILabel!
              
              
              @IBInspectable var textLabel1: String? {
                  get {
                      return label.text
                  }
                  set {
                      label.text = newValue
                  }
              }
          
              
              // MARK: Setup
              
              var view1: UIView!
              var nibName: String = "TestView"
              
              
              override init(frame: CGRect) {
                  super.init(frame: frame)
                  xibSetup()
              }
              
              required init?(coder aDecoder: NSCoder) {
                  super.init(coder: aDecoder)
                  xibSetup()
              }
              
              private func xibSetup() {
                  view1 = loadViewFromNib()
                  
                  view1?.frame = self.bounds
                  view1?.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
                  
                  if view1 != nil {
                      addSubview(view1!)
                      //textLabel1 = "ok"
                  }
              }
              
              private func loadViewFromNib() -> UIView? {
                  let bundle = NSBundle(forClass: self.dynamicType)
                  let nib = UINib(nibName: nibName, bundle: bundle)
                  for object in nib.instantiateWithOwner(self, options: nil) {
                      if let view: UIView = object as? UIView {
                          return view
                      }
                  }
                  return nil
              }
              
              
          }

          用法:

          【讨论】:

            【解决方案9】:

            只需在另一个 Xcode 设置系统上重新打开代码即可。就我而言,它有效。

            【讨论】:

            • 这似乎适用于某些情况。我遇到了同样的问题尝试了所有可能无法解决问题的方法,最后我确实完全关闭了 xcode 并打开了另一个没有实现任何@IBDesignable 的项目,并打开了代理崩溃的项目和错误消息消失了。我没有任何有效的逻辑,但似乎 xcode 有一些沼泽:(
            【解决方案10】:

            我浪费了一整天的时间,终于解决了我的问题

            我选择 Build for target 作为 8.0,它为我修复了所有问题。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-12-03
              • 2021-07-27
              • 2019-07-21
              • 1970-01-01
              • 2015-10-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多