2016-02-03 9 views
21

スウィフトファイルに(childXib)のファイルを添付しました。Ownerです。インターフェイスビルダーでIBDesignable xibを読み込めません

これは私が私のカスタムUIViewを初期化する方法である:

// init for IBDesignable 
override init(frame: CGRect) { 
    super.init(frame: frame) 

    let view = loadViewFromNib() 
    view.frame = bounds 

    addSubview(view) 
} 

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

func loadViewFromNib() -> UIView { 

    let bundle = NSBundle(forClass: self.dynamicType) 
    let nib = UINib(nibName: "CommentCellView", bundle: bundle) 
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView 

    return view 
} 

私は別のxibparentXib)にこのxibchildXib)を追加したい場合は、私は次のエラーを取得:

error: IB Designables: Failed to render instance of MyRootView: The agent threw an exception. 

MyRootViewparentXib

にファイルをリンクされている場合は

childXibにリンクされたファイルです。私はIdentity inspectorからCustom classDebugをクリックすることで、それをデバッグする場合

、そのラインから動作しません:

let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView 

すべてxibファイルはBuild PhasesCopy Bundle Resourcesです。

間違って何任意のアイデア?以下のようなエラーの両方のために

+0

ているのですか?そうであれば、そのクラスにキャストしてみてください。 – AMayes

+0

はい、それらはすべて 'UIView'のサブクラスです – Nico

+0

次に' let view = nib.instantiateWithOwner(self、options:nil)[0] as as try! MyCustomView' – AMayes

答えて

0

:.xibファイルがある

  1. チェックした場合:

    error: IB Designables: Failed to render instance of .... 
    error: IB Designables: Failed to update auto layout status: The agent raised a "NSInternalInconsistencyException" exception: Could not load NIB in bundle ... 
    

    は、私が問題に対処しなければならない場所を把握することを助けることができる小型の迅速な自己検証を持つことが示唆しますプロジェクトに正しく追加されました

  2. nibNameが正しく設定されていることを確認してください。ここでタイプミスが発生することがあります
  3. 両方の出口がチェックされています&適切に接続されているアクションは、 コードの実装が含まれ
14

ファーストステップ:

は、私はあなたにIBDesignableとIBInspectableの紹介を与え、あなたに新しい機能を利用するにはどのようにみんなが表示されます。デモを作成するよりも機能を詳しく説明する方法はありません。そこで、「Rainbow」というカスタムインターフェイスを構築します。 IBDesignableとIBInspectableで

IBDesignableとIBInspectable

、開発者はリアルタイムでInterface Builderでレンダリングインターフェイス(またはビュー)を作成することが許可されています。一般に、この新しい機能を適用するには、UIViewまたはUIControlをサブクラス化してビジュアルクラスを作成し、クラス名の前に@IBDesignableというキーワードをSwiftでプレフィックスする必要があります。 Objective-Cを使用している場合は、代わりにIB_DESIGNABLEマクロを使用します。ここでスウィフトのサンプルコードです:

@IBDesignable 
class Rainbow: UIView { 
} 

のXcodeの古いバージョンでは、ユーザー定義のランタイムは、Interface Builderでのオブジェクト(例えばlayer.cornerRadius)のプロパティを変更する属性を編集することができます。問題は、プロパティの正確な名前をキー入力する必要があることです。 IBInspectableは一歩前進します。あなたはIBInspectableとビジュアルクラスのプロパティの前に付ける場合は、プロパティを使用すると、非常に簡単な方法でその値を変更できるようにInterface Builderにさらされることになります。

enter image description here

もう一度アプリを開発している場合Swiftでは、あなたがしなければならないことは、@IBInspectableというキーワードで選択したプロパティに接頭辞を付けることです。ここではサンプルコードスニペットです:のは、Xcodeで新規プロジェクトを作成し、テンプレートとして単一のビューのアプリケーションを選択することにより、始めましょう

