IB_DESIGNABLE,IBspectable —— Interface Builder 不会更新

我有以下一组代码:

CustomView.h

#import <UIKit/UIKit.h>


IB_DESIGNABLE
@interface CustomView : UIView


@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;


@end

CustomView.m

#import "CustomView.h"


@implementation CustomView


- (void)setBorderColor:(UIColor *)borderColor {
_borderColor = borderColor;
self.layer.borderColor = borderColor.CGColor;
}


- (void)setBorderWidth:(CGFloat)borderWidth {
_borderWidth = borderWidth;
self.layer.borderWidth = borderWidth;
}


- (void)setCornerRadius:(CGFloat)cornerRadius {
_cornerRadius = cornerRadius;
self.layer.cornerRadius = cornerRadius;
}


@end

(对于 Swift 来说,这个问题也出现在 Swift 代码中)

CustomView.swift

@IBDesignable
class CustomView : UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}


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


@IBInspectable var borderColor : UIColor = UIColor.clearColor() {
didSet {
self.layer.borderColor = borderColor.CGColor
}
}


@IBInspectable var borderWidth : CGFloat = 0.0 {
didSet {
self.layer.borderWidth = borderWidth
}
}


@IBInspectable var cornerRadius : CGFloat = 0.0 {
didSet {
self.layer.cornerRadius = cornerRadius
}
}
}

我在情节串连板上向视图控制器添加了一个 UIView,并将其子类设置为 CustomView

enter image description here

这将添加“ Designables”行。它停留在“更新”和工具提示说“等待目标构建”。从来没有改变过。

当我转到属性检查时,我能够设置这些 IBInspectable属性:

enter image description here

一旦设置好,它们还会出现在“用户定义的运行时属性”中:

enter image description here

然而,“ Designables”状态从来没有超出“更新”的范围,仍然使用相同的工具提示(我已经尝试了几次 Cmd + B 构建,没有任何改变)。

此外,在设置 IBInspectable属性时,每个属性都会得到一个警告:

IBDesignables -忽略“ UIView”实例上的键路径“ borderColor”的用户定义的运行时属性... 这个类与键 borderColor 的键值编码不兼容。

生成的警告截图:

enter image description here


我熟悉符合键值编码的问题,并且通常知道如何解决它们... ... 但是我不知道如何在这里解决这个问题。根据视图的标识检查器,视图是“ CustomView”(不是普通的“ UIView”,它没有这些属性)。如果视图不是“ CustomView”,那么这些可设计的属性就不会显示在属性检查器中,对吗?但是,当 Interface Builder 试图将这些属性应用到视图时,它又回到了认为视图的类是“ UIView”并且不能应用这些属性的想法。

有人帮忙吗?请让我知道,如果我遗漏了一些重要的细节,但为了它的价值,我完全遵循了这个教程(除了目标对斯威夫特)。同样值得注意的是,我在另一台机器上完全遵循了这个教程,而且效果非常好(我昨晚打算写这篇文章,但是我当时使用的电脑没有这个问题)。


根据注释,有人认为可能没有包含 .m文件,这可能是导致问题的原因。我想我肯定会走出我的方式,为这种情况下,但我检查了无论如何。

enter image description here

当我第一次开始尝试这样做时,我的理解是 IB_DESIGNABLE类必须是不同的 UIKit框架的一部分。因此,从第一个屏幕快照中,您可以看到我设置了一个“ CustomView”框架,它有一个类 CustomView。这里您还会看到我还创建了一个 OtherView,它与 CustomView相同,只是它不在一个单独的框架中。然而,相同的问题仍然存在于两个类之间的故事板上。

这里我们有一个屏幕截图,表明 CustomView.m是包含在 CustomViews框架中构建的:

enter image description here

同时,下面的截图显示了一些事情:

  • CustomViews.framework适当地包含在主项目中。
  • OtherView.m也包含在编译源代码中,所以即使 CustomView出了问题,OtherView也应该可以工作,但是它会产生相同的错误。
  • Main.storyboardLaunchScreen.xib显示为红色。我不知道为什么,也不知道为什么 LaunchScreen.xib应该(我还没有碰过这个文件) ,虽然我可以说在看过其他项目之后,Main.storyboard在这些项目中也显示为红色,我没有用 IB_DESIGNABLEIBInspectable做任何事情。

