“是的,你(几乎)可以。”
我在我的项目中使用 Interface Builder。
唯一的缺陷是您在 Interface Builder 中看到一个表示“嵌套 nib”的白色区域。假设同时(我主要等待Apple在XCode中添加此功能),我在这里提出的解决方案是可以接受的。
首先阅读此内容:https://blog.compeople.eu/apps/?p=142
然后,如果您使用 ARC,请按照这些说明获取此处包含的我的 UIVIew+Util 类别。
对于 ARC,您必须允许这种“自我”分配。 (https://blog.compeople.eu/apps/?p=142 表示不需要,但确实需要。如果不需要,您将收到一些“发送到已释放实例的消息”)
要在 ARC 项目中实现此目的,请在文件中添加“-fno-objc-arc”标志编译器设置。
然后在这个文件中做NO-ARC编码(比如dealloc设置nils,调用super dealloc等)
另外,客户端 nib 的视图控制器应该使用 strong 属性来保存 awakeFromNib 返回的实例。在我的示例代码中,customView 是这样引用的:
@property (strong, nonatomic) IBOutlet CustomView* customView;
我终于使用在我的 UIView+Util 类别中定义的 copyUIPropertiesTo: 和 loadNibNamed 对属性处理和 nib 加载进行了一些其他改进。
所以 awakeAfterUsingCoder: 代码现在是
#import "UIView+Util.h"
...
- (id) awakeAfterUsingCoder:(NSCoder*)aDecoder
{
// are we loading an empty “placeholder” or the real thing?
BOOL theThingThatGotLoadedWasJustAPlaceholder = ([[self subviews] count] == 0);
if (theThingThatGotLoadedWasJustAPlaceholder)
{
CustomView* customView = (id) [CustomView loadInstanceFromNib];
// copy all UI properties from self to new view!
// if not, property that were set using Interface buider are lost!
[self copyUIPropertiesTo:customView];
[self release];
// need retain to avoid deallocation
self = [customView retain];
}
return self;
}
UIView+Util类代码为
@interface UIView (Util)
+(UIView*) loadInstanceFromNib;
-(void) copyUIPropertiesTo:(UIView *)view;
@end
连同它的实现
#import "UIView+Util.h"
#import "Log.h"
@implementation UIView (Util)
+(UIView*) loadInstanceFromNib
{
UIView *result = nil;
NSArray* elements = [[NSBundle mainBundle] loadNibNamed: NSStringFromClass([self class]) owner: nil options: nil];
for (id anObject in elements)
{
if ([anObject isKindOfClass:[self class]])
{
result = anObject;
break;
}
}
return result;
}
-(void) copyUIPropertiesTo:(UIView *)view
{
// reflection did not work to get those lists, so I hardcoded them
// any suggestions are welcome here
NSArray *properties =
[NSArray arrayWithObjects: @"frame",@"bounds", @"center", @"transform", @"contentScaleFactor", @"multipleTouchEnabled", @"exclusiveTouch", @"autoresizesSubviews", @"autoresizingMask", @"clipsToBounds", @"backgroundColor", @"alpha", @"opaque", @"clearsContextBeforeDrawing", @"hidden", @"contentMode", @"contentStretch", nil];
// some getters have 'is' prefix
NSArray *getters =
[NSArray arrayWithObjects: @"frame", @"bounds", @"center", @"transform", @"contentScaleFactor", @"isMultipleTouchEnabled", @"isExclusiveTouch", @"autoresizesSubviews", @"autoresizingMask", @"clipsToBounds", @"backgroundColor", @"alpha", @"isOpaque", @"clearsContextBeforeDrawing", @"isHidden", @"contentMode", @"contentStretch", nil];
for (int i=0; i<[properties count]; i++)
{
NSString * propertyName = [properties objectAtIndex:i];
NSString * getter = [getters objectAtIndex:i];
SEL getPropertySelector = NSSelectorFromString(getter);
NSString *setterSelectorName =
[propertyName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[propertyName substringToIndex:1] capitalizedString]];
setterSelectorName = [NSString stringWithFormat:@"set%@:", setterSelectorName];
SEL setPropertySelector = NSSelectorFromString(setterSelectorName);
if ([self respondsToSelector:getPropertySelector] && [view respondsToSelector:setPropertySelector])
{
NSObject * propertyValue = [self valueForKey:propertyName];
[view setValue:propertyValue forKey:propertyName];
}
}
}
Tadaaaa :-)
积分转到https://stackoverflow.com/users/45018/yang 以获得初始解决方案。我刚刚改进了它。