UITableView制作九宫格视图

本文介绍了如何利用UITableView实现类似九宫格的布局效果。关键步骤包括创建自定义数据模型、设计自定义视图、定制UITableViewCell,以及具体的实现方法。虽然UICollectionView通常是更好的选择,但此教程展示了在特定情况下使用UITableView的技巧。

使用UITableView制作类型于九宫格的视图列表时,注意三个方面,第一使用自定义数据、第二使用自定义视图、第三使用自定义cell。当然最好的方法还是使用UICollectionView来做类似九宫格的处理。

如图所示


具体方法如下

1 创建自定义数据模型

#import <Foundation/Foundation.h>

@interface ShopModel : NSObject

@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *name;

@end

#import "ShopModel.h"

@implementation ShopModel

@end


2 自定义视图

#import <UIKit/UIKit.h>

@interface MyButton : UIButton

@end

#import "MyButton.h"

#define kImageRatio 0.6
#define kMarginRatio 0.1
#define kLabelRatio (1 - kImageRatio - 2 * kMarginRatio)

@implementation MyButton

- (id)init
{
    if (self = [super init])
    {
       // 设置文字颜色,一定要设置否则不会显示标题
        [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        // 设置文字大小
        self.titleLabel.font = [UIFont systemFontOfSize:10.0];
        // 设置文字居中
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
        
       // 设置图片不要拉伸,保持原来的比例
        self.imageView.contentMode = UIViewContentModeScaleAspectFit;
       // 高亮显示的时候不需要调整图片的颜色
        self.adjustsImageWhenHighlighted = NO;
    }
    
    return self;
}

#pragma mark 设置文字的位置

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    return CGRectMake(0, contentRect.size.height * (kImageRatio + kMarginRatio), contentRect.size.width, contentRect.size.height * kLabelRatio);
}

#pragma mark 设置图片的位置

- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    return CGRectMake(0, contentRect.size.height * kMarginRatio, contentRect.size.width, contentRect.size.height * kImageRatio);
}

@end


3 自定义cell

#import <UIKit/UIKit.h>

#define kColumn 3
#define kCellHeight 40.0 

@interface MyCell : UITableViewCell

- (void)setRowShops:(NSArray *)shops;

@end

#import "MyCell.h"
#import "ShopModel.h"
#import "MyButton.h"

#define kTagPrefix 10

@implementation MyCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
    {
        // 按钮宽度
        CGFloat btnWidth = self.contentView.bounds.size.width / kColumn;
        
        for (int i = 0; i < kColumn; i++)
        {
            MyButton *btn = [[MyButton alloc] init];
            btn.tag = kTagPrefix + i;
            [btn addTarget:self action:@selector(itemClick:) forControlEvents:UIControlEventTouchUpInside];
            btn.frame = CGRectMake(btnWidth * i, 0, btnWidth, kCellHeight);
            //btn.backgroundColor = [UIColor redColor];
            [self.contentView addSubview:btn];
        }
        
    }
    return self;
}

- (void)itemClick:(MyButton *)item
{
    NSLog(@"点击了-%@", item.titleLabel.text);
}

- (void)setRowShops:(NSArray *)shops
{
    NSInteger count = shops.count;
    
    for (NSInteger i = 0; i < kColumn; i++)
    {
        MyButton *btn = (MyButton *)[self.contentView viewWithTag:kTagPrefix + i];
        
        // 设置数据
        if (i < count)
        {
            btn.hidden = NO;
            ShopModel *shop = [shops objectAtIndex:i];
            // 设置背景上面的小图片
            [btn setImage:[UIImage imageNamed:shop.icon] forState:UIControlStateNormal];
            
            [btn setTitle:shop.name forState:UIControlStateNormal];
        }
        else
        {
            btn.hidden = YES;
        }
    }
}

@end


4 使用

#import <UIKit/UIKit.h>

@interface MyTableVC : UIViewController

@end

#import "MyTableVC.h"
#import "MyCell.h"
#import "ShopModel.h"

@interface MyTableVC () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *shops;

@end

@implementation MyTableVC

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    self.title = @"列表九宫格-未封装";
    [self setUI];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)loadView
{
    [super loadView];
    self.view.backgroundColor = [UIColor whiteColor];
}

#pragma mark - 创建视图

- (void)setUI
{
    if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
    {
        [self setEdgesForExtendedLayout:UIRectEdgeNone];
    }
    
    self.shops = [NSMutableArray array];
    for (int i = 1; i <= 20; i++)
    {
        ShopModel *shop = [[ShopModel alloc] init];
        shop.name = [NSString stringWithFormat:@"大衣-%i", i];
        shop.icon = [NSString stringWithFormat:@"animation_%i.jpg", i % 2];
        
        [self.shops addObject:shop];
    }
    
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    [self.view addSubview:self.tableView];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}

#pragma mark - UITableViewDataSource, UITableViewDelegate

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return (self.shops.count + kColumn - 1) / kColumn;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *const identifier = @"MyCell";
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil)
    {
        // 创建Cell的时候绑定一个标识
        cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
   // 从哪个位置开始截取
    NSInteger location = indexPath.row * kColumn;
    // 截取的长度
    NSInteger length = kColumn;
    if (location + length >= self.shops.count)
    {
        length = self.shops.count - location;
    }
    
    NSRange range = NSMakeRange(location, length);
    NSArray *rowShops = [self.shops subarrayWithRange:range];
    [cell setRowShops:rowShops];
    
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return kCellHeight;
}

@end




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

番薯大佬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值