enter image description here


我已经试了好几次了。它每次都能在我家里的电脑上工作——我不能在家里重现这个问题中描述的问题。工作的时候,从来不管用。这个问题中描述的问题每次都会发生。

这两台电脑都是 Mac Mini 今年新买的(不是新型号,是2012年底的型号)。两台电脑都运行 OS X Yosemite 10.10。两台计算机都运行 Xcode Version 6.1。在国内,建设是(6A1052d)。今天早上我可以确认两台电脑运行的是 Xcode 的相同版本。

其他人向我建议,它可能是坏的 RAM。这对我来说似乎有点牵强。我已经重新启动项目多次,重新启动计算机多次。在我看来,如果一台使用了大约6个月的计算机存储器存在问题,那么我就会看到其他问题,而且这个问题不会那么一致。但是,尽管无数次从头开始重新启动整个项目并在计算机上完全重新启动,这个问题仍然存在。


值得注意的是,如果我实际编译并运行这个项目,那么带有 IBInspectable属性的自定义视图实际上显示为我期望的情节串连板显示的样子。我想即使没有 IB_DESIGNABLEIBInspectable指令,情况也是如此,因为它们是作为用户定义的运行时属性创建的。

46914 次浏览

Based on chrisco's suggestion to debug the selected view (which I had already done, but went to try again for good measure), I noticed a couple of other options at the bottom of the Editor menu.

  • Automatically Refresh Views
  • Refresh All Views

I clicked "Refresh All Views" and after Xcode had a bit of a think, suddenly the storyboard was displaying my view as expected (properly applying my IBInspectable properties).

enter image description here

I then went through the whole process again to confirm that this is the solution.

I created a new class, ThirdView. This class is identical to the others, again. I changed my view's class to ThirdView and got something slightly different this time:

enter image description here

Clicking "Show" to me to the warnings:

enter image description here

A new one this time:

Using class UIView for object with custom class because the class ThirdView does not exist.

This isn't really any more helpful than what already existed. Plus, now the other three warnings have doubled into 6 strangely.

Anyway, if I click "Refresh All Views" from the Editor drop down menu again, all the errors go away, and once again, the view properly displays.

Still, up to this point, everything I did was stuff I never messed with at home. At home, it just worked. So I turned on "Automatically Refresh Views" and created a "FourthView" to test--once again, identical to the first three.

After changing the view's class to "FourthView" the designables label said "Updating" for a short moment then finally said "Up to date":

enter image description here

So, I checked my computer at home. "Automatically Refresh Views" is turned on at the computer that was always working. It was turned off at the computer that wasn't. I don't ever remember touching this menu option. I can't even tell you for sure whether it existed before Xcode 6. But this option is what was making the difference.


TL;DR, if you're having the same problem described in the question, make sure "Automatically Refresh Views" is turned on (or manually "Refresh All Views" when you need an update in IB):

enter image description here

I have a few more details that may cause your IBDesignable classes to not be loaded.

Select your problematic storyboard/xib where your custom views ought to display.

In the navigator area, head to the Report Navigator in your XCode workspace/project.

In the Editor menu of XCode, hit (as mentioned by nhgrif), the "Refresh All Views" option. This will cause IB to launch a compile for a whole bunch of stuff that you, I'm certain, would not expect.

In the Report Navigator, Click on "By Group" to filter content and look at the "Interface Builder" section. You will see that for the sake of loading the custom IBDesignable views framework, it will compile LOTS of things. If any of these targets do NOT compile, such as (perhaps deprecated) unit test targets (even if they are totally unrelated to the code that loads these views or storyboard), then IB will fail at loading your dll.

In my case, IB tried to compile 8 targets, including 4 that where unit tests that had not been updated since recent refactoring changes we've been working on.

Most of the code changes/fixes I have done in order for IB to properly load and display my customs views where not related or even linked against these classes, nor would it ever load the storyboard in the course of running these unit tests. Yet, IB had a dependency on the whole workspace compiling for it to work.

Incase any one else comes up against the error IB Designables class does not exist, for the same reason as I did. Top answer was not my issue... but here is a slightly related problem...

There is a property hidden in the story board source code called customModule.

For example I had a class called ForwardArrow inside a separate framework that I accidentally added to my main target.

So the XML for some views ended up as customClass="ForwardArrow" customModule="MainTargetNameWasHere"

When I removed them from the main target in the build the story board did not update MainTargetNameWasHere to CustomViews which is the framework where it was located and started giving that no class found error.

So TLDR; Make sure that if your IBDesignable is in another framework that the customModule xml attribute in your story board is set to the right value. And if it isn't there at all add it.

Example from my source:

<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MUG-jc-2Ml" customClass="ForwardArrow" customModule="CustomViews">

I personally solved this problem by using the "-" button to delete content from my identity inspector. When you remove custom classes, change content in the IB and then add a new custom class, the designable elements in the identity inspector don't get removed and it caused me to have that error. Just Delete everything and rebuild. enter image description here

I had the same warning Ignoring user defined runtime attribute for key path .. even though I am absolutely sure I didn't do anything wrong with my custom IBDesignable view class.

Turned out, in my case, it got to do with Xcode cache.

rm -rf ~/Library/Developer/Xcode/DerivedData/*

Purge DerivedData and the warning is gone.

I just went through the ringer on this problem. I tried all the things listed here and elsewhere without any luck. This is a storyboard that worked fine forever and it suddenly stopped working with the "Ignoring user-defined runtime attribute..." problem.

For whatever reason, removing this code from one of my IBDesignable's fixed it:

-(void)viewDidLoad {
self.clipsToBounds = YES;
}

removing this caused all the warnings to go away, even in other IBDesignable objects. I have no idea why this one step fixed it, but maybe it will help someone else too.

I know this is answered, but here is one more experience.

I was having some problems unrelated to this issue, but in the process I removed @IBInspectable from the vars in my class and deleted the attributes from the identity inspector (alt-apple-3).

After fixing the (code) issue with the component, I refreshed everything a ton of times, but still no attributes in the identity inspector.

Eventually, I noticed that they were back, but only in the attributes inspector (alt-apple-4). As soon as I added values to them there, they re-appeared in the identity inspector

Dave Thomas's answer above gave me the (reverse) solution when not of the others (Derived Data, Editor > Refresh) did, but for the sake of clarity in case people aren't sure where to edit the XML... you don't need to!

  1. In your storyboard file select the troublesome view
  2. On the right-hand sidebar select the Identity Inspector tab (3rd option from the left).
  3. You'll have your custom class, which should already be set, and the Module. For me this was empty, and I was getting the same errors as OP. I set the Module to my project name and BAM - it started working after rebuilding!

I was having the same problem and I had to change the cornerRadius and BorderWidth to be a String and then cast it to CGFloat, it was the only solution for me to be able to change the values and see the changes in interface builder.

@IBInspectable var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor!.CGColor
}
}


@IBInspectable var borderWidth: String? {
didSet {
layer.borderWidth = CGFloat(Int(borderWidth!) ?? 0)
}
}


@IBInspectable var cornerRadius: String? {
didSet {
layer.cornerRadius = CGFloat(Int(cornerRadius!) ?? 0)
layer.masksToBounds = layer.cornerRadius > 0
}
}

Just a quick hint for anyone else having this problem: remember to specify the type of the variable.

// Doesn't show up in IB
@IBInspectable var includeLeftSection = true


// Shows now that it knows the type
@IBInspectable var includeLeftSection : Bool = true

As my example, I was using CheckboxButton via pod and the graphics of checkbox never shows up in the storyboard while I got the same issues described in the question here:

warning: IB Designables: Using class UIView for object with custom class because the class CheckboxButton does not exist

and

warning: IB Designables: Ignoring user defined runtime attribute for key path "checkColor" on instance of "UIView". Hit an exception when attempting to set its value: [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key checkColor.

The way solved my problem was to supply the module with name CheckboxButton as below:

Note: you should replace CheckboxButton to whatever the name of module you are using.