【问题标题】:IBDesignable View Rendering times outIBDesignable 视图渲染超时
【发布时间】:2015-01-02 13:28:46
【问题描述】:

从第一个 XCode 6/iOS 8 测试版开始,几个月来我一直在断断续续地开发一个应用程序。我最喜欢添加的功能之一是实时渲染,它可以通过 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 会设计一个低效的圆角矩形绘图算法。我切换到简单地设置颜色并按原样绘制矩形。还是有问题。

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

这不是我必须继续做的事情,但是让实时渲染工作对我来说将使开发更快、更容易,因为我将能够看到我的接口并对其进行测试,而无需运行它们。

提前感谢任何对如何解决此问题有远程线索的人。

【问题讨论】:

    标签: ios xcode rendering ibdesignable


    【解决方案1】:

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

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

    【讨论】:

    • 根据我读过的其他帖子,实时渲染根本不调用 init(code: NSCoder) -- 只是 init(frame: CGRect)
    • 重写 init(frame: CGRect) , init(code: NSCoder) 和 init() 也对我有帮助。
    • 哈,难怪!谢谢大佬,这也解决了我的问题。想知道为什么 Apple 也不将 init(frame: CGRect) 设为必需的覆盖。
    • 这可能应该被标记为答案,因为它似乎是大多数人的解决方法。立即解决了我的问题。
    • 除此之外,您还应该检查您在 drawRect 中是否使用了任何未初始化的变量,因为这也会导致此问题。
    【解决方案2】:

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

    【讨论】:

      【解决方案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
      }
      }
      

      【讨论】:

        【解决方案4】:

        有同样的问题,但看一眼这篇很棒的文章。它解决了我的问题。

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

        简而言之

        在 xcode 中获取这些选项

        制作这样的属性:

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

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-14
            相关资源
            最近更新 更多