带有IB_DESIGNABLE的UIButton会抛出运行时属性警告,并且不会在Interface Builder中呈现 [英] UIButton with IB_DESIGNABLE throws runtime attribute warning and does not render in Interface Builder

查看:128
本文介绍了带有IB_DESIGNABLE的UIButton会抛出运行时属性警告,并且不会在Interface Builder中呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行Xcode 6.1并且我已经将IB_DESIGNABLE与IBInspectable一起用于了很多项目,但突然之间它就不再起作用了。我创建了子类按钮,将图像和标题垂直居中放置,并允许用户通过IB使用IBInspectable设置边框宽度和颜色。

I'm running Xcode 6.1 and I have been using IB_DESIGNABLE with IBInspectable for quite a few projects already but all of the sudden it just doesn't work anymore. I have created subclassed buttons that arrange the image and the title vertically centred above each other and enable the user to set a border width and color through IB with IBInspectable.

以下警告已记录,并且我的代码无法预览drawRect:

The following warning is logged and there is no preview available of my code in 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.

仍然,运行时它呈现的方式就像我打算渲染一样,它也尊重相同的自定义间距I'通过IB添加。

Still, runtime it renders like I intended it to render and it also honours that same custom spacing I've added through IB.

以下是重新排列按钮和标题的menubutton的代码:

Here's the code of the menubutton that rearranges the button and the title:

#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中绘制它的边框,并且它具有相同类型的错误。为了完整起见,这是代码:

You've probably noticed it inherits HamburgerButton. This basic hamburger button does not have an image and it only draws the border around the button. This basic hamburger button has exactly the same problem: it does not draw it's border in drawRect in IB and it has the same type of errors. Here's that code for sake of completeness:

#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(最新版本)中运行。

I don't really understand why it just throws a warning and nothing else. I didn't really change what I did. I've checked the storyboard, it's iOS 7 and up, meant to run in Xcode 6 (latest).

它抱怨无法在UIButton上找到该值这有点奇怪,因为我已将其分类。

It complains about not being able to find that value on UIButton and that's a bit weird because I've subclassed it.

更新:
所以我改变了一切有效。现在它又重新出现了,没有改变任何其他东西。我认为Xcode 6.1中存在一个错误...:/

Update: So I changed everything around and it worked. Now it craps out again, without changing anything else. I think there's a bug in Xcode 6.1... :/

推荐答案

我一直在与Live Views进行广泛的合作,因为它是介绍和就像Xcode最初的许多新功能一样,它有一些缺陷。我仍然喜欢它,我希望它会在新版本中得到改进。

I have been working extensively with Live Views since it's introductions and like a lot of new features in Xcode initially, it has some flaws. Still I like it a lot and I hope that it will be improved in newer versions.

实时视图与@property属性一起使用,这些属性获得一个特殊的IB_Designable标记,该标记将为UI类提供额外的属性,它可以通过属性检查器设置的用户定义的运行时属性来处理。您将看到Identity Inspector中也存在所有这些属性。问题的根本原因是它无法将这些用户定义的运行时属性映射到公开的属性。

Live Views work with @property properties that get a special IB_Designable tag that will give the UI class extra attributes it can approach via User Defined Runtime Attributes that will be set through the Attributes Inspector. You will see that all those properties also exist in the Identity Inspector. The root cause of the problem is that it cannot map those User Defined Runtime Attributes anymore to exposed properties.

只要打开使用IB_Designable的Storyboard或xib,如果您打开了自动刷新视图,Xcode将在每次更改时重新编译屏幕。由于您的代码也会影响您的UI,因此不必在Interface Builder本身进行更改。

As soon as you open up a Storyboard or xib that uses IB_Designable, Xcode will recompile the screen at every change if you have "Automatically Refresh Views" turned on. Since your code influences your UI as well this doesn't have to be a change in Interface Builder per se.

在更快的机器上使用更简单的项目,这在大多数情况下都能很好地工作的时间。对于具有更多IB_Designable的较大项目,CPU根本没有足够的容量来跟上你,并且在渲染UI时会出现一种超时错误。这是警告的原因:IB Designables:忽略UIButton实例上的键路径spacingBetweenLabelAndImage的用户定义的运行时属性。尝试设置其值时遇到异常:[setValue:forUndefinedKey:]:对于密钥spacingBetweenLabelAndImage,此类不符合键值编码。错误。

With simpler projects on faster machines this works pretty well the majority of the time. With larger projects that also have more IB_Designable the CPU simply doesn't have enough capacity to keep up with you and you will get a sort of time-out error while rendering the UI. This is the cause of the "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." error.

它也不会再使用您的自定义代码更新您的UI。但是当你运行它时这不是问题,因为在运行时它会反映这些变化。

It will also not update your UI anymore with your custom code. This is not a problem when you run it though, because at run time it will reflect those changes.

另一个原因可能是你的代码在编译时根本不编译尝试在后台编译。当你处理代码时,这是不可避免的,所以也经常触发它。

Another cause can be that your code simply doesn't compile when it tries to compile in the background. This is inevitable when you are working on code so that triggers it frequently as well.

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

We need to make sure that your custom view class compiles again so the properties can be set successfully via Interface Builder


  • 在故事板中,转到顶部栏菜单中的编辑器

  • 取消选择自动刷新视图(如果它仍然打开)

  • 关闭所有故事板标签

  • 重建项目

  • 修复所有构建错误(如果有)

  • 重新打开故事板。

  • 再次转到编辑器并单击刷新所有视图

  • While in a storyboard, go to "Editor" in the top bar menu
  • deselect "Automatically refresh views" if it was still turned on
  • Close all your storyboard tabs
  • Rebuild the project
  • Fix all build errors if any
  • Re-open your storyboard.
  • Go to "Editor" again and click "Refresh All Views"

警告应该消失,如果是在您再次看到自定义视图代码之前已经完成了工作。

The warnings should be gone and if it worked before you will see your custom view code again as well.

在sunkas发表评论之后:清理您的解决方案如果出现任何奇怪的问题,请彻底解决。

After a comment below by sunkas: it's always a very good idea to clean your solution thoroughly in case of any weird problems that persist.

这篇关于带有IB_DESIGNABLE的UIButton会抛出运行时属性警告,并且不会在Interface Builder中呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