【问题标题】:UICollectionViewCell subclass init never runUICollectionViewCell 子类初始化从不运行
【发布时间】:2013-05-08 01:35:30
【问题描述】:

我已经像这样在 viewDidLoad 中添加了一个集合视图...

self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 10, 10) collectionViewLayout:flowLayout];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
self.collectionView.backgroundColor = [UIColor whiteColor];
[self.collectionView registerClass:[CameraCell class] forCellWithReuseIdentifier:CameraCellReuseIdentifier];
[self.collectionView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:self.collectionView];

我有一个名为 CameraCell 的 UICollectionViewCell 子类,它的 init 是这样的......

- (id)init
{
    self = [super init];
    if (self) {
        // Add customisation here...
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imageChanged:) name:@"image" object:nil];

        self.contentView.backgroundColor = [UIColor yellowColor];

        self.imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        self.imageView.contentMode = UIViewContentModeScaleAspectFill;
        self.imageView.clipsToBounds = YES;
        [self.imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self.contentView addSubview:self.imageView];

        NSDictionary *views = NSDictionaryOfVariableBindings(_imageView);

        [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_imageView]|"
                                                                                 options:0
                                                                                 metrics:nil
                                                                                   views:views]];

        [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_imageView]|"
                                                                                 options:0
                                                                                 metrics:nil
                                                                                   views:views]];
    }
    return self;
}

但是当我运行应用程序时,集合视图就在那里,我可以滚动它,但我看不到任何单元格。我在单元格的 init 中添加了一个断点,它永远不会被调用。还有其他方法我必须重写吗?

编辑

当我在 cellForItemAtIndexPath 中记录单元格时...

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CameraCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CameraCellReuseIdentifier forIndexPath:indexPath];

    NSLog(@"%@", cell);

    return cell;
}

它显示正确的类...

<CameraCell: 0x1f07ba30; baseClass = UICollectionViewCell; frame = (0 20; 320 280); layer = <CALayer: 0x1f07bb40>> 

【问题讨论】:

  • 我的意思是,你调用的是 initWithFrame 而不是 init...

标签: ios uicollectionview uicollectionviewcell


【解决方案1】:

你需要实现的方法是- (instancetype)initWithFrame:(CGRect)rect

【讨论】:

  • 天啊,我不敢相信我做到了。谢谢。
  • 但是框架不是由collectionView 本身管理的吗?从collectionViewCell 渲染这个initWithFrame 没用?
  • 你得到的 frame 参数有点没用,但你仍然需要在这里初始化你自己的属性。
【解决方案2】:

我最近在 iOS7 SDK 中尝试过这个,我不得不覆盖 initWithCoder,因为从未调用过 initWithFrame

【讨论】:

  • 您是从情节提要还是从 nib 加载它?还是全部在代码中?
  • 单元格是从情节提要中加载的。
  • ^那就是为什么。 initWithCoder 是从情节提要构建的视图的指定初始化程序。 initWithFrame 用于以编程方式构建的视图。
  • 常见问题 :) 我通常把所有的构造都放在init 中,然后从覆盖的initWithFrameinitWithCoder 中调用它。它使细胞类别更加普遍。或者,当我需要保存原始 initWithCoder 行为时,我创建另一个方法universalInit,将我所有的自定义代码放在那里并从所有默认初始化程序中调用它。当然,对于 Swift,这个技巧就不再那么方便了。
【解决方案3】:

如果单元格是从 StoryBoard 加载的,那么您将需要像这样覆盖初始化器:

斯威夫特

override init?(coder aDecoder: NSCoder) {
  super.init(coder:aDecoder)
  //You Code here
} 

Objective-C

- (id)initWithCoder:(NSCoder *)aDecoder {
  self = [super initWithCoder:aDecoder];
  //You code here
}

如果您从 nib 加载,那么您将需要像这样覆盖初始化器:

斯威夫特

override init(frame: CGRect) {
  super.init(frame:frame)
  //You Code here
} 

Objective-C

- (id)initWithFrame:(CGRect)frame {
  self = [super initWithFrame:frame];
  //You code here
}

【讨论】:

    【解决方案4】:

    我知道这个问题已经很老了,但我个人很懒,想从某个地方复制粘贴代码。不幸的是,上面没有 100% 正确的解决方案,所以我编写了通用模式(基于 IB 和基于代码的单元格)

        override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            commonInit()
        }
        
        override func awakeFromNib() {
            commonInit()
        }
        
        private func commonInit() {
            
        }
    

    【讨论】:

      【解决方案5】:

      就我而言,当我使用[[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 10, 10) collectionViewLayout:flowLayout] 以编程方式实例化一个collectionView 时,initWithFrame 永远不会被调用,但initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout 会。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-18
        • 2021-03-23
        • 1970-01-01
        相关资源
        最近更新 更多