私はXcode 6.1を実行しており、すでにかなりの数のプロジェクトでIB_DESIGNABLEとIBInspectableを使用していますが、突然すべてが機能しなくなりました。サブクラス化されたボタンを作成して、画像とタイトルを上下に中央に配置し、ユーザーがIBInspectableを使用してIBで境界線の幅と色を設定できるようにしました。
次の警告がログに記録され、drawRectでコードのプレビューを利用できません。
warning: IB Designables: Ignoring user defined runtime attribute for key path "spacingBetweenLabelAndImage" on instance of "UIButton". Hit an exception when attempting to set its value: [<UIButton 0x7f9278591260> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key spacingBetweenLabelAndImage.
それでも、ランタイムはレンダリングしたとおりにレンダリングされ、IBを介して追加したのと同じカスタム間隔も尊重します。
ボタンとタイトルを再配置するメニューボタンのコードは次のとおりです。
#import "HamburgerButton.h"
IB_DESIGNABLE
@interface HamburgerImageButton : HamburgerButton
@property IBInspectable CGFloat spacingBetweenLabelAndImage;
@end
実装:
#import "HamburgerImageButton.h"
@implementation HamburgerImageButton
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGSize imageSize = self.imageView.frame.size;
CGSize titleSize = self.titleLabel.frame.size;
// Move the label left and the image right by half the width
CGFloat leftInset = titleSize.width / 2;
CGFloat rightInset = imageSize.width / 2;
CGFloat halfSpacing = self.spacingBetweenLabelAndImage == 0 ? 0 : self.spacingBetweenLabelAndImage / 2;
CGFloat topInset = imageSize.height / 2 + halfSpacing;
CGFloat bottomInset = titleSize.height / 2 + halfSpacing;
UIEdgeInsets imageInsets = UIEdgeInsetsMake(-bottomInset, leftInset, bottomInset, -leftInset);
UIEdgeInsets titleInsets = UIEdgeInsetsMake(topInset, -rightInset, -topInset, rightInset);
self.imageEdgeInsets = imageInsets;
self.titleEdgeInsets = titleInsets;
}
@end
おそらく、HamburgerButtonを継承していることに気づいたでしょう。この基本的なハンバーガーボタンには画像がなく、ボタンの周りの境界線のみを描画します。この基本的なハンバーガーボタンにはまったく同じ問題があります。IBのdrawRectに境界線を描画せず、同じタイプのエラーがあります。完全を期すためのコードを次に示します。
#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface HamburgerButton : UIButton
@property IBInspectable CGFloat borderWidth;
@property IBInspectable UIColor *borderColor;
@end
実装:
#import "HamburgerButton.h"
#import <QuartzCore/QuartzCore.h>
@implementation HamburgerButton
- (void)copyInspectables {
self.layer.borderWidth = self.borderWidth;
self.layer.borderColor = self.borderColor.CGColor;
}
- (void)drawRect:(CGRect)rect {
[self copyInspectables];
}
@end
私はそれが単に警告を投げるだけで何もしない理由を本当に理解していません。私は実際に自分のしたことを変えませんでした。ストーリーボードをチェックしました。iOS7以上で、Xcode 6(最新)で実行することを意図しています。
UIButtonでその値を見つけることができないという不満があり、それをサブクラス化したので少し奇妙です。
更新:だから私は周りのすべてを変更し、それが機能しました。今では、他の何も変更せずに、再びクラップスします。 Xcode 6.1にはバグがあると思います...:/
私はライブビューが導入されて以来、広範囲に取り組んできました。最初はXcodeの多くの新機能と同様に、いくつかの欠陥があります。それでも私はそれがとても好きで、新しいバージョンで改善されることを願っています。
ライブビューは、属性インスペクターを介して設定されるユーザー定義のランタイム属性を介してアプローチできる追加の属性をUIクラスに与える特別なIB_Designableタグを取得する@propertyプロパティで動作します。これらすべてのプロパティがIdentity Inspectorにも存在することがわかります。この問題の根本的な原因は、これらのユーザー定義のランタイム属性を公開されたプロパティにマップできないことです。
IB_Designableを使用するStoryboardまたはxibを開くと、「ビューの自動更新」がオンになっている場合、Xcodeは変更のたびに画面を再コンパイルします。コードはUIにも影響を与えるため、これはInterface Builder自体を変更する必要はありません。
より高速なマシンでのよりシンプルなプロジェクトでは、これはほとんどの場合うまく機能します。より大きなIB_Designableを備えた大規模なプロジェクトでは、CPUに十分な容量がないため、UIのレンダリング中にタイムアウトエラーが発生します。これが "警告の原因です:IB Designables:" UIButton "のインスタンス上のキーパス" spacingBetweenLabelAndImage "のユーザー定義ランタイム属性を無視します。その値を設定しようとすると例外が発生します:[ setValue:forUndefinedKey:]:このクラスは、キースペーシングBetweenLabelAndImage。 "エラーのキー値コーディングに準拠していません。
また、カスタムコードでUIが更新されることもありません。ただし、実行時にはこれらの変更が反映されるため、これを実行しても問題はありません。
別の原因として、コードがバックグラウンドでコンパイルしようとすると、単にコンパイルされないことがあります。これは、コードで作業しているときに避けられないため、頻繁にトリガーされます。
Interface Builderでプロパティを正常に設定できるように、カスタムビュークラスが再度コンパイルされることを確認する必要があります。
警告は消えるはずであり、それが機能する前にカスタムビューコードが再び表示されます。
Sunkasによる以下のコメントの後: clean 永続的な奇妙な問題が発生した場合、ソリューションを徹底的にすることは常に非常に良い考えです。
CGFloat
の「spacingBetweenLabelAndImage
」宣言を「NSNumber
」に変更してみてください。
私の知る限り、 「setValue:
"Cタイプ変数の場合 。
「spacingBetwenLabelAndImage
」の宣言をNSNumberに変更するには、少しのコードも変更する必要があります。
CGFloat halfSpacing = self.spacingBetweenLabelAndImage == 0 ? 0 : self.spacingBetweenLabelAndImage / 2;
次のようなものになるかもしれません:
CGFloat halfSpacing = (self.spacingBetweenLabelAndImage ? ([self.spacingBetweenLabelAndImage floatValue] / 2) : 0.0);
(これが最初の行の完全な翻訳であるかどうかは100%確かではありませんが、NSNumberからfloatValueを取得する方法を示したかったのです)
私は同様の問題を抱えていましたが、実際にクラスからプロパティを削除しましたが、Interface Builderはまだ見つからないプロパティについて不平を言っていました。
クリーニング、再構築など、多くのことを試しました...しかし、何も機能しませんでした!
本当に解決したのは、ストーリーボードファイルを右クリックし、[開く]、[ソースコード]の順に選択することでした。これにより、エディターでストーリーボードXMLコンテンツが開かれ、セクションが見つかるまで欠落しているプロパティへの参照を検索できました。
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute... keyPath="My Missing Property Name">
...
</userDefinedRuntimeAttributes>
セクション全体を削除した後、ファイルを保存し、Interface Builderでビューを更新しました。これですべての警告が消えました!
Departamento Bが提供する方法を使用しましたが、実際には機能しませんでした。ただし、1で問題を修正しました。ストーリーボードからバグのあるビューを選択する2.(エディター-選択したビューをデバッグする)をクリックしてください
すべてのセッターを正しく設定し、プロジェクトに他のSDKをインポートしてこの問題が発生している場合は、[ターゲット-全般]の[リンクされたフレームワークとライブラリ]をチェックしてください。
いくつかのSDKフレームワークを正しくリンクした後、エラーはなくなりました。