与Android不同,iOS自身并不提供Grid控件,所以只能自己通过算法和UITableView来实现九宫格的效果。如果是布局已经定好了,有多少个格子,那样实现起来确实简单很多。这里主要是说一下,根据从后台获取到的数据,做一个动态的Grid布局。
算法思路很重要。不同于写死的九宫格,动态加载就需要一点点小算法去计算。
1.UITableView的行数计算。既然是动态的,那么行数肯定是不一定会相同的。从后台获取的数据,存储在一个array中,暂且叫做dataSource。按照每行放置3个,那么行数应该是[dataSourcecount]/3。可是如果不能被整除,那么就要用到计算余数的函数fmod(x,y)。通过判断是否有余数来确定最终的行数是多少。如果无余数,行数就是[dataSourcecount]/3;如果有余数,行数就应该是[dataSource count]/3+1。代码如下:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//每行3个,取余数
int n = (int)fmod ((float)[self.dataSouceArray count], 3.0);
int munberOfRows = 0;
//判断,如果有余数,munberOfRows应该是总数去掉余数除以每行个数再加1所得的值
if (n > 0) {
munberOfRows = ([self.dataSouceArray count]-(int)fmod ((float)[self.dataSouceArray count], 3.0))/3+1;
}
//判断,如果无余数,munberOfRows应该是总数除以每行个数所得的值
if (n == 0) {
munberOfRows = ([self.dataSouceArray count]-(int)fmod ((float)[self.dataSouceArray count], 3.0))/3;
}
return munberOfRows;
}
2.加载
UITableViewCell
。同样要考虑到获取到的数据数量是否能被3整除的因素。如果可以整除,那么就按照每行三个视图的排列,循环加载就可以了。如果不能整除,那么就要将余数先提出来,先按照每行三个视图的排列循环加载,再将余数在下一行进行加载,也就是看成加载两部分。代码如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.showsReorderControl = YES;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//计算总数是否能被3整除,是否有余数
int n = (int)fmod ((float)[self.dataSouceArray count], 3.0);
//如果有余数,要分两次排列。先要正常排列,余数又分别进行排列。
if (n > 0) {
if (indexPath.row == ([self.dataSouceArray count]-n)/3) {
for (int i = 0; i < n; i ++) {
UIButton *gridBtn = [UIButton buttonWithType:UIButtonTypeSystem];
gridBtn.frame = CGRectMake(10.0/640.0*self.frame.size.width*(i+1) + 200.0/640.0*self.frame.size.width*i , 20.0/1136.0*self.frame.size.height, 200.0/640.0*self.frame.size.width, 200.0/1136.0*self.frame.size.height);
gridBtn.tag = i+indexPath.row*3;
[gridBtn setBackgroundColor:[UIColor greenColor]];
[gridBtn addTarget:self action:@selector(gridBtnTap:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:gridBtn];
}
}else{
for (int i = 0; i < 3; i ++) {
UIButton *gridBtn = [UIButton buttonWithType:UIButtonTypeSystem];
gridBtn.frame = CGRectMake(10.0/640.0*self.frame.size.width*(i+1) + 200.0/640.0*self.frame.size.width*i , 20.0/1136.0*self.frame.size.height, 200.0/640.0*self.frame.size.width, 200.0/1136.0*self.frame.size.height);
gridBtn.tag = i+indexPath.row*3;
[gridBtn setBackgroundColor:[UIColor greenColor]];
[gridBtn addTarget:self action:@selector(gridBtnTap:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:gridBtn];
}
}
}else{
//如果无余数,正常排列
for (int i = 0; i < 3; i ++) {
UIButton *gridBtn = [UIButton buttonWithType:UIButtonTypeSystem];
gridBtn.frame = CGRectMake(10.0/640.0*self.frame.size.width*(i+1) + 200.0/640.0*self.frame.size.width*i , 20.0/1136.0*self.frame.size.height, 200.0/640.0*self.frame.size.width, 200.0/1136.0*self.frame.size.height);
gridBtn.tag = i+indexPath.row*3;
[gridBtn setBackgroundColor:[UIColor greenColor]];
[gridBtn addTarget:self action:@selector(gridBtnTap:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:gridBtn];
}
}
}
return cell;
}
注意了这两个部分,这个问题就基本搞定了。效果也就差不多达到了。(我这里给我的
dataSource
中放置了5个数据)
下面给个传送门,给需要源码的童鞋下载。
如有需要,请点击iOS九宫格Demo下载我写的Demo。希望能帮助到有需要的人。