jiangleligejiang / JNote

记录相关日常笔记
0 stars 0 forks source link

UICollectionView相关内容 #19

Open jiangleligejiang opened 4 years ago

jiangleligejiang commented 4 years ago
jiangleligejiang commented 4 years ago

自定义实现UICollectionView布局

jiangleligejiang commented 4 years ago

layoutAttributesForElementsInRectlayoutAttributesForItemAtIndexPath之间的关系

在自定义UICollectionViewLayout时,要注意若需要layoutAttributesForItemAtIndexPath中实现对属性改变,则需要复写layoutAttributesForElementsInRect方法,否则layoutAttributesForItemAtIndexPath方法不会被调用。

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
  NSArray *attributesInRect = [super layoutAttributesForElementsInRect:rect];
  for (UICollectionViewLayoutAttributes *cellAttributes in attributesInRect) {
    [self modifyLayoutAttributes:cellAttributes];
  }
  return attributesInRect;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
  [self modifyLayoutAttributes:attributes];
  return attributes;
}

- (void)modifyLayoutAttributes:(UICollectionViewLayoutAttributes *)attributes
{
  // Adjust the standard properties size, center, transform etc.
  // Or subclass UICollectionViewLayoutAttributes and add additional attributes.
  // Note, that a subclass will require you to override copyWithZone and isEqual.
  // And you'll need to tell your layout to use your subclass in +(Class)layoutAttributesClass
}
jiangleligejiang commented 4 years ago

UICollectionViewCell的返回问题

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    CCCustomCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([CCCustomCell class]) forIndexPath:indexPath];
    if (cell) {
        cell.model = ...;
        return cell;
    }
    return [[UICollectionViewCell alloc] init];
}

[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class])];

jiangleligejiang commented 4 years ago

使用KVO避免UICollectionView的频繁刷新

对于一些频繁变化的数据,比如监听说话的声音,根据声音的变化来显示动画,若我们的视图是UICollectionViewCell,那么要更新视图的话,通常会调用reloadData方法。但这么做会导致其他cell也会一起更新,而且更新的频率也比较高。为了避免这个问题,我们可以通过数据的引用传递,然后通过监听model中对应的字段,从而监听到数据的变化。

- (void)addObservers {
    if (_model) {
        [_model addObserver:self forKeyPath:@"customField" options:NSKeyValueObservingOptionNew context:nil];
    }
}

- (void)removeObservers {
    if (_model) {
        [_model removeObserver:self forKeyPath:@"customField" context:nil];
    }
}

//监听`model`的`customField`字段的变化,从而做一些处理
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if (object == _model && [keyPath isEqualToString:@"customField"]) {
        [self dosomething];
    }
}

- (void)setModel:(CustomModel *)model {
      if (model && _model != model) {
          [self removeObservers];
          _model = model;
          [self addObservers];
      }
}
jiangleligejiang commented 4 years ago

设置UICollectionView的大小为zero时,导致陷入[UICollectionViewData layoutAttributesForElementsInRect:]死循环

jiangleligejiang commented 4 years ago

使用zPosition来设置UICollectionViewCell的层级关系

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    .....
    cell.layer.zPosition = indexPath.row;
    return cell;
}
jiangleligejiang commented 4 years ago

UICollectionView原理探究