【问题标题】:calling addSubview in initWithNibName: causes viewDidLoad (and other UI Object inits)to fire before the addSubview Call executes在 initWithNibName 中调用 addSubview:导致 viewDidLoad(和其他 UI 对象初始化)在 addSubview 调用执行之前触发
【发布时间】:2011-10-17 20:39:33
【问题描述】:

我在initWithNibName:bundle: 的中间添加了一个按钮,当我将按钮视图添加到 self.view 时,视图在添加按钮之前开始初始化。因此,viewDidLoad 中的代码会在 initWithNibName:bundle: 完成之前触发。在 viewDidLoad 中依赖的 addSubview 下方有代码,并导致它崩溃/无法工作,因为初始化代码尚未运行。

当我将按钮代码添加到viewDidLoad 方法时,我也有同样的经历。 .xib 中有一个 UITableView,并且该表在 viewDidLoad 的其余部分运行之前被初始化并导致 tableView 获取错误数据。

在初始化和加载视图时向视图添加视图的最佳做法是什么?只是把所有的 addSubViews 放在 Return 之前?

谢谢!

这是我的 initWithNibName:bundle:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{

    self = [super initWithNibName:nibNameOrNil bundle:nil];

    [self setIoUIDebug:(IoUIDebugSelectorNames)];

    if (IoUIDebug & IoUIDebugSelectorNames) {
        NSLog(@"%@ - %@", [self description], NSStringFromSelector(_cmd) );
    }   

    CGRect frame = CGRectMake(20, 521, 500, 37);                                


    saveButton = [UIButton newButtonWithTitle:NSLocalizedStringFromTable(@"Save Animation Label",@"ScreenEditor",@"Save Animation Label")
                                       target:self
                                     selector:@selector(saveButtonPressedAction:)
                                        frame:frame
                                        image:[UIImage imageNamed:@"BlueButtonSmall.png"]
                                 imagePressed:[UIImage imageNamed:@"BlueButtonSmallPressed.png"]
                                darkTextColor:NO];                      

    [self.view addSubview:saveButton];  // <- Right here I'll hit breakpoints in other parts of viewDidLoad and cellForRowAtIndexPath, before the lined below get executed. 
    [saveButton setEnabled: NO];
    [saveButton setUserInteractionEnabled: NO];

    newAnimation = nil;
    selectedSysCDAnimation = nil;
    selectedIoCDTag = nil;
    animationSaved = NO;  
    return self;
}

【问题讨论】:

    标签: objective-c init viewdidload addsubview


    【解决方案1】:

    您应该在viewDidLoad 中添加子视图,这意味着当主视图加载到内存中时会添加视图。我会保留您的 initWithNibName:bundle: 调用以进行自定义初始化,而不是与 UI 交互,因为这是 viewDidLoad 的设计目的。

    关于您的 tableView,您应该调用以在 viewDidLoad 中加载表数据源。加载数据源后,您只需在 tableview 上调用 reloadData 即可将数据加载到 tableview 中。

    例如:

    - (void)viewDidLoad
    {
    
        [super viewDidLoad];
    
        [self.view addSubview:saveButton];
    
        [self loadDataSource];
    
    }
    
    - (void)loadDataSource {
    
      // load datasource here
    
      [self.tableView reloadData];
    
    }
    

    【讨论】:

    • 我最初遇到了类似的问题,但将其缩小到相同的问题。我在 ViewDidLoad 中有按钮的 addSubView,但在 ViewDidLoad 的中间,我的 IB TableView 正在初始化。我的 ViewDidLoad 具有在 TableView 初始化之前未设置的 TableView 的初始化代码。所以我的 tableview cellForRowAtIndexPath 没有返回 Cell 因为 ViewDidLoad 中的初始化代码还没有完成。所以我将 addSubView 放在 ViewDidLoad 的末尾,这会有所帮助,但我想知道为什么 viewDidLoad 会被中断以初始化 TableView。
    【解决方案2】:

    对视图控制器的视图属性的任何访问都会延迟初始化视图。这将触发对 viewDidLoad 的调用,该调用将在对视图属性的访问返回 initWithNibName: 之前执行。您应该在 viewDidLoad 或使用界面生成器中添加子视图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多