我是界面构建器的新手,我希望有一个屏幕,它包含一个UIView的3x3网格,每个网格都包含一个UIImageView和4个UILabels。
我的逻辑可能有缺陷,但我试图做到这一点的方式是:
是否有可能从InterfaceBuilder中以图形方式将一个nib加载到另一个nib中,如果是这样的话,我该如何做呢?我是否将“标准”UIView拖到画布上,然后将类更改为MyUIView?
还是需要在MyGridViewController.m中以编程方式完成这些操作,比如:
for (int i=0; i<9; i++)
{
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"MyUIView" owner:self options:nil];
[myViewArray addObject:[ nibViews objectAtIndex: 1]];
}我让它工作的唯一方法是拥有一个Nib,并放置9 UIImageViews和36 UILabels,但是当我需要更新3x3“单元”时,这显然是一种痛苦。我认为在一个文件中修改它会更容易,并且所有的9个都会被更新。
发布于 2009-08-19 01:51:19
您不能在Interface中这样做。
我可能要做的是创建一个自定义视图,比如MyGridItem,在它醒来时将MyUIView.nib作为子视图加载,然后在您的MyGridView.nib中使用其中的9个。
小心awakeFromNib,因为如果在加载两个不同的nib时涉及到视图,则可以调用它两次(例如,如果MyGridItem是加载MyGridView.nib时的所有者,那么MyGridItem awakeFromNib将在作为加载MyUIView.nib的一部分加载时调用一次,在加载MyGridView.nib时调用一次。
另外,由于要加载nib 9次,所以您可能需要使用
NSNib* theNib = [[NSNib alloc] initWithNibNamed:@"MyGridItem" bundle:nil];装载以下内容:
if ( [theNib instantiateNibWithOwner:self topLevelObjects:NULL] ) {然后,在加载了所有9个子视图之后,您可能需要释放它。
发布于 2012-06-07 15:34:42
“是的,你(几乎)可以。”
我使用Interface在我的项目中这样做。
唯一的缺陷是,您看到一个白色区域来表示Interface中的“嵌套nib”。假设同时(我主要在等待苹果在XCode中添加此功能),我在这里介绍的解决方案是可以接受的。
首先阅读以下内容:https://blog.compeople.eu/apps/?p=142
然后,如果您做了ARC,按照这些说明,并抓取我的UIVIew+Util类别包括在这里。
对于ARC,您必须允许这种“自我”分配。(https://blog.compeople.eu/apps/?p=142声明它不需要,但它是需要的。如果不这样做,您将得到一些“发送到已分配实例的消息”)
要在ARC项目中实现这一点,请在文件中添加‘-fno-objc-圆弧’标志编译器设置。然后在这个文件中不进行ARC编码(比如dealloc设置nils,调用等等)
此外,客户端nib的视图控制器应该使用强属性来保存awakeFromNib返回的实例。在我的示例代码中,引用customView如下所示:
@property (strong,非原子) IBOutlet CustomView* customView;
最后,我使用定义在我的copyUIPropertiesTo: UIView+Util类别中的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获得初始解决方案的学分。我只是改进了一下。
发布于 2011-10-31 14:38:52
如果使用一个nib中的1个图像视图和4个标签创建视图(我将此视图称为“网格单元格”),则可以为网格创建另一个nib,并拖动网格单元格的9个实例。这9个实例在IB中只显示为占位符(空白视图),但当您运行应用程序时,它们将工作。
这篇文章告诉你如何去做。请查看名为“可重用子视图”的部分。既然你正在用9个相同的单元格构建一个网格,那么使用AQGridView可能是有意义的--参见“可重用的AQGridViewCell”一节。
https://stackoverflow.com/questions/1296903
复制相似问题