让UICollectionViewCell恰好适合可用空间

问题描述 投票:2回答:3

我的细胞是正方形和在任何规模的好看。我期待找到细胞的最大尺寸,以便显示他们都不会需要滚动。

并且举例,这个屏幕截图是伟大的3名球员,但踢它多达12名球员,使他们的边界,这是要避免的滚动出来。

有没有办法做到这一点?

ios cocoa-touch uikit uicollectionview
3个回答
2
投票

上面取出所有的技巧基于rdelmar的代码。蛮力计算确保在一些边缘情况对方回答在未能正确答案。

使用效率二进制搜索。

// Make the cells fit
override func viewDidLayoutSubviews() {
    var highestWorking = 0
    var lowestNotWorking = 9999
    while lowestNotWorking > highestWorking + 1 {
        let currentTest = (highestWorking + lowestNotWorking) / 2
        let cols = Int(playerPhotoCollectionView.frame.size.width + 10) / (currentTest + 10)
        let rows = Int(playerPhotoCollectionView.frame.size.height + 10) / (currentTest + 10)
        if cols * rows >= game.numberOfPlayers {
            highestWorking = currentTest
        } else {
            lowestNotWorking = currentTest
        }
    }
    let size = CGSize(width: CGFloat(highestWorking), height: CGFloat(highestWorking))
    (self.playerPhotoCollectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize = size
    super.viewDidLayoutSubviews()
}

1
投票

解决这个问题主要是代数与扔有点逻辑。首先,你需要获得集合视图的纵横比,所以你知道你是否应该有更多的行或多个列。一旦你知道,你可以计算出itemsPerRow和numberOfRows。既然你想你的细胞是正方形,您需要使用您计算有多少项目将适合的行或列的两种尺寸的变小。当你计算的大小,你需要采取在考虑到在每个方向的最小间距。这里是一个小的测试项目,显示我是如何做的。

#define PLAYERS 4.0
#import "ViewController.h"

@interface ViewController ()
@property (weak,nonatomic) IBOutlet UICollectionView *collectionView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [(UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout setMinimumInteritemSpacing:10];
    [(UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout setMinimumLineSpacing:10];
}

-(void)viewDidLayoutSubviews {
    CGFloat aspectRatio =  (self.collectionView.bounds.size.height/self.collectionView.bounds.size.width);
    int itemsPerRow = (aspectRatio > 1)? floorf(pow(PLAYERS,.5)) : ceilf(pow(PLAYERS,.5));
    if (aspectRatio >1) {
        itemsPerRow = itemsPerRow - (floorf(aspectRatio) - 1);
    }else{
        itemsPerRow = itemsPerRow - (floorf(1/aspectRatio) - 1);
    }
        int numberOfRows = ceilf(PLAYERS/itemsPerRow);
        CGFloat width = (self.collectionView.bounds.size.width - ((itemsPerRow - 1) *10)) / itemsPerRow;
        CGFloat height = (self.collectionView.bounds.size.height - ((numberOfRows - 1) *10)) / numberOfRows;
        CGFloat dim = MIN(width, height);
        [(UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout setItemSize:CGSizeMake(dim,dim)];
        [self.collectionView reloadData];
}


-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return PLAYERS;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"Cell";
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    return cell;
}

0
投票

这里是斯威夫特一个新的解决方案。它采用了性能更好的二进制搜索。

假设:

  • 您的收藏图只有一个部分
  • 您的屏幕小于9999个像素
  • 你的细胞是正方形(以其它方式使用currentTest作为最长的大小和编辑rowscols,这曾经是较小的外观尺寸)

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    var highestWorking = 0
    var lowestNotWorking = 9999
    while lowestNotWorking > highestWorking + 1 {
        let currentTest = (highestWorking + lowestNotWorking) / 2
        let cols = Int(playerPhotoCollectionView.frame.size.width + 10) / (currentTest + 10)
        let rows = Int(playerPhotoCollectionView.frame.size.height + 10) / (currentTest + 10)
        if cols * rows >= self.playerCount {
            highestWorking = currentTest
        } else {
            lowestNotWorking = currentTest
        }
    }
    let size = CGSizeMake(CGFloat(highestWorking), CGFloat(highestWorking))
    (self.playerPhotoCollectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize = size
}
© www.soinside.com 2019 - 2024. All rights reserved.