我运行的是Xcode 6.1,我已经在很多项目中使用了IB_DESIGNABLE和IBInspectable,但突然之间,它不再起作用了.我创建了子类按钮,将图像和标题垂直居中排列在彼此上方,使用户可以通过IB和IBInspectable设置边框宽度和 colored颜色 .

以下警告已被记录,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

你可能已经注意到它继承了汉堡包.这个基本的汉堡按钮没有图像,它只在按钮周围绘制边框.这个基本的汉堡包按钮有完全相同的问题:它在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

我真的不明白为什么它只是发出警告,而不是别的.我并没有真正改变我所做的.我已经判断了故事板,它是iOS 7及更高版本,打算在Xcode 6(最新版本)中运行.

它抱怨无法在UIButton上找到该值,这有点奇怪,因为我已经对它进行了子类化.


更新:

推荐答案

自从推出Live Views以来,我一直在广泛使用它,就像Xcode中的许多新功能一样,它最初也有一些缺陷.尽管如此,我还是非常喜欢它,我希望它能在新版本中得到改进.

Cause:

实时视图与@property properties一起工作,后者会获得一个特殊的IB_可设计标记,该标记将为UI类提供额外的属性,它可以通过用户定义的运行时属性来访问这些属性,这些属性将通过attributes Inspector设置.您将看到,所有这些属性也存在于Identity Inspector中.问题的根本原因是它无法再将这些用户定义的运行时属性映射到公开的属性.

一旦打开使用IB_可设计的故事板或xib,如果打开"自动刷新视图",Xcode将在每次更改时重新编译屏幕.因为你的代码也会影响你的用户界面,所以界面生成器本身不需要改变.

对于速度更快的机器上更简单的项目,这在大多数情况下都很有效.对于具有更多IB_可设计性的大型项目,CPU根本没有足够的容量来跟上您,并且在呈现UI时会出现某种超时错误.这就是"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: [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key spacingBetweenLabelAndImage."错误的原因.

它也不会再使用自定义代码更新用户界面.但在运行时这不是问题,因为在运行时它会反映这些更改.

另一个原因可能是,当代码试图在后台编译时,它根本无法编译.当您在编写代码时,这是不可避免的,因此也会频繁触发代码.

Solution:

我们需要确保自定义视图类再次编译,以便通过Interface Builder成功设置属性

  • 在故事板中,转到顶部栏菜单中的"编辑器"
  • 如果"自动刷新视图"仍处于打开状态,则取消 Select 该选项
  • 关闭所有情节提要选项卡
  • 重建项目
  • 修复所有生成错误(如果有)
  • 重新打开你的故事板.
  • 再次转到"编辑器"并单击"刷新所有视图"

警告应该消失,如果它在你再次看到你的自定义视图代码之前起作用.

sunkas在下面的 comments 之后说:如果有任何奇怪的问题持续存在,彻底解决问题总是一个非常好的主意.

Objective-c相关问答推荐

NSString "nil or empty" 判断 - 这完成了吗?

iPhone 可达性判断

如何删除警告按钮的框架在运行时会有所不同.

在objective-c中isa是什么意思?

为什么 UITableViewCell Select 时所有背景都消失了?

在我的 UIImageView 的子类中没有调用 drawRect

Objective-C 属性的默认属性是什么?

如果用户禁用了应用程序的推送,是否可以进行静默远程通知?

判断对象是 NSArray 还是 NSDictionary

Select 时如何更改 UITableViewCell 的 colored颜色 ?

关于如何将项目从 UITableView 拖放到 UITableView 的教程

无法访问 dispatch_async 中的全局变量:变量不可赋值(缺少 _block 类型说明符)

iOS:如何将 UIViewAnimationCurve 转换为 UIViewAnimationOptions?

iOS 5:对 UIAppearance 感到好奇

AdMob 因 [GADObjectPrivate changeState:] 崩溃:无法识别的 Select 器

如何删除应用程序可访问的所有 keys 串项目?

获取当前调度队列?

为什么我们不能在当前队列上使用 dispatch_sync?

如何让 UITextView 检测网站、邮件和电话号码的链接

按字典中键的值对字典的 NSArray 进行排序