我对项目有一个非常奇怪的问题。 XCode一直给我红色错误,并说我的IBDesignables有问题。但错误消息每次都不同,并且它总是受到另一个视图控制器的影响。我不知道如何找到问题的原因。它似乎与我创建的所有IBDesignables随机发生。
该应用程序仍然有效。虽然,有时它不能正确渲染一些视图(我有自定义绘制蒙版的视图)。它很少发生,但确实发生了。
这些是我得到的错误:
“无法更新自动布局状态:代理程序崩溃”
“无法呈现和更新{随机的自动布局状态 选择VC名称}:代理商崩溃了“
一旦点击它就会消失。有时,当我进入故事板时,所有错误都会消失。当我打开任何其他文件时,我会收到多个红色错误(有时像3,有时是6或更多)。
我检查了崩溃日志。他们中的每一个都说:
致命错误:在解包可选值时意外发现nil
我不确定这意味着什么。
我尝试清理项目并重新启动XCode。
另外,我实现了所有init
方法。
以下代码是class
(几乎)总是我得到的错误的一部分。此外,它是自定义绘制的视图,有时无法正确呈现:
import UIKit
struct TriangleViewLabelDefault {
static let triangleWidth: CGFloat = 20
static let triangleHeight: CGFloat = 10
}
@IBDesignable
class TriangleView: UIView {
let DEFAULT_TRIANGLE_WIDTH: CGFloat = 30
let DEFAULT_TRIAGNLE_HEIGHT: CGFloat = 20
struct Triangle {
static var width: CGFloat = TriangleViewLabelDefault.triangleWidth
static var height: CGFloat = TriangleViewLabelDefault.triangleHeight
static var midXPosition: CGFloat = 0
}
@IBInspectable var triangleWidth: CGFloat = TriangleViewLabelDefault.triangleWidth {
didSet {
Triangle.width = triangleWidth
}
}
@IBInspectable var triangleHeight: CGFloat = TriangleViewLabelDefault.triangleHeight {
didSet {
Triangle.height = triangleHeight
}
}
@IBInspectable var relativePosition: Bool = true {
didSet {
setNeedsDisplay()
}
}
@IBInspectable var triangleMidXOffset: CGFloat = 0 {
didSet {
setNeedsDisplay()
}
}
@IBInspectable var decoration: Bool = true {
didSet {
setNeedsDisplay()
}
}
@IBInspectable var lines: Int = 20 {
didSet {
setNeedsDisplay()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func draw(_ rect: CGRect) {
super.draw(rect)
calcTriangleMidXPosition()
addLines()
if decoration {
addDecoration()
}
let maskLayer = CAShapeLayer()
maskLayer.frame = bounds
let maskPath = UIBezierPath()
maskPath.move(to: CGPoint(x: 0, y: Triangle.height))
/* Triangle */
maskPath.addLine(to: CGPoint(x: Triangle.midXPosition - Triangle.width, y: Triangle.height))
maskPath.addLine(to: CGPoint(x: Triangle.midXPosition, y: 0))
maskPath.addLine(to: CGPoint(x: Triangle.midXPosition + Triangle.width, y: Triangle.height))
/* */
maskPath.addLine(to: CGPoint(x: bounds.size.width, y: Triangle.height))
maskPath.addLine(to: CGPoint(x: bounds.size.width, y: bounds.size.height))
maskPath.addLine(to: CGPoint(x: 0, y: bounds.size.height))
maskPath.addLine(to: CGPoint(x: 0, y: Triangle.height))
maskPath.close()
maskLayer.path = maskPath.cgPath
layer.mask = maskLayer
}
/// Evaluates the properties set in storyboard. This methods calculates the x-center of the triangle
private func calcTriangleMidXPosition() {
if relativePosition {
Triangle.midXPosition = bounds.size.width / 2 + triangleMidXOffset * bounds.size.width / 2
} else {
Triangle.midXPosition = bounds.size.width / 2 + triangleMidXOffset
}
}
private func addDecoration() {
if let superview = superview {
let topLine = UIView(frame: CGRect(x: 0, y: frame.minY + Triangle.height - 2, width: bounds.size.width, height: 1))
let bottomLine = UIView(frame: CGRect(x: 0, y: frame.minY + Triangle.height - 4, width: bounds.size.width, height: 1))
topLine.backgroundColor = UIColor.white
bottomLine.backgroundColor = UIColor.white
topLine.alpha = 0.5
bottomLine.alpha = 0.2
superview.insertSubview(topLine, belowSubview: self)
superview.insertSubview(bottomLine, belowSubview: self)
}
}
private func addLines() {
guard lines > 0 else {
return
}
let paddingLeft: Int = 20
let lineLength: Int = 25
let linesLayer = CAShapeLayer()
linesLayer.frame = bounds
let padding: CGFloat = 20
let minY = Triangle.height + padding
let maxY = bounds.height - padding
let yArea = maxY - minY
for x in 0...lines {
let path = UIBezierPath()
path.lineWidth = 3.0
path.move(to: CGPoint(x: CGFloat(paddingLeft), y: minY + CGFloat(x) * yArea / CGFloat(lines)))
path.addLine(to: CGPoint(x: CGFloat(paddingLeft) + CGFloat(lineLength), y: minY + CGFloat(x) * yArea / CGFloat(lines)))
UIColor(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, alpha: 1.0).setStroke()
path.stroke()
}
}
}
谢谢你们的帮助!
答案 0 :(得分:5)
每次发生“代理崩溃”问题时,都会创建崩溃日志。你可以在这里找到所有这些:
/Users/<user>/Library/Logs/DiagnosticReports
命名为IBDesignablesAgentCocoaTouch _ *。崩溃
进入Finder(转到&gt;转到文件夹),复制路径并替换为您的用户名。
你可能会有太多的崩溃日志,你可以删除它们,清理你的项目,再次构建并检查文件夹。
答案 1 :(得分:3)
答案 2 :(得分:0)
我在创建一个复选框按钮时遇到了问题,该按钮定义了2个UIImage,用于选中和未选中。 代码确实运行良好,但是Agent因IBDesignable而崩溃(IBInspectable没问题)
我注意到了几个原因: 不得在类内部创建UIImages 我必须在外部声明一个属性,以保存选定的图像,然后在init(coder)中初始化:
import UIKit
let checkedImage = UIImage(named: "checked")!// as UIImage
let uncheckedImage = UIImage(named: "unchecked")!// as UIImage
@IBDesignable class CheckBox: UIButton {
@IBInspectable public var image: UIImage?
我必须删除计算属性中的setImage
@IBInspectable public var isChecked: Bool = false { // this caused a crash
didSet{
if isChecked == true {
self.setImage(checkedImage, for: UIControl.State.normal)
} else {
self.setImage(uncheckedImage, for: UIControl.State.normal)
}
}
}
只保留
@IBInspectable public var isChecked: Bool = false
最后添加了绘画功能
override func draw(_ rect: CGRect) {
image?.draw(in: rect)
}
如果这可以帮助其他人。