与XIB相比,重用基于代码的UIViews

时间:2011-02-05 10:54:40

标签: iphone uiview uikit interface-builder xib

假设我有一个UIView我想在多个视图控制器中重用,因为它是一个相当通用的UIView对象,具有高可重用性值(如UITextField或{{1}对象)。根据我的理解,如果我在代码中编写UIView而不是使用Interface Builder创建XIB,那么重用这个UIView会容易得多。我已经得出了这个结论,因为如果UIView是用代码编写的,那么我可以简单地在任何视图控制器中初始化该UIView的新实例:

UISegmentedControl

...然后直接访问该UIView的属性和属性,就像库存UIView控件一样,例如MyGreatReusableView *greatReusableView = [[MyGreatReusableView alloc] initWithFrame:CGRectMake(...)]; 的{​​{1}},UITextField等属性。

但是,如果我将UIView创建为XIB,则必须将其(通过文件所有者或XIB中View对象上的IBOutlet)绑定到特定视图控制器,因此只能在该视图中使用控制器。此外,我只能使用连接到该视图控制器的IBOutlet访问XIB上的控件属性。

我在想我完全误解了有关XIB文件的内容,因为这似乎是一个很大的限制!如果有人可以提供关于是否可以在多个视图控制器中重用XIB文件的说明,如果是这样,提供基于代码的解决方案与基于XIB的解决方案的示例,我将非常感激。

提前感谢您的任何帮助!

2 个答案:

答案 0 :(得分:2)

无需设置可重用视图的IBOutlets的替代解决方案是将要使用的子视图分配给特定标记。然后,您可以使用标记获取视图。

例如,当您要创建带有标签和文本字段的视图时。这样做的过程是:

  1. 创建一个空的xib
  2. 使用标签和文本字段设置视图作为子视图。
  3. 为标签和文本字段分配不同的标签(比方说10和11)

  4. 为此xib创建一个头文件,并为标签定义宏 #define kReusableViewNibName @"ReusableViewNibName"
    #define kLabelTag 10
    #define kTextFieldTag 11

  5. 您现在可以在任何想要的视图控制器中加载xib:

  6. 
    // Import header file with previous defines
    
    NSArray *rootViewsFromXib = [[NSBundle mainBundle] loadNibNamed:@"NameOfXib"
                                                              owner:nil
                                                            options:nil];
    
    // There is only one root view in the xib,
    // the view that contains the label and text field
    UIView *loadedView = [rootViewsFromXib objectAtIndex:0];
    
    // You can now use the views from within the xib
    // by using the tags to obtain the views.
    UILabel *label = (UILabel *)[loadedView viewWithTag:kLabelTag];
    UITextField *textField = (UITextField *)[loadedView viewWithTag:kTextFieldTag];
    
    

答案 1 :(得分:1)

确实可以在多个视图控制器中使用相同的视图。你走在正确的轨道上。关键是您不必使用视图所绑定的视图控制器。以下是我对可重复使用的表格单元格(包含滑块等内容)所做的操作

  1. 创建新的XIB文件
  2. 创建一个新视图(在我的情况下,这是一个表格单元格)
  3. 将UIViewController.view设置为视图(同样,表格单元格)
  4. 我用这个代码(目前在生产中使用)将它连接起来:
    
    @implementation TableCellFactory
    +(UITableViewCell*) createCellInstanceFromXIBName:(NSString*)name {
            UIViewController* tmp = [[UIViewController alloc] initWithNibName:name bundle:nil];
            UITableViewCell* cell = (UITableViewCell*)[tmp view];
            DebugAssert([[cell class] isSubclassOfClass:[UITableViewCell class]], @"XIB view cell is not a subclass of UITableViewCell; xib name:%@",name);
            DebugAssert(cell != nil,@"cell is nil -- Xib name:%@",name);
            [cell retain];
            [tmp release];
            return cell;
    }
    @end