25

最初の XCode 6/iOS 8 ベータ版のリリースから数か月間、アプリのオンとオフに取り組んできました。@IBDesignable追加された私のお気に入りの機能の 1 つは、 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()
    }
}

ストーリーボードでこれらのボタンのいずれかを使用してビルドしようとすると、次のエラーが表示されます。

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 つあります。ある種の無限ループになりそうですか?

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

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

4

5 に答える 5

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
}
}
于 2016-05-12T13:26:35.320 に答える
1

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

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

要するに

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

ここに画像の説明を入力

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

@IBInspectable var cornerRadius: CGFloat = 0 {
   didSet {
       layer.cornerRadius = cornerRadius
       layer.masksToBounds = cornerRadius > 0
   }
}
于 2015-08-10T20:45:11.983 に答える
0

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

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

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

于 2015-03-10T22:39:29.290 に答える