web-dev-qa-db-ja.com

IBDesignableビューのレンダリングがタイムアウトする

最初のXCode 6/iOS 8ベータリリースから数ヶ月間、アプリのオンとオフに取り組んできました。私が追加した私のお気に入りの機能の1つはライブレンダリングで、@IBDesignable Swiftのタグ。

ライブレンダリングで1つのものを取得することができませんでした。ベータ版だったのではないかと思ったので、完全版が出るのを待ってやり直しました。それでも失敗しました。私はそのとき、コードにベータリリースからのアーティファクトがあるかもしれないと考えたので、それを破棄して新鮮に始めました。それでも動作しません。もちろん、エラーはもう少し説明的です。

これが私のコードです:

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()
    }
}

ストーリーボードのこれらのボタンの1つを使用してビルドしようとすると、次のエラーが発生します。

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は丸みのある長方形の描画アルゴリズムを非効率的に設計することに驚いたが、これがこの問題の理由かもしれないと考えた。色を設定して長方形をそのまま描画するように切り替えた。それでも問題がありました。

私はググしていて、この問題を抱えていると思われる人がいないため、私が間違っている小さなことが1つあると思います(とにかく願っています)。それはある種の無限ループかもしれないようですか?

継続するために必要なことではありませんが、ライブレンダリングを機能させることで、インターフェイスを表示してテストすることができるため、開発をより速く簡単に行うことができます。

これを解決する方法について遠い手がかりを持っている人に前もって感謝します。

25
jchitel

どうやらinit(frame: CGRect)とともにinit(code: NSCoder)をオーバーライドする必要がありました。

うまくいきました!これがうまくいかなかった理由を誰かが説明できれば、それはすばらしいことです。そうでなければ、私はここで元気です。

49
jchitel

これは本当に役立つ回答ではないかもしれませんが、30分の解決策を探した後、Xcodeを単純に閉じて再び開くとうまくいくことがわかりました。まだ試していない場合は、試してみてください!

6
Nathan Dries

これを解決するには、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
konsti

同じ問題がありましたが、この素晴らしい記事を一目で見ました。それは私の問題を解決しました。

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

要するに

これらのオプションをxcodeで取得するには

enter image description here

次のようなプロパティを作成します。

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

私にとって、このエラーは、@ IBInspectableプロパティの1つでのCoreDataを使用したsqliteデータベースへの呼び出しのブロックが原因であることがわかりました。

私のコードは最初にデータベースを照会し、次にdispatchAsyncを使用して、照会の結果に基づいてラベルの値を設定しました。クエリもdispatchAsyncブロックで起動されるように変更しました。エラーはすぐに消えました。

他の誰かがこのエラーで問題を抱えている場合は、設計段階で実行されるコード(@IBInspetableでマークされたコンストラクターまたは計算されたプロパティ)を確認することをお勧めします。ブロッキングコード(ネットワーク操作、データベースアクセスなど)がある場合は、タイムアウトエラーの原因となっている可能性があります。お役に立てれば。

0
Michael Daw