Iphone 使用interface builder创建可移植视图

Iphone 使用interface builder创建可移植视图,iphone,uiview,interface-builder,Iphone,Uiview,Interface Builder,从Nib文件中获取项目的新方法。 #import "TableViewCells.h" @implementation TableViewCells @synthesize nibArray; - (void) unloadProperties{ [uiNibHolder release]; } - (NSArray *)nibArray{ return [uiNibHolder instantiateWithOwner:nil options:nil]; } - (id)

从Nib文件中获取项目的新方法。

#import "TableViewCells.h"

@implementation TableViewCells

@synthesize nibArray;

- (void) unloadProperties{
    [uiNibHolder release];
}
- (NSArray *)nibArray{
    return [uiNibHolder instantiateWithOwner:nil options:nil];
}
- (id) init{
    if ((self = [super init]))
    {
        // Im using the class name for the Xib file. 
        // This means it will look in TableViewCells.xib
        // You can change the class name, or pass a Nib name to this class 
        uiNibHolder = [[UINib nibWithNibName:[[self class] description] bundle: [NSBundle mainBundle]] retain];
    }
    return self;
}
- (TitleCell *)titleCell{
    return [self loadViewByClass:[TitleCell class]];
}
- (ToggleCell *)toggleCell{
    return [self loadViewByClass:[ToggleCell class]];
}
- (ButtonCell *)buttonCell{
    return [self loadViewByClass:[ButtonCell class]];
}
- (TextCell *)textCell{
    return [self loadViewByClass:[TextCell class]];
}
- (id)loadViewByClass:(Class)viewClass{
    for (id item in self.nibArray) 
    {
        if ([item isKindOfClass:viewClass])
        {
            return item;
        }
    }
    return nil;
}

- (void)dealloc{
    [self performSelector:@selector(unloadProperties)];
    [super dealloc];
}

@end
LSObjectLoader *oLoader = [[LSObjectLoader alloc] init];
MyClass *thisInstance = [oLoader loadViewFromNib:@"TableViewCells"
                                     ofClassType:[MyClass class]];
下面答案中的示例。

#import "TableViewCells.h"

@implementation TableViewCells

@synthesize nibArray;

- (void) unloadProperties{
    [uiNibHolder release];
}
- (NSArray *)nibArray{
    return [uiNibHolder instantiateWithOwner:nil options:nil];
}
- (id) init{
    if ((self = [super init]))
    {
        // Im using the class name for the Xib file. 
        // This means it will look in TableViewCells.xib
        // You can change the class name, or pass a Nib name to this class 
        uiNibHolder = [[UINib nibWithNibName:[[self class] description] bundle: [NSBundle mainBundle]] retain];
    }
    return self;
}
- (TitleCell *)titleCell{
    return [self loadViewByClass:[TitleCell class]];
}
- (ToggleCell *)toggleCell{
    return [self loadViewByClass:[ToggleCell class]];
}
- (ButtonCell *)buttonCell{
    return [self loadViewByClass:[ButtonCell class]];
}
- (TextCell *)textCell{
    return [self loadViewByClass:[TextCell class]];
}
- (id)loadViewByClass:(Class)viewClass{
    for (id item in self.nibArray) 
    {
        if ([item isKindOfClass:viewClass])
        {
            return item;
        }
    }
    return nil;
}

- (void)dealloc{
    [self performSelector:@selector(unloadProperties)];
    [super dealloc];
}

@end
LSObjectLoader *oLoader = [[LSObjectLoader alloc] init];
MyClass *thisInstance = [oLoader loadViewFromNib:@"TableViewCells"
                                     ofClassType:[MyClass class]];
这个新答案是这个项目和问题的最新变化

我想创建一个UIView子类,并为UIView创建一个Interface builder文件。如何将文件所有者连接到自身。我希望能够设计视图并让它创建连接,但我不需要视图控制器

除了将nib加载到数组中,我还可以使用nib文件作为视图本身的连接器吗

我希望我问得对。我会详细说明的

创建UIViewController我可以选择为其创建xib文件。此时,我可以将UIView添加到xib,并进行连接。但是,文件所有者似乎没有关联的UI编辑器,因此我想创建一个UIView,它将成为另一个视图中的子视图。我真的不想用代码创建它,因为手动布局项目是一件痛苦的事情。因此,我想使用相同的构造来创建一个小uiview,并将其放入另一个uiview中

编辑:

当我找到另一种更好的加载nib类的方法时,我再次编辑了这个。我估计有些堆栈溢出用户会希望看到这一点。

#import "TableViewCells.h"

@implementation TableViewCells

@synthesize nibArray;

- (void) unloadProperties{
    [uiNibHolder release];
}
- (NSArray *)nibArray{
    return [uiNibHolder instantiateWithOwner:nil options:nil];
}
- (id) init{
    if ((self = [super init]))
    {
        // Im using the class name for the Xib file. 
        // This means it will look in TableViewCells.xib
        // You can change the class name, or pass a Nib name to this class 
        uiNibHolder = [[UINib nibWithNibName:[[self class] description] bundle: [NSBundle mainBundle]] retain];
    }
    return self;
}
- (TitleCell *)titleCell{
    return [self loadViewByClass:[TitleCell class]];
}
- (ToggleCell *)toggleCell{
    return [self loadViewByClass:[ToggleCell class]];
}
- (ButtonCell *)buttonCell{
    return [self loadViewByClass:[ButtonCell class]];
}
- (TextCell *)textCell{
    return [self loadViewByClass:[TextCell class]];
}
- (id)loadViewByClass:(Class)viewClass{
    for (id item in self.nibArray) 
    {
        if ([item isKindOfClass:viewClass])
        {
            return item;
        }
    }
    return nil;
}

- (void)dealloc{
    [self performSelector:@selector(unloadProperties)];
    [super dealloc];
}

@end
LSObjectLoader *oLoader = [[LSObjectLoader alloc] init];
MyClass *thisInstance = [oLoader loadViewFromNib:@"TableViewCells"
                                     ofClassType:[MyClass class]];
我想找到一种优雅的方式从nib加载UIView。利用stack overflow用户PeyloW提供的一些信息,我成功地做到了这一点

我将发布我的结果,因为这些信息将导致一个解决方案,但这个解决方案让我感觉异常优雅

  • 首先,我创建了一个名为“TableViewCells.Xib”的Xib文件
    (名称与类名匹配,因此[[self Class]description]=“TableViewCells”)
  • 接下来,我创建了用于Nib中视图的类。 类并不重要,只需确保在interface builder中为类对象选择了“自定义类”
  • 最后,我创建了类“TableViewCells”以匹配xib文件名
我的新头文件。
(导入的每个头文件都与单个xib文件中的项目相关联。)

能够按类加载是非常好的。如果类不在xib文件中,它将返回nil

根据您正在加载的视图的类型,这可以调整为使用多个nib文件。使用lazy-load属性技术,您可以仅在需要时加载这些nib,从而使内存占用很小,并且仍然允许您通过一个方便的类加载器加载类

作为演示,我使用TableView加载了大量视图

@synthesize tableViewCellLoader = _tableViewCellLoader;
- (TableViewCells *)tableViewCellLoader{
    if (_tableViewCellLoader == nil){
        _tableViewCellLoader = [[TableViewCells alloc] init];
    }
    return _tableViewCellLoader;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    switch (indexPath.row) {
        case 0:
            return self.tableViewCellLoader.toggleCell;
            break;
        case 1: 
            return self.tableViewCellLoader.textCell;
            break;
        case 2:
            return self.tableViewCellLoader.titleCell;
            break;
        case 3:
            return self.tableViewCellLoader.buttonCell;
            break;
    }
    return nil;
}
如您所见,我延迟加载了TableViewCellLoader,如果我愿意,我可以使TableViewCells类仅在调用其类时延迟加载UINib对象

我喜欢代码的便利性

尽管如此,
再次感谢PeyloW。

您可以这样做,但没有理由不能在UIView中创建IBoutlet并直接连接到它们。因此,在xib文件中,您将有一个根UIView,请确保将该类更改为自定义类。然后,您可以直接在视图上设置出口,您不需要使用文件所有者。

您可以这样做,但没有理由不能在UIView中创建IBoutlet并直接连接到它们。因此,在xib文件中,您将有一个根UIView,请确保将该类更改为自定义类。然后,您可以直接在视图上设置插座,无需使用文件所有者。

文件所有者只是一个代理对象,不需要在运行时指定,但在设计时在Interface Builder中始终可见

如果不需要,您可以忽略将任何内容连接到文件所有者。运行时加载NIB文件时,使用如下方式:

NSArray* rootObject = [[NSBundle mainBundle] loadNibNamed:@"MyNib" 
                                                    owner:nil 
                                                  options:nil];
owner
参数传递的内容是加载nib时作为文件所有者代理传递的内容,
nil
工作正常

rootObject
数组包含所有根级别的对象,但没有代理。请注意,数组是自动释放的,因此如果需要加载的对象留在周围,则必须保留数组,或者只保留感兴趣的特定元素

并不是说使用
loadNibNamed:owner:options:
是IO绑定的。如果需要性能,则应使用
UINib
的实例将NIB文件缓存在内存中,并从中实例化对象

UINib* myNib = [[UINib nibWithNibName:@"MyNib" 
                               bundle:[NSBundle mainBundle]] retain];
// And then instantiate using:
NSArray* rootObject = [myNib instantiateWithOwner:nil
                                          options:nil];
文件所有者只是一个代理对象,不需要在运行时指定它,但在设计时在Interface Builder中始终可见

如果不需要,您可以忽略将任何内容连接到文件所有者。运行时加载NIB文件时,使用如下方式:

NSArray* rootObject = [[NSBundle mainBundle] loadNibNamed:@"MyNib" 
                                                    owner:nil 
                                                  options:nil];
owner
参数传递的内容是加载nib时作为文件所有者代理传递的内容,
nil
工作正常

rootObject
数组包含所有根级别的对象,但没有代理。请注意,数组是自动释放的,因此如果需要加载的对象留在周围,则必须保留数组,或者只保留感兴趣的特定元素

并不是说使用
loadNibNamed:owner:options:
是IO绑定的。如果需要性能,则应使用
UINib
的实例将NIB文件缓存在内存中,并从中实例化对象

UINib* myNib = [[UINib nibWithNibName:@"MyNib" 
                               bundle:[NSBundle mainBundle]] retain];
// And then instantiate using:
NSArray* rootObject = [myNib instantiateWithOwner:nil
                                          options:nil];

我的最新答案

经过长时间的研究,我尝试了很多场景,得出的结论是,最好的场景是为每个请求创建UINib,并获取有问题的对象。一次通过的结果最好。如果你有一个你计划经常制作的对象,最好把它放在它自己的nib中,而不是放在一个有多个不同类的nib中,因为每次初始化UINib时都会创建每个类

这是你的电话号码
#import "MyChatCells.h"

@implementation MyChatCells

+ (LSObjectLoader*) nibLoader{
    static LSObjectLoader *_objectLoader;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _objectLoader = [[LSObjectLoader alloc] init];
    });
    return _objectLoader;
}

+ (MeChat*)newMeChat{
    return [[self nibLoader] loadViewFromNib:NSStringFromClass([self class])
                                 ofClassType:[MeChat class]];
}

+ (ThemChat*)newThemChat{
    return [[self nibLoader] loadViewFromNib:NSStringFromClass([self class])
                                 ofClassType:[ThemChat class]];
}

@end