【问题标题】:IB Designables: Failed to render and update auto layout statusIB Designables:无法渲染和更新自动布局状态
【发布时间】:2018-03-25 05:19:51
【问题描述】:

我有一个自定义视图 (xib),其中有一个 UIButton,我将 id IBDesignable 设置为:

UserView.swift

import UIKit

@IBDesignable
class UserView: UIView {

    @IBOutlet var view: UIView!
    @IBOutlet weak var userButton: UIButton!

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

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        load()
    }

    fileprivate func load() {
        Bundle.main.loadNibNamed("UserView", owner: self, options: nil)
        addSubview(view)
        self.frame = bounds
    }

}

UserView.xib

  • 添加了 UIButton 并设置了约束
  • 设置文件所有者:UserView

故事板

我将 UIView 添加到 Bar Button Item 并分配了 UserView 类,但没有呈现任何内容,并且出现以下构建错误:

错误:IB Designables:无法呈现和更新自动布局状态 对于 FoodViewController (bR3-Kz-wX7):代理抛出异常。

我目前的环境:Xcode 9、Swift 4

【问题讨论】:

标签: ios swift xcode interface-builder ibdesignable


【解决方案1】:

我刚刚遇到了完全相同的问题,唯一对我有用的是,我必须为我想要的 Nib 获取捆绑包,而不是使用主捆绑包。本质上的变化:

Bundle.main.loadNibNamed("UserView", owner: self, options: nil)

收件人:

let bundle = Bundle(for: UserView.self)
bundle.loadNibNamed("UserView", owner: self, options: nil)

这很奇怪,就我而言,在运行时在 LLDB 中比较两个 Bundle 时它们是相同的(类名不同,但我的其余设置与 OP 相同)

更新

为什么从主包加载 NIB 不起作用?

因为在 InterfaceBuilder 渲染时它没有运行应用程序。没有“主应用程序包”。

【讨论】:

  • 这对我有用,有谁知道为什么从主包加载 NIB 不起作用?
  • 因为 InterfaceBuilder 正在渲染它并没有运行应用程序。没有“主应用程序包”。
  • @quellish 既然你这么说,那就太有道理了!为什么文档中没有,或者至少在 Xcode 帮助中他们实际介绍了@IBDesignable?!
  • 绝妙的答案:)
【解决方案2】:

我在Podfile 的末尾添加了这个脚本并再次执行pod install。所以我可以正常构建我的项目。

post_install do |installer|
    installer.pods_project.build_configurations.each do |config|
        config.build_settings.delete('CODE_SIGNING_ALLOWED')
        config.build_settings.delete('CODE_SIGNING_REQUIRED')
    end
end

【讨论】:

  • 这对我也有用。我只是好奇问题是什么以及这段代码到底做了什么。它会影响我项目中的其他任何事情吗?
  • 它也对我有用。它只是放宽了对要通过 Cocoapods 加载的框架的代码签名要求。
【解决方案3】:

这个问题与这个答案有关。检查两者。
Failed to render instance of ClassName: The agent threw an exception loading nib in bundle

底线

确保您的 xib 文件没有任何孤立的插座。检查笔尖的每个视图/元素是否有插座,然后删除并重新添加。

对我来说,它们是孤立的网点。似乎 nib 和 IB 非常挑剔,调试器没有提供很多细节……如果你不能让它工作,你可以从一个新的 nib/xib 文件开始。


我的工作代码演练

这个问题我花了好几天才解决。为了其他人的利益,我给出了一个详细的答案并显示了我所有的相关代码和连接。

我实施了修复操作(上图)的工作提交在这里: https://github.com/jfosterdavis/ZMAppFoundation/commit/6855f0d5b9cd1bc320395e57e2b271653ef7acd1

Xcode 9.2 版

我的文件结构

这是我的文件结构(注意:我正在使用名为 ZMAppFoundation 的 cocoapods 创建一个 pod。此外,ZMPieTimerView.swift 与解决方案无关。):

我希望我的 nib 在 Main.storyboard 文件中可见(IBDesignable)。这是我的 xib ZMGauge.xib 的文件所有者和自定义类:

代码、实现

这是我的 ZMXibView 类:

//  Adapted from https://medium.com/zenchef-tech-and-product/how-to-visualize-reusable-xibs-in-storyboards-using-ibdesignable-c0488c7f525d

import UIKit

@IBDesignable
open class ZMXibView: UIView {
    
    
    var contentView:UIView?
    @IBInspectable var nibName:String?
    
    override open func awakeFromNib() {
        super.awakeFromNib()
        xibSetup()
    }
    
    func xibSetup() {
        guard let view = loadViewFromNib() else { return }
        view.frame = bounds
        view.autoresizingMask =
            [.flexibleWidth, .flexibleHeight]
        addSubview(view)
        contentView = view
    }
    
    func loadViewFromNib() -> UIView? {
        guard let nibName = nibName else { return nil }
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(
            withOwner: self,
            options: nil).first as? UIView
    }
    
    override open func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        xibSetup()
        contentView?.prepareForInterfaceBuilder()
    }
}

在故事板中,我的 xib 是在自定义类中指定的。我正在使用 cocoapods 开发一个豆荚。我已经明确选择了模块。 (请注意,在我的 XibView 类中,我必须定义 nibName 属性。):

别忘了!

然后您可能需要清理、关闭 Xcode、重建或只是等待 IB 再次渲染它。 Xcode 何时决定尝试渲染 IBDesignables 对我来说仍然是个谜,我不知道有什么方法可以强制。

成功

根据我的代码和我采取的行动,我的笔尖现在可以在 Main.storyboard 中以 IBDesignable 形式查看。

万一你错过了

如果你错过了,我的解决方案在这篇文章的最顶部。我通过删除一些孤立的 IBOutlets 来清除 OP 引用的错误。

【讨论】:

    【解决方案4】:

    Xcode 9.3、CocoaPods 1.5.3 这可能是由于最近更新了 CocoaPods 版本。见issue here。

    我在故事板中遇到了这个错误IB Designables: Failed to render and update auto layout status,Stripe SDK 中的 STPPaymentCardTextField 类与 Cocoapods 相关。

    解决方案是将 CocoaPods 降级到 1.4.0。

    sudo gem list cocoapods
    
    sudo gem uninstall cocoapods
    
    sudo gem install cocoapods -v 1.4.0
    
    pod update
    

    【讨论】:

    • 在所有步骤删除派生数据并重新启动 xcode 之后。它对我有用
    • 我一目了然地忽略了这个答案,因为我在当前项目中使用 Carthage。但是,这会影响项目是否包含 Podfile
    【解决方案5】:

    对我来说,修复归结为让 Interface Builder 重绘对象。我在两个地方都有这个问题,并且都没有更改代码,但代理错误的症状和情节提要中的视图为空白最终得到了修复。

    通过将 UIView 拖到 View 下的不同顺序并重新构建,已修复。通过选择 TableView,将 Prototype 单元格的计数更改为两个,等待一秒钟,然后将其更改回一个,从而修复了带有 Prototype 单元格的 TableView 中的一秒。 TableView,本来是一片空白,然后正确地绘制了所有元素,代理错误消失了。

    感觉这是 IB 的一个错误,从其他搜索来看,存在许多针对类似错误的解决方案。希望这对某人有所帮助。

    【讨论】:

    • 这个答案在 Xcode 11.2.1 中仍然适用。我能够在表格视图表单属性检查器中简单地增加原型单元格的数量,顶部的状态栏显示一个正在启动的过程(该过程很快完成),当它完成后,我将原型单元格带回原来的编号和视图控制器再次出现。
    【解决方案6】:

    (xCode 9.2, Swift 4) 以下内容可能对您的确切问题没有帮助,但可能会帮助其他人解决非常相似的问题。这是我的错误:

    错误:IB Designables:无法呈现和更新 CustomExampleView (XXXXX) 的自动布局状态:代理崩溃

    删除 CustomExampleView.xib 和 CustomExampleView.swift 时,我能够消除错误。为了复制,我重新创建了文件,转到 .xib 并将顶级视图的自定义类设置为 CustomExampleView。

    我的错误将自定义类设置为 .xib 上的顶级视图,而不是在 文件的所有者上设置自定义类。设置正确的自定义类后,我的问题就解决了。

    【讨论】:

    • 在查看了上面更复杂的答案之后,这个更简单的解决方案原来是我的解决方案。如果您在 Swift 中没有那么先进,这可能是您的问题。上面提到的文件所有者位于 .xib 视图中“占位符”的正下方,视图图标树的正上方等。出于某种原因,在旧版本的 Swift 中这无关紧要,但它现在会导致此错误。跨度>
    【解决方案7】:

    我对按照我将要告诉你的事情有所不同是多么愚蠢,但你可以尝试从

    中删除破坏代码
    override func prepareForInterfaceBuilder() {
    

    并且只在

    中使用
    override func awakeFromNib() {
    

    。当我报告说您的更改仍然可能在执行此操作时根据需要反映在情节提要中时,我更加畏缩了。

    您可以通过注释掉所有行并使用排除过程来识别中断代码来识别中断代码。

    【讨论】:

    • 这原来是我的问题的解决方案,虽然答案本身写得不好,我一开始忽略了它。简而言之,我的 init 函数中有代码,它只在运行时(而不是设计时)有意义。将其移至 awakeFromNib 对我来说是正确的解决方案。
    • 嘿@JohnJ.Camilleri,欢迎来到 StackOverflow!如果您想编辑答案,可以按下答案下方的编辑按钮,我敢打赌您有一些很好的编辑建议。
    【解决方案8】:

    对我来说,这个问题解决了,

    1. 更新 pod。
    2. 将 Swift 库的构建设置更改为“$(inherited)” 嵌入式选项。
    3. 建筑、清洁、建筑。
    4. 关闭项目。
    5. 退出 Xcode。
    6. 再次运行。

    哈哈哈老黑客 :) 谢谢!

    【讨论】:

    • 嗯...是的,清除派生数据,关闭 xcode,更新 pod 并打开 xcode。也为我工作!!!
    【解决方案9】:
        post_install do |installer|
        installer.pods_project.build_configurations.each do |config|
            config.build_settings.delete('CODE_SIGNING_ALLOWED')
            config.build_settings.delete('CODE_SIGNING_REQUIRED')
        end
    end
    

    在 Podfile 中输入上述代码即可解决问题。这段代码只是取消了通过 Cocoapods 对已安装框架进行代码签名的要求。但这似乎也是 IBDesignable 中的一个错误,因为使用 Xcode 10 bets 4 由于 Xcode 10 中包含了新的构建系统,我没有得到这个错误。

    【讨论】:

      【解决方案10】:

      这是 1.5.0 等一些可可豆荚版本的问题。 如果您使用的是这个,那么它会导致渲染失败 从当前版本移动到其他在终端中运行此命令

      sudo gem uninstall cocoapods
      

      您可以通过这样提及来安装任何特定版本

      sudo gem install cocoapods -v 1.4.0
      

      希望它对你有用。

      【讨论】:

      • 它不适合我。当我在 xcode 9.4.1 中工作时,问题正在发生。如果我在 xcode 9.3 中工作就可以了。
      • 试试这个 Xcode -> 首选项 -> 常规并检查实时问题
      【解决方案11】:

      很遗憾,您不能在 IBDesignable 中使用 IBOutlets。在这里为您提供更好的答案:

      Live Render IBOutlet Connected Subviews Via IBInspectable Properties

      也许您想让您的 UserView 扩展 UIButton,而不是 UIView?

      【讨论】:

        【解决方案12】:

        我不太了解造成这种情况的原因,但我已经看过几次了,每次只需重新启动 xcode 即可解决。我认为这是每个人都应该开始的地方,如果这不起作用,那么您可以尝试其他建议的答案。

        【讨论】:

          【解决方案13】:

          XCode 11.6

          如果您使用UITableView & 原型单元格,请选择 UITableView 并在属性检查器中,只需增加原型单元格的数量即可。然后 xcode 将自动再次构建它并解决问题。解决后,将计数减少到以前的值。

          【讨论】:

            【解决方案14】:

            我禁用了“用户特征变化”,我的问题得到了解决。

            【讨论】:

            • 这里没有帮助。我们应该应用另一个步骤。 (如 pod 后安装和擦除派生数据)
            猜你喜欢
            • 2020-06-29
            • 1970-01-01
            • 2017-02-05
            • 1970-01-01
            • 1970-01-01
            • 2018-11-10
            • 2018-06-24
            相关资源
            最近更新 更多