根据需求九宫格的效果可以有很多种。九宫格效果应用比较广泛,实现也多种多样,比如选项抽屉效果。
这里写了一个在UITableView上显示九宫格效果的Demo。
思路:在Cell上初始化自定义按钮,根据预设的每行按钮个数来决定他们在Cell上的位置。然后响应点击事件即可。整体实现不是很难,细节上注意一下即可。
搭建界面
数据,图片来自于天猫客户端的一些资源图片,然后还是以属性字典的方式读取提前设定的数据。
程序读取数据
- (void)loadData
{
static NSString * const TitleKey = @"title";
static NSString * const ImageNameKey = @"imagename";
static NSString * const FlagKey = @"flag";
NSString *path = [[NSBundle mainBundle] pathForResource:@"Products" ofType:@"plist"];
NSArray *array = [NSArray arrayWithContentsOfFile:path];
if (!array)
{
MyLog(@"文件加载失败");
}
_productList = [NSMutableArray arrayWithCapacity:array.count];
[array enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) {
Product *product = [[Product alloc] init];
product.title = dict[TitleKey];
product.imageName = dict[ImageNameKey];
product.flag = [dict[FlagKey] integerValue];
[_productList addObject:product];
}];
}
Product是一个模型类,有三个属性,其中Flag是为了区分每个商品分类设定的。
于是要进行一些准备工作,为了达到按钮是这种效果,我们需要自定义一个按钮。
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.titleLabel.font = [UIFont systemFontOfSize:15.0f];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
}
return self;
}
- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
CGFloat imageX = 0;
CGFloat imageY = 0;
CGFloat imageW = contentRect.size.width;
CGFloat imageH = contentRect.size.height * RImageHeightPercent;
return CGRectMake(imageX, imageY, imageW, imageH);
}
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
CGFloat x = 0;
CGFloat y = contentRect.size.height * RImageHeightPercent;
CGFloat width = contentRect.size.width;
CGFloat height = contentRect.size.height * (1 - RImageHeightPercent);
return CGRectMake(x, y, width, height);
}
其中宏为#define RImageHeightPercent 0.7 也就是上面百分之70显示图片,下面30显示标题
然后在自定义cell上初始化按钮
NSInteger width = RCellWidth/RColCount;
for (NSInteger i = 0; i < RColCount; i++)
{
ProductButton *btn = [[ProductButton alloc] init];
btn.frame = CGRectMake(i*width + RMarginX, RMarginY, width - 2*RMarginX, RCellHeight - 2*RMarginY);
btn.tag = RStartTag + i;
[self.contentView addSubview:btn];
}
设置tag是为了一会在绑定数据的时候能够定位到每一个button
- (void)bindProducts:(NSArray *)productList
{
for (NSInteger i = 0; i < RColCount; i++)
{
ProductButton *btn = (ProductButton *)[self.contentView viewWithTag:RStartTag + i];
Product *product = productList[i];
btn.tag = product.flag;
[btn setImage:[UIImage imageNamed:product.imageName] forState:UIControlStateNormal];
[btn setTitle:product.title forState:UIControlStateNormal];
[btn addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
}
在Cell设置的时候传过来一个参数productList来让cell获取到要绑定的若干个Product数据模型。
并且监听事件,将具体哪个按钮被点击的事件通过设置代理的方式传递给视图控制器。
协议
@class ProductCell;
@protocol ProductCellDelegate <NSObject>
@optional
- (void)productCell:(ProductCell *)cell actionWithFlag:(NSInteger)flag;
@end
监听方法
- (void)buttonTapped:(ProductButton *)sender
{
//MyLog(@"%d", sender.tag);
[_cellDelegate productCell:self actionWithFlag:sender.tag];
}
视图控制器实现则根据不同情况进行不同操作即可
再看下配置单元格的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ProductCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSInteger index = indexPath.row;
NSMutableArray *list = [NSMutableArray arrayWithCapacity:RColCount];
for (NSInteger i = 0; i < RColCount; i++)
{
[list addObject:_productList[index*RColCount + i]];
}
cell.cellDelegate = self;
[cell bindProducts:list];
return cell;
}
到这里,主要的实现方法已经完成。具体的代码可以下载Demo:
最后来看下效果图
以上就是本篇博客全部内容,欢迎指正和交流。转载注明出处~