应该使用什么方法在选择时动态更改 UICollectionViewCell 的大小? [英] What method should be used to dynamically change the size of UICollectionViewCell on selection?

查看:35
本文介绍了应该使用什么方法在选择时动态更改 UICollectionViewCell 的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做的是加宽选定单元格的宽度,同时缩短其余未选定单元格的宽度,以便一次性显示所有单元格.

What I need to do is to widen the width of a cell selected and at the same time shorten widths of the rest of the cells not selected so that all the cells are shown in one time.

我现在拥有的是:

  func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 30
  }
  func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSize(width: collectionView.bounds.width / 30, height: collectionView.bounds.height)
  }
  func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    var cell: UIDateSliderCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as UIDateSliderCell
    return cell
  }

我在子类 UIView 中有一个 horizo​​ntal UICollectionView 设置,有 30 个单元格,它们平均分配.

I have a horizontal UICollectionView setup in subclassed UIView, with 30 cells and they're divided equally.

为了通过检测手势来选择单元格,我将 UIPanGestureRecognizer 添加到 collectionView.

To select a cell by detecting gestures, I have UIPanGestureRecognizer added to collectionView.

  func pan(sender: UIPanGestureRecognizer) {
    switch sender.state {
    case .Began:
      fallthrough
    case .Changed:
    _collectionView.selectItemAtIndexPath(_collectionView.indexPathForItemAtPoint(CGPointMake(sender.locationInView(_collectionView).x, 0.0)), animated: true, scrollPosition: nil)
    case .Ended:
      break
    default:
      break
    }
  }

此外,我将 UICollectionViewCell 子类化,我实际上可以通过以下代码更改所选单元格的宽度:

Additionally, I have UICollectionViewCell subclassed and I can actually change the width of selected cell by this code:

  override var selected: Bool {
    didSet {

      if selected {        
        UIView.animateWithDuration(1.0,
          delay: 0.0,
          usingSpringWithDamping: 0.5,
          initialSpringVelocity: 1.0,
          options: .CurveEaseIn,
          animations: { () -> Void in
            self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width*2, self.frame.size.height)
          },
          completion: { (finished: Bool) -> Void in
        })
      }
    }
  } 

当然,它只能更改选定的单元格.我需要做的是改变选定的一个单元格的宽度,并根据选定的单元格重新计算其他单元格的宽度.

But of course with this it can only change a cell selected. What I need to do is to change the width of one cell selected and recalculate the widths of other cells according to the selected cell.

再次澄清我的问题,我想做的是:

To clarify my question again, what I'd like to do is this:

  1. 假设 UICollectionView.width 为 300
  2. 它有 30 个单元格,Cell.width 为 300/30 = 10
  3. 必须一次显示所有单元格,UICollectionView 不会滚动.
  4. 当一个单元格被选中时,它的宽度将为 20.
  5. 因此其他单元格的宽度将为 (300-20)/29.

我应该挂钩什么方法或函数?最好是简单的示例代码,非常感谢.

What method or functions should I hook? Preferbly simple sample codes please, thanks a lot in advance.

推荐答案

我觉得子类化 UICollectionViewFlowLayout 会更适合您的问题/可扩展的解决方案.

I feel like subclassing UICollectionViewFlowLayout would be a more suitable/scalable solution for your problem.

下面我在子类化UICollectionViewLayout时分享了一些小代码,这样你就会得到大致的想法.

Below I shared small code when subclassing UICollectionViewLayout So you'll get the general Idea.

将 totalItem 添加到您的子类.以及指示正在选择哪个单元格的索引路径.在您的 collectionview 上选择一个单元格调用 invalidatelayout

add totalItem to your subclass. and a indexpath that indicates which cell is being selected. after selecting a cell call invalidatelayout on your collectionview

在您的情况下,您希望每次都计算单元格的所有属性.

in your case you want to calculate all the cell's attributes every time.

这是粗略的草图,没有经过测试可能有一些计算错误

    - (void)prepareLayout {

        self.totalItems = (int)[self.collectionView numberOfItemsInSection:0];

    }

    - (CGSize)collectionViewContentSize
    {
        return self.collectionView.frame.size;
    }



    -(CGRect) rectForIndex:(int) index {
        //Here you should calculate the sizes of all the cells
        // The ones before the selected one , the selected one, and the ones after the selected
        if (index<selected) {
           //Regular calculating
           frame=CGRectMake(0, height * index, width, height)
        } else if (index>selected) {
          //here the tricky part is the origin you ( assuming one is seleceted) you calculate the accumulated height of index-1 regular cells and 1 selected cell  
           frame=CGRectMake(0, (height* (selected-1) + sizeOfSelectedCell) +height * (index-selected), width, height)
        } else {
           frame=CGRectMake(0, (height* (index-selected)) , width, selectedHeight)
}
        return frame;
    }
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {

        NSMutableArray *attributes = [NSMutableArray array];
        for (int i = 0; i<  self.totalItems; i++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
            [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
        }
    return attributes;
    }




    -(UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
        UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

        attributes.frame = [self rectForIndex:(int)indexPath.row];


        return attributes;
    }

这篇关于应该使用什么方法在选择时动态更改 UICollectionViewCell 的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