【问题标题】:IOS UICollectionview Dynamically change Cell's HeightIOS UICollectionview动态改变Cell的高度
【发布时间】:2015-09-09 07:05:12
【问题描述】:

我正在开发基于集合视图的项目,其中 Numberofitem 将根据用户对特定索引的点击进行更改和增加。全部在我的项目中完美运行,但我无法根据集合视图中的单元格数量设置单元格大小。此外,collectionview 将无法通过调整大小来滚动查看所有单元格修复。 这里我附上了所有的图片。

1) 故事板视图

2) 四个单元格的结果

3)当细胞数量增加时

目前我使用以下代码通过这种方式设置了我的单元格。但我想设置,如果集合视图中有四个单元格,则每个单元格的大小会根据集合视图和设备大小(iphone 5s、iphone 6、iphone 6plus)增加并适合

这是我的尝试,

-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
    return 5.0;
}
-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
    return 5.0;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
              layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
        ////@property NSInteger count;////
 if (_count == 0)  {
    //  width = ((width - (span*5))/4);
    //        return CGSizeMake(self.view.frame.size.width/4,  self.view.frame.size.height/4);
    return CGSizeMake(self.view.frame.size.width/2.5, self.view.frame.size.height/5);
}
if (_count == 1 || _count == 2)
{
    return CGSizeMake(self.view.frame.size.width/2.5, self.view.frame.size.height/5);
    // return CGSizeMake(100.0, 100.0);
}
if (  _count == 3 || _count == 4 || _count == 5)
{
    // return CGSizeMake(100.0, 100.0);
    return CGSizeMake(self.view.frame.size.width/3.5, self.view.frame.size.height/6.5);
}
if (  _count == 6 || _count == 7 || _count == 8 || _count == 9)
{
    //return CGSizeMake(90.0, 90.0);
    return CGSizeMake(self.view.frame.size.width/4, self.view.frame.size.height/8);
}
if (  _count == 10 || _count == 11 || _count == 12 || _count == 13 || _count == 14)
{
    //  return CGSizeMake(80.0, 80.0);
    return CGSizeMake(self.view.frame.size.width/4, self.view.frame.size.height/8);
}
if (  _count == 15 || _count == 16 || _count == 17 || _count == 18 || _count == 19 || _count ==20)
{
    //return CGSizeMake(70.0, 70.0);
    return CGSizeMake(self.view.frame.size.width/4.75, self.view.frame.size.height/9.5);
}
if (_count ==21 || _count == 22 || _count == 23 || _count == 24 || _count == 25 || _count == 26 || _count == 27) {
    // return CGSizeMake(60.0, 60.0);
    return CGSizeMake(self.view.frame.size.width/6, self.view.frame.size.height/12);
}
if (_count ==28 || _count == 29  ) {
    //  return CGSizeMake(50.0, 50.0);
    return CGSizeMake(self.view.frame.size.width/6.25, self.view.frame.size.height/12.5);
}
else
    return CGSizeMake(0, 0);
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return itemincollectionview.count;
}

注意:- 这个方法我也试过了。

  - (void)viewDidLayoutSubviews
  {
    self.automaticallyAdjustsScrollViewInsets = NO;
    [self.collectionView layoutIfNeeded];
    NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
    NSIndexPath *currentItem = [visibleItems objectAtIndex:0];
    NSIndexPath *nextItem = [NSIndexPath indexPathForItem:_setRandomIndex inSection:currentItem.section];

    [self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
 }

 - (void)viewWillLayoutSubviews
 {
    [super viewWillLayoutSubviews];
    [self.collectionView.collectionViewLayout invalidateLayout];
 }

 -(void)viewWillAppear:(BOOL)animated
 {
     [super viewWillAppear:YES];
     [self.view layoutIfNeeded];
 }

【问题讨论】:

  • 你应该更清楚,因为我可能不是唯一一个对你想要做什么感到困惑的人。
  • 我想这样做igame.com/eye-test
  • 你的问题解决了吗?

标签: objective-c ios7 uicollectionview


【解决方案1】:

据我了解,您想复制 this 测试的布局。

您需要更好地了解UICollectionView 是如何像here 一样工作的

您必须在此委托方法中更改 UICollectionView 中的项目数

- (NSInteger)numberOfItemsInSection:(NSInteger)section;

在这里,您想在测试开始时返回 4,然后是 4*2、4*2*2,依此类推。这将为您提供正确数量的项目。

然后是布局。你应该有多个值,因为你不希望元素之间的空间与开头和结尾相同。随着项目数量的增加,我会减少空间。

你需要小心间距,因为它会导致单元格被强制在下一行

你已经做得很好了,通过分割框架来获得单元格的最大高度和宽度,但是你的

- (CGSize)collectionView:(UICollectionView *)collectionView
              layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath

方法真的很乱。

由于您的UICollectionView 中的项目数量不会无限,因此您可以使用switch statement,并在每个开关中返回计算得出的单元格CGSize

例如,你可以这样使用它:

    switch (numberOfHorizontalItems) {
      case 2:
            return CGSizeMake(self.collectionView.frame.size.width/2.5,self.collectionView.frame.size.width/2.5);
                break;

    case 4:
                return CGSizeMake(self.collectionView.frame.size.width/4.5,self.collectionView.frame.size.width/4.5);
                break;
    case 8:
                CGSizeMake(self.collectionView.frame.size.width/8.5,self.collectionView.frame.size.width/8.5);
                break;
(And so on)

      default:
                break;
        }

您应该注意,此处显示的计算 CGSize 必须包含 items 之间的间距/合并

你也不需要viewWillLayoutSubviewsviewDidLayoutSubviews,你只需要在用户点击单元格时调用[self.collectionView reloadData](或者在用户点击单元格后处理逻辑的方法中)

最后,如果您不希望UICollectionView 可滚动,只需设置属性self.collectionView.scrollEnabled = NO;

【讨论】:

  • 你能解释一下beat吗?我必须在开关柜中返回什么(意味着哪个尺寸)?并且根据设备屏幕尺寸-正方形位置的另一件事在设备更改时会错位。所以我必须为所有设备单独设置条件?谢谢。
  • 感谢您的重播。但是通过更改设备,它会自动排列正方形,或者我需要为每个设备设置条件?
  • 不,它会根据collectionView的frame来排列,所以如果它更宽,单元格会更宽,反之亦然
  • 我试过你说的,但由于 iphone 5s 和 iphone 4s 的屏幕尺寸,它不能正确自动排列。
  • 你是指垂直还是水平?
【解决方案2】:

点击此博客链接,该链接使用example code 以非常简单的方式说明:- http://www.fantageek.com/1468/ios-dynamic-table-view-cells-with-varying-row-height-and-autolayout/

上面的链接用于表格视图,但您可以以同样的方式work on collection view 并达到您想要的结果。

注意:这都是关于内容拥抱与内容压缩阻力优先级的关系。

【讨论】:

    【解决方案3】:

    使用这个GitHub CHTCollectionViewWaterfallLayout是UICollectionViewLayout的子类,它尽量模仿UICollectionViewFlowLayout的用法。

    此布局的灵感来自 Pinterest。它还兼容PSTCollectionView.

    【讨论】:

      【解决方案4】:

      所以我正在快速添加答案,但此解决方案仅在您具有最小宽度值的情况下才有效。

      /**
      Calculates the CollectionView Cell Size when the parent view is loaded. It happens only once per VC Lifecycle.
      - returns: `width` - The cell width calculated from the current screen size. <p/> `height` - The cell height, which is fixed for now.
      */
      private class func getCellSize() -> (size: CGSize) {
      
          var cellWidth: CGFloat, cellHeight: CGFloat
      
          //Notes: CellSpacing you want to have
          let CellSpacing: CGFloat = 5    
      
          // Notes: Minimum Cell Width that renders for all the screens        
          let MinCellWidth:CGFloat = 130      
      
          let screenWidth: CGFloat = UIScreen.mainScreen().bounds.size.width
          let numberOfCellsPerRow: Int = Int((screenWidth + CellSpacing) / (MinCellWidth + CellSpacing))
          let totalSpaceTaken: Int = (Int(MinCellWidth + CellSpacing) * numberOfCellsPerRow)
          let remainingWidth = Int(screenWidth + CellSpacing) - totalSpaceTaken
      
          cellWidth = MinCellWidth + CGFloat((remainingWidth/numberOfCellsPerRow))
      
          //Now calculate the height based on the Width:Height Ratio. 
          // Assuming it is 1:1.5
      
          cellHeight = cellWidth * 1.5
      
          return CGSizeMake(cellWidth, FixedCellHeight)
      }
      

      这可以很容易地转换为 Objective-C。我们在这里所做的只是获取屏幕宽度并检查我们可以容纳多少个单元格并以正确的单元格间距来适应它们。

      注意:你只需要调用一次 getCellSize() 方法,就可以在下面的方法中使用相同的 CGSize。

      //In your viewDidLoad 
      CGSize cellSize = [self getCellSize];
      
      //In this function you pass the property you initialised above
      - (CGSize)collectionView:(UICollectionView *)collectionView
                    layout:(UICollectionViewLayout *)collectionViewLayout
        sizeForItemAtIndexPath:(NSIndexPath *)indexPath 
       {
          return self.cellSize;
       }
      

      注意:仅当您的 collectionView.width = viewController.width 即您的 collectionView 宽度正在拥抱视图控制器,或者 collectionView 大小与问题中所要求的屏幕大小相同时才有效。

      【讨论】:

        【解决方案5】:

        您项目中的一切都很好,您只需添加一个新的委托方法,如下所示:

        - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
            return UIEdgeInsetsMake(15, 20, 20, 20);
        }
        

        根据您拥有的计数改变此方法的插图。插入设置将常见于:

        self.view.frame.size.width/2.5
        

        和不同的:

        self.view.frame.size.width/3.5
        

        因此额外的间距问题将得到解决

        【讨论】:

          猜你喜欢
          • 2016-06-17
          • 1970-01-01
          • 2014-09-30
          • 2021-01-23
          • 1970-01-01
          • 2019-10-12
          • 1970-01-01
          • 2019-03-26
          • 1970-01-01
          相关资源
          最近更新 更多