我的细胞是正方形和在任何规模的好看。我期待找到细胞的最大尺寸,以便显示他们都不会需要滚动。
并且举例,这个屏幕截图是伟大的3名球员,但踢它多达12名球员,使他们的边界,这是要避免的滚动出来。
有没有办法做到这一点?
上面取出所有的技巧基于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()
}
解决这个问题主要是代数与扔有点逻辑。首先,你需要获得集合视图的纵横比,所以你知道你是否应该有更多的行或多个列。一旦你知道,你可以计算出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;
}
这里是斯威夫特一个新的解决方案。它采用了性能更好的二进制搜索。
假设:
currentTest
作为最长的大小和编辑rows
或cols
,这曾经是较小的外观尺寸)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
}