【发布时间】:2021-03-24 22:00:43
【问题描述】:
我的项目有一个非常奇怪的问题。 XCode 一直给我红色错误,并说我的 IBDesignables 有问题。但是错误信息每次都不同,而且总是另一个视图控制器受到影响。我不知道如何找到问题的原因。我创建的所有 IBDesignables 似乎都是随机发生的。
该应用程序仍然有效。虽然,有时它不能正确呈现某些视图(我有带有自定义绘制蒙版的视图)。它很少发生,但确实会发生。
这些是我得到的错误:
“更新自动布局状态失败:代理崩溃”
"无法为 {randomly 渲染和更新自动布局状态 选择的 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()
}
}
}
谢谢大家的帮助!
【问题讨论】:
-
我今天也遇到了类似的问题,我尝试
debug这个类,发现崩溃可能是由于属性没有初始化,所以你可能需要调试看看是哪个语句它崩溃了。 -
您的意思是设置断点并逐步执行?我试过了,不幸的是,它没有崩溃。我尝试了多次
-
不,转到
identify inspector,您会在顶部看到Designable标签,右侧有一个小debug按钮。点击debug按钮,可以看到是哪条语句让你崩溃了 -
我没有在身份检查器中找到它,但我使用了“编辑器->调试选定的视图”。我跳过它,它确实崩溃了。我现在来看看这个。也许这就是导致我的问题的原因。谢谢,到目前为止!