将子视图添加到 UICollectionViewCell 时出现意外行为
Posted
技术标签:
【中文标题】将子视图添加到 UICollectionViewCell 时出现意外行为【英文标题】:Unexpected behaviour when adding subviews to UICollectionViewCell 【发布时间】:2012-10-09 05:49:26 【问题描述】:我目前在向 UICollectionViewCell 添加子视图时遇到了一个奇怪的问题,但仅限于某些情况下。
这是场景:
我有一个“容器”视图,它符合带有嵌套视图的非常特定的协议 (ADGControl),通常是 UIKit 控件子类,即 MyCustomTextField:用于自定义控件的 UITextField。
“容器”视图公开了一个名为“innerControlView”的属性,该属性持有对自定义控件的强引用,我正试图将其作为子视图添加到单元格的内容视图中。
代码如下:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
FormControlCollectionViewCell *cell = [self.formCollectionView dequeueReusableCellWithReuseIdentifier:@"formControlCell" forIndexPath:indexPath];
NSArray *sectionContents = [_controlList objectAtIndex:[indexPath section]];
// This works
//UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 315.0f, 30.0f)];
//textField.borderStyle = UITextBorderStyleLine;
//[cell.controlView addSubview:textField];
// This doesn't (see the behaviour in video clip)
id <ADGControl> control = [sectionContents objectAtIndex:[indexPath row]]; // The container view I'm referring to
[cell.contentView addSubview:(UIView *)[control innerControlView]]; // [control innerControlView] is the typical UIKit control subclass for custom controls. In this example it will be a UITextField
return cell;
正如您在上面的代码 cmets 中看到的,每当我尝试直接添加 UIKit 控件 (textField) 时,它都可以正常工作。但是,一旦我尝试添加我的自定义控件([control innerControlView],我就会在此处的视频剪辑中看到意外的行为:http://media.shinywhitebox.com/ryno-burger/ios-simulator-ios-simulator-ipad-ios-a
上面的链接只是一个 23 秒的短视频片段,以更好地展示我得到的“意外行为”。
如果有人能指出我做错了什么问题,我将不胜感激。
谢谢
【问题讨论】:
您可能想将该代码(添加子视图)移动到子类中。因为如果你这样做,它会在每次调用方法时添加它。 好吧,很酷,但我不确定在 UICollectionViewCell 的子类中添加它的位置,因为我从 dequeueReusableCellWithReuseIdentifier 获取实例:。我试过 - (id)init 但它没有被调用。使用 dequeueReusableCellWithReuseIdentifier 时,我很难理解 UICollectionViewCell 的生命周期,所以我不确定在哪里添加我的初始化代码。 对不起,我的意思是 - (id)initWithFrame。但它永远不会在调试器中达到我的断点。 【参考方案1】:正如您在the documentation on UICollectionViewCell
s 中看到的那样,您不应该将内容子视图添加到单元格本身,而是添加到contentView
。
而且,就像我之前在评论中所说的那样,您不应该在数据源中添加子视图,而应该在子类中添加子视图。您已经注意到 initWithFrame:
没有被调用,请改用 initWithCoder:
:
-(id)initWithCoder:(NSCoder *)aDecoder
self = [super initWithCoder:aDecoder];
if (self)
// Add your subviews here
// self.contentView for content
// self.backgroundView for the cell background
// self.selectedBackgroundView for the selected cell background
return self;
【讨论】:
我真的不喜欢在单元格本身中添加子视图,但是如果我的 uiview 被数据源填充怎么办?我的意思是我使用来自数据源的信息创建了一些。我创建了一个自定义单元类并在解码器方法中添加了视图。我还在 cellForIndexPath 方法中填充了我的视图,它没有出现。我的解码器崩溃了,说我的视图为零【参考方案2】:一个视图一次只能在一个超级视图中。如果它已经是容器视图的子视图,则不能将其添加为另一个视图(您的单元格)的子视图。
目前还不清楚为什么要将视图用作模型对象的一部分,但是在将其添加到单元格之前,您要么必须更改它,要么必须从当前父视图中删除内部视图。
【讨论】:
嗨,我尝试只添加已经包含内部控制视图的容器视图,而不是直接添加内部控制视图,但仍然得到相同的行为,但略有不同。现在似乎所有文本字段都被覆盖在一个单元格上。两个视图都有相同的框架,这有关系吗?请查看更新的视频剪辑:media.shinywhitebox.com/ryno-burger/… GuidoH 有你在 cmets,我想。您每次都添加相同的视图,即使对于重复使用的单元格也是如此。以上是关于将子视图添加到 UICollectionViewCell 时出现意外行为的主要内容,如果未能解决你的问题,请参考以下文章