あなたのXcodeのプロジェクトを構築

@IBInspectable var firstColor: UIColor = UIColor.blackColor() 
{ 
    // Update your UI when value changes 
} 



@IBInspectable var firstColor: UIColor = UIColor.blackColor() 
{ 
    // Update your UI when value changes 
} 

、名前をRainbowDemo。このプロジェクトではSwiftをプログラミング言語として使用しますので、プロジェクトを作成する際にはそれを選択することを忘れないでください。

終了したら、Project NavigatorでMain.storyboardを選択し、ViewオブジェクトをオブジェクトライブラリからView Controllerにドラッグします。 #38334C(または好きな色)に変更し、サイズを600 x 434に設定します。次に、メインビューの中央に配置します。メインビューの色をビューオブジェクトの同じ色に変更することを忘れないでください。 ヒント:コードのRGBカラー値を変更するには、カラーパレットを開き、スライダタブに切り替えてRGB値を変更します。

困ったですか?心配ない。プロジェクトのデモを行った後、私が何を意味するのかを理解するでしょう。

Xcode 6では、すべてのタイプのiOSデバイスをサポートするために、ビューの自動レイアウト制約を設定する必要があります。 Auto LayoutはXcodeの最新バージョンでかなり強力です。単純な制約の場合は、[自動レイアウト]メニューの[問題]オプションをクリックし、[欠落している制約を追加]を選択すると、Xcodeによって自動的にレイアウトのレイアウト制約が設定されます。

enter image description here

カスタムビュークラスの作成

今、あなたはストーリーボードでビューを作成したこと、それが私たちのカスタムビュークラスを作成してみましょう。クラス作成のためにSwiftクラステンプレートを使用します。名前を「Rainbow」とします。

enter image description here

Then insert the following code in the class: 

import UIKit 

class Rainbow: UIView { 
    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
    } 
} 

前に述べたように、視覚的なクラスは、のUIViewのサブクラスです。ライブレンダリングでカスタムクラスを使用するには、上記のように両方の初期化子をオーバーライドする必要があります。次アシスタントエディターを選択することで、ビューを分割する:あなたは、リアルタイムで構築しているかを見ることができるように

一度行わ

enter image description here

は、アシスタントエディタでメインストーリーボードを選択します。アイデンティティインスペクタの下に「虹」にビューのクラス名を変更することを忘れないでください:

実装IBDesignableライブレンダリングのための制御を可能にする

最初のステップは、によって設計可能などのカスタムビューを設定することでコントロール

クラス名の前に@IBDesignableを付けます。

@IBDesignable 
class Rainbow: UIView { 
    ... 
} 

これはちょっとわかります。しかし、この単純なキーワードはあなたの開発をはるかに容易にします。次に、サークルの色を設定するためのプロパティをいくつか追加します。レインボークラスでのコード行を挿入します。ここでは

@IBInspectable var firstColor: UIColor = UIColor(red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0) 
@IBInspectable var secondColor: UIColor = UIColor(red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0) 
@IBInspectable var thirdColor: UIColor = UIColor(red: (238.0/255.0), green: (32.0/255) 

、我々はデフォルトの色で各プロパティを事前定義し、ビューを再描画するために、ユーザーがその値を変更するたびにそれを伝えます。最も重要なことは、各プロパティの先頭に@IBInspectableというキーワードを付けます。ビューの属性インスペクタブルに移動すると、これらのプロパティが視覚的に見つかるはずです。

クール、右?プロパティをIBInspectableとして指定すると、カラーピッカーを使用してプロパティを視覚的に編集できます。

さて、画面上に円を描くために使用されるRainbowクラスの主なメソッドを実装しましょう。クラスに次のメソッドを挿入します。

func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat, strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor, shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) { 

    let arc = CAShapeLayer() 
    arc.lineWidth = lineWidth 
    arc.path = path 
    arc.strokeStart = strokeStart 
    arc.strokeEnd = strokeEnd 
    arc.strokeColor = strokeColor.CGColor 
    arc.fillColor = fillColor.CGColor 
    arc.shadowColor = UIColor.blackColor().CGColor 
    arc.shadowRadius = shadowRadius 
    arc.shadowOpacity = shadowOpacity 
    arc.shadowOffset = shadowOffsset 
    layer.addSublayer(arc) 
} 

enter image description here

コードがきれいで、読みやすくするために、我々は、呼び出し側によって提供されたパラメータに応じて完全または半円を描くための一般的な方法を作成します。 CAShapeLayerクラスを使用して円または弧を描くのはかなり簡単です。ストロークの開始と終了は、strokeStartプロパティとstrokeEndプロパティを使用して制御できます。 stokeEndの値を0.0〜1.0の間で変化させることで、円の一部または全部を描くことができます。残りのプロパティは、ストローク、シャドウカラーなどの色を設定するためだけに使用されます。CAShapeLayerで利用可能なすべてのプロパティの詳細については、公式ドキュメントを参照してください。

次に、レインボークラスの次のメソッドを挿入します。

override func drawRect(rect: CGRect) { 
    // Add ARCs 
    self.addCirle(80, capRadius: 20, color: self.firstColor) 
    self.addCirle(150, capRadius: 20, color: self.secondColor) 
    self.addCirle(215, capRadius: 20, color: self.thirdColor) 
} 

func addCirle(arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) { 
    let X = CGRectGetMidX(self.bounds) 
    let Y = CGRectGetMidY(self.bounds) 

    // Bottom Oval 
    let pathBottom = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath 
    self.addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero) 

    // Middle Cap 
    let pathMiddle = UIBezierPath(ovalInRect: CGRectMake((X - (capRadius/2)) - (arcRadius/2), (Y - (capRadius/2)), capRadius, capRadius)).CGPath 
    self.addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero) 

    // Top Oval 
    let pathTop = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath 
    self.addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero) 

} 

drawRectメソッドのデフォルトの実装は何もしません。ビューに円を描画するために、独自の描画コードを実装するためにメソッドをオーバーライドします。 addCircleメソッドは、arcRadius、capRadius、およびcolorの3つのパラメータを取ります。 arcRadiusは円の半径であり、capRadiusは丸いキャップの半径です。

addCircle方法が弧を描くUIBezierPathを使用すると、それは次のように動作しますのdrawRectメソッドで

First it draws a half circle at the bottom 
Next it draws a full small circle at the edge of the arc. 
Finally, it draws the other half of the circle 

、我々は異なる半径と色でaddCircleメソッドを3回呼び出します。この図は、円の描画方法を示しています。 enter image description here

ヒント:UIBezierPathの詳細については、Appleの公式ドキュメントを参照してください。IBInspectableの施設

、あなたは今コードにダイビングせずに右Interface Builderで各サークルの色を変更するのは自由です。

もちろん、あなたがさらにIBInspectableプロパティとしてarcRadiusを公開することができます。私はあなたのための練習としてそれを残します。ここでは例のコードをクリック用

enter image description here

enter image description here

https://github.com/appcoda/Rainbow-IBDesignable-Demo

+0

男、これは絶対に狂った、1つの答えの努力の量!そんなに尊敬する@prince。 –

+12

IBDesignableの書き込みは大丈夫ですが、XIBファイルに対するユーザーの要求には対応できませんでした。 – mobilemonkey

+0

@mobilemonkeyが合意しました。私はこの答えが恩恵に値するとは思わない。 – Sid

4

私は同じ問題を抱えていたと私はそれを修正するために管理。

スウィフト3

let bundle = Bundle(for: MyView.self) 
let view = UINib(nibName: "MyView", bundle: bundle).instantiate(withOwner: self) as! MyView 

重要なビットは、あなたのXIBがサブクラス化のUIViewを使用していバンドル

関連する問題