@IBDesignable 崩溃剂
@IBDesignable crashing agent
当我编写自己的 UIButton
-extended class 并使其成为 @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()
}
}
我在 Xcode 7 beta 2 OS X 10.11 beta 2 上工作。(运行 在 VM 中)
Xcode 的 Interface Builder 要求您实现 both or nether initializer for @IBDesignable
classes 在 IB 中正确呈现。
如果您实施 required init(coder aDecoder: NSCoder)
,您还需要重写 init(frame: CGRect)
,否则 "the agent will crash",如 Xcode.[=14= 抛出的错误所示]
为此,将以下代码添加到您的 class:
override init(frame: CGRect) {
super.init(frame: frame)
}
有无数的问题会导致这种情况。启动控制台,并查找崩溃报告 IBDesignablesCocoaTouch...
我刚刚解决了第 3 方可设计的问题,该问题与 valueForKey
语义有关。
我遇到了同样的问题,并且是这样解决的:
- 问题:
错误:IB Designables:无法更新自动布局状态:代理崩溃
- 在检查文件中找到调试按钮并点击它。
然后Xcode会告诉你问题出在哪里。
在我的例子中,我在 class.
之前删除了 IBDesignable
然后我清理并重建它,错误消失了
我是这样解决这个问题的:
- 确保插座已正确初始化
- @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
}
}
用法:
在 Xcode 7.3 中,上述解决方案中的 none 对我有用,但对这个问题的接受答案确实如此:Failed to render instance of IB Designables
- Clear Xcode derived data for the project. They are in ~/Library/Developer/Xcode/DerivedData
- Clean your current build by pressing ⌘⇧K
- Build your project
- In storyboard go to Editor menu and do Refresh All Views; wait for build to be completed and errors should be gone
我不需要执行第 4 步来解决问题(并让我的 PaintCode-drawRect'd UIView 在故事板中绘制),以防万一。
感谢@Mojtaba 和@WeZZard
对我来说,不是使用 #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 -> Debug Selected View
时看到的内容:
然后你会在正确的位置坠毁
就我而言,如您所见,initXXXX
正在执行一个 assert
,它在设计时崩溃了,因为它正在我的 Bundle 中的文件中寻找一个值——它是 Xcode,在设计时。
只需在另一个 Xcode 安装系统上重新打开一个代码。在我的例子中它起作用了。
我为此浪费了一整天,终于解决了我的问题
我选择 Build for target 为 8.0,它为我修复了所有问题。
在任何 class 标记为@IBDesignable 的地方使用 UIImage 时,我发现了一些非常重要的东西。
classic UIImage init 会使代理崩溃:
let myImage = UIImage(named: String) // crash the agent
解决方法是使用UIImage的这个初始化方法:
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 是您的 class 和 @IBDesignable 关键字。
Xcode9.4,Swift4.1
XCode10,Swift4.2
我找到了答案here
解决方案很简单 - 更改在我的自定义视图 required init?(coder aDecoder: NSCoder)
方法中解析包的方式 class。
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)
当我编写自己的 UIButton
-extended class 并使其成为 @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()
}
}
我在 Xcode 7 beta 2 OS X 10.11 beta 2 上工作。(运行 在 VM 中)
Xcode 的 Interface Builder 要求您实现 both or nether initializer for @IBDesignable
classes 在 IB 中正确呈现。
如果您实施 required init(coder aDecoder: NSCoder)
,您还需要重写 init(frame: CGRect)
,否则 "the agent will crash",如 Xcode.[=14= 抛出的错误所示]
为此,将以下代码添加到您的 class:
override init(frame: CGRect) {
super.init(frame: frame)
}
有无数的问题会导致这种情况。启动控制台,并查找崩溃报告 IBDesignablesCocoaTouch...
我刚刚解决了第 3 方可设计的问题,该问题与 valueForKey
语义有关。
我遇到了同样的问题,并且是这样解决的:
- 问题:
错误:IB Designables:无法更新自动布局状态:代理崩溃
- 在检查文件中找到调试按钮并点击它。
然后Xcode会告诉你问题出在哪里。 在我的例子中,我在 class.
之前删除了 然后我清理并重建它,错误消失了
IBDesignable
我是这样解决这个问题的:
- 确保插座已正确初始化
- @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
}
}
用法:
在 Xcode 7.3 中,上述解决方案中的 none 对我有用,但对这个问题的接受答案确实如此:Failed to render instance of IB Designables
- Clear Xcode derived data for the project. They are in ~/Library/Developer/Xcode/DerivedData
- Clean your current build by pressing ⌘⇧K
- Build your project
- In storyboard go to Editor menu and do Refresh All Views; wait for build to be completed and errors should be gone
我不需要执行第 4 步来解决问题(并让我的 PaintCode-drawRect'd UIView 在故事板中绘制),以防万一。
感谢@Mojtaba 和@WeZZard
对我来说,不是使用 #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 -> Debug Selected View
时看到的内容:
然后你会在正确的位置坠毁
就我而言,如您所见,initXXXX
正在执行一个 assert
,它在设计时崩溃了,因为它正在我的 Bundle 中的文件中寻找一个值——它是 Xcode,在设计时。
只需在另一个 Xcode 安装系统上重新打开一个代码。在我的例子中它起作用了。
我为此浪费了一整天,终于解决了我的问题
我选择 Build for target 为 8.0,它为我修复了所有问题。
在任何 class 标记为@IBDesignable 的地方使用 UIImage 时,我发现了一些非常重要的东西。 classic UIImage init 会使代理崩溃:
let myImage = UIImage(named: String) // crash the agent
解决方法是使用UIImage的这个初始化方法:
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 是您的 class 和 @IBDesignable 关键字。 Xcode9.4,Swift4.1
XCode10,Swift4.2
我找到了答案here
解决方案很简单 - 更改在我的自定义视图 required init?(coder aDecoder: NSCoder)
方法中解析包的方式 class。
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)