UIPickerVIew viewForRow 中的重用视图:丢失其子视图?

Posted

技术标签:

【中文标题】UIPickerVIew viewForRow 中的重用视图:丢失其子视图?【英文标题】:Reused view in UIPickerVIew viewForRow: loses its subviews? 【发布时间】:2013-05-16 14:33:36 【问题描述】:

我正在尝试在 UIPickerView 中重用带有子视图的视图:

- (UIView *)pickerView:(UIPickerView *)pickerView 
            viewForRow:(NSInteger)row
          forComponent:(NSInteger)component 
           reusingView:(UIView *)view

    UILabel* label = nil;
    if (view == nil) 
        view = [[UIView alloc] init];
        label = [[UILabel alloc] init];
        [view addSubview:label];
    
    if (label == nil) 
        label = view.subviews[0]; // Exception here because there are no subviews
    
    ...

如果我的“reusingView”UIView 在入口处设置,我希望它保留(字面上和比喻上!)我添加的子视图,UILabel。但是,在从头开始设置前几个屏幕视图之后,我被一个(回收的,我假设)非零“reusingView”调用,但它没有任何子视图,所以我崩溃了尝试获取其现有标签来更改它时。

我是不是误会了什么?

【问题讨论】:

【参考方案1】:

我无法复制您的问题。我用下面的代码做了一个简单的项目,和你的很相似。我在标签上添加了一个框架,并为背景着色,这样我就可以看到发生了什么。您能看到与您所拥有的任何会导致结果不同的差异吗(可能问题出在您未显示的“...”区域)?

- (void)viewDidLoad 
    [super viewDidLoad];
    self.picker.dataSource = self;
    self.picker.delegate = self;


-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 
    return 1;


-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 
    return 10;


- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view 
    UILabel* label = nil;
    if (view == nil) 
        view = [[UIView alloc] init];
        view.backgroundColor = [UIColor blueColor];
        label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 60, 22)];
        label.text = @"test";
        [view addSubview:label];
    
    if (label == nil) 
        NSLog(@"%@",view.subviews);
        label = view.subviews[0]; // I do get subviews here.
    
    return view;

【讨论】:

谢谢!这给了我信心,我没有误解视图回收,而是做错了其他事情。事实证明,如果您扩展现有方法以添加一个围绕现有视图的新视图,它有助于返回您添加的新视图,而不是现在其中的旧视图。 (工作的结果看起来是正确的,因为我只是在一个空视图中包装了相同的标签,而我正在工作。D'oh!) 始终视图正在创建并进入您在上面添加的第一个 if 条件。 @rdelmar - 使用这种方法时 -> view = [[UIView alloc] init];在 swift 3.0 中,我收到一个错误:“无法分配值:'view' is let constant”。这就是我的做法: --------- if let vv = view return vv view = UIView(frame: .zero) 链接到我的问题:***.com/questions/43388853/…

以上是关于UIPickerVIew viewForRow 中的重用视图:丢失其子视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 UIPickerView.viewForRow 在中心突出显示,重置行灰色?

XCUITest 使用 adjustToPickerWheelValue: && viewForRow: 委托导致断言

UIPickerView 中中心行的静态视图

为啥 UIPickerView 是半透明的

如何更改 UIPickerView 中的字体大小? [复制]

在 Swift 中为选定的 UIPickerView 行设置动画背景颜色