IBDesignable View渲染超时

时间:2014-11-06 06:03:45

标签: ios xcode rendering ibdesignable

从第一个XCode 6 / iOS 8 beta版本开始,我一直在开发和关闭应用程序几个月。我最喜欢的功能之一是实时渲染,可以使用Swift中的@IBDesignable标记。

我无法通过渲染来获得一件事。我认为一定是因为它是测试版,所以我决定等待完整版本再次尝试。它仍然失败了。我认为在我的代码中可能存在来自beta版本的工件,所以我废弃它并重新开始。它仍然无法正常工作。当然,这些错误现在更具描述性。

这是我的代码:

import UIKit

@IBDesignable class MyButton : UIButton {

    let UNPRESSED_COLOR = UIColor(red: 221.0/256.0, green: 249.0/256.0, blue: 14.0/256.0, alpha: 1.0)
    let PRESSED_COLOR = UIColor(red: 166.0/256.0, green: 187.0/156.0, blue: 11.0/256.0, alpha: 1.0)
    var buttonColorValue: UIColor

    let TEXT_COLOR = UIColor(red: 72.0/256.0, green: 160.0/256.0, blue: 5.0/256.0, alpha: 1.0)

    required init(coder: NSCoder) {
        self.buttonColorValue = UNPRESSED_COLOR
        super.init(coder: coder)
        // Initialization code
        self.setTitleColor(TEXT_COLOR, forState: UIControlState.Normal)
        self.setTitleColor(TEXT_COLOR, forState: UIControlState.Highlighted)
        self.setTitleColor(TEXT_COLOR, forState: UIControlState.Selected)
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        buttonColorValue = PRESSED_COLOR
        self.setNeedsDisplay()
    }

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        buttonColorValue = UNPRESSED_COLOR
        self.setNeedsDisplay()
    }

    override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {
        super.touchesCancelled(touches, withEvent: event)
        buttonColorValue = UNPRESSED_COLOR
        self.setNeedsDisplay()
    }

    override func drawRect(rect: CGRect) {
        buttonColorValue.setFill()
        let ctx = UIGraphicsGetCurrentContext()
        CGContextFillRect(ctx, rect)
        //UIBezierPath(roundedRect: rect, cornerRadius: 5.0).fill()
    }
}

以下是我在故事板中尝试使用其中一个按钮构建时出现的错误:

IB Designables: Failed to update auto layout status: Interface Builder Cocoa Touch Tool crashed

IB Designables: Failed to render instance of MyButton: Rendering the view took longer than 200 ms. Your drawing code may suffer from slow performance.

正如您在我的代码中看到的那样,我原本希望这个按钮被舍入。我想这可能是造成这个问题的原因,尽管让我感到惊讶的是Apple会设计一个效率低下的圆角矩形绘图算法。我切换到简单地设置颜色并按原样绘制矩形。还是有问题。

我认为(我希望,无论如何)有一件小事我做错了,因为我用Google搜索了,似乎没有其他人似乎有这个问题。好像它可能是某种无限循环?

这不是我继续需要的东西,但让实时渲染工作将使我的开发更快更容易,因为我将能够看到我的界面并测试它们而无需运行它们。

提前感谢任何有关如何解决这个问题的远程线索的人。

5 个答案:

答案 0 :(得分:49)

显然我需要覆盖init(frame: CGRect)以及init(code: NSCoder)

搞定了!如果有人可以解释为什么这不起作用,那就太好了。否则,我在这里很好。

答案 1 :(得分:6)

虽然这可能不是一个有用的答案,但我发现在寻找一个解决方案半小时后,简单的关闭并重新打开Xcode就可以了 - 如果你还没有试过这个,那就给它吧一个去!

答案 2 :(得分:3)

确保覆盖prepareForInterfaceBuilder来解决此问题。

@IBDesignable
class SomeView: UITableView {
 @IBInspectable var something: Int? { didSet { setup() } }

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

override init(frame: CGRect, style: UITableViewStyle) {
    super.init(frame: frame, style: style)
    setup()
}

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setup()
}

func setup() {
    // do sth
}
}

答案 3 :(得分:1)

有同样的问题,但只要看一眼这篇伟大的文章。它解决了我的问题。

http://nshipster.com/ibinspectable-ibdesignable/

简而言之

在xcode中获取这些选项

enter image description here

制作这样的房产:

@IBInspectable var cornerRadius: CGFloat = 0 {
   didSet {
       layer.cornerRadius = cornerRadius
       layer.masksToBounds = cornerRadius > 0
   }
}

答案 4 :(得分:0)

对我来说,这个错误原来是由于在我的一个@IBInspectable属性中对sqlite数据库(使用CoreData)的阻塞调用。

我的代码最初查询数据库,然后使用dispatchAsync根据查询结果设置标签的值。我更改了它,以便查询也在dispatchAsync块中启动。错误立刻就消失了。

如果其他人遇到此错误的问题,我建议检查在设计阶段执行的任何代码(构造函数或使用@IBInspetable标记的计算属性)。如果存在任何阻止代码(网络操作,数据库访问等),则可能导致超时错误。希望这会有所帮助。