182在屏幕中实现网格化视图效果

实现同样效果,更简单的方式如之前写的这篇随笔:使用 UICollectionView 实现网格化视图效果

 

实现思路:

(1)自定义继承 UITableView<UITableViewDataSource, UITableViewDelegate>的 KMGridView,定义并实现类似 UITableView 的数据源和委托协议;计算每行的单元格个数宽度,实现等比间距

(2)使用 StoryBoard 故事版布局界面,新增一个 UICollectionView,为其 CollectionViewCell 填充 UIImageView 和UILabel,IBOutlet 和 IBAction 绑定操作,并设置 CollectionViewFlowLayout 的相关内容和间距值;

自定义继承 UICollectionViewCell 的 KMCollectionViewCell;ViewController 继承并实现 UICollectionViewDataSource 和 UICollectionViewDelegate 的相关方法

 

效果如下:

iPhone 5s

iPhone 6

iPhone 6 Plus

ViewController.h

1 #import <UIKit/UIKit.h>
2 #import "KMGridViewDelegate.h"
3 #import "KMGridView.h"
4 
5 @interface ViewController : UIViewController<KMGridViewDelegate>
6 @property (strong, nonatomic) KMGridView *gridView;
7 
8 @end

ViewController.m

 1 #import "ViewController.h"
 2 
 3 @interface ViewController ()
 4 - (void)layoutUI;
 5 @end
 6 
 7 @implementation ViewController
 8 #define kNumberOfCells 25
 9 #define kNumberOfColumns 3
10 #define kWidthOfImage 80.0
11 #define kHeightOfImage 80.0
12 #define kWidthOfDesc 80.0
13 #define kHeightOfDesc 30.0
14 #define kPaddingOfScreen 20.0
15 
16 - (void)viewDidLoad {
17     [super viewDidLoad];
18     
19     [self layoutUI];
20 }
21 
22 - (void)didReceiveMemoryWarning {
23     [super didReceiveMemoryWarning];
24     // Dispose of any resources that can be recreated.
25 }
26 
27 - (void)layoutUI {
28     self.view.backgroundColor = [UIColor whiteColor];
29     self.navigationItem.title = @"在屏幕中实现网格化视图效果";
30     
31     _gridView = [[KMGridView alloc] initWithFrame:CGRectMake(kPaddingOfScreen, kPaddingOfScreen, self.view.frame.size.width, self.view.frame.size.height)];
32     _gridView.gridViewDelegate = self;
33     [self.view addSubview:_gridView];
34 }
35 
36 #pragma mark - KMGridViewDelegate
37 - (CGFloat)gridView:(KMGridView *)gridView widthForColumnAt:(NSUInteger)columnIndex {
38     return kWidthOfImage;
39 }
40 
41 - (CGFloat)gridView:(KMGridView *)gridView heightForRowAt:(NSUInteger)rowIndex {
42     return kHeightOfImage + kHeightOfDesc;
43 }
44 
45 - (CGFloat)gridView:(KMGridView *)gridView widthOfSpaceForRowAt:(NSUInteger)rowIndex {
46     CGFloat widthOfAllSpace = (self.view.frame.size.width - kPaddingOfScreen * 2) - kNumberOfColumns * kWidthOfImage;
47     return widthOfAllSpace / (kNumberOfColumns -1);
48 }
49 
50 - (NSUInteger)numberOfCellsOfGridView:(KMGridView *)gridView {
51     return kNumberOfCells;
52 }
53 
54 - (NSUInteger)numberOfColumnsOfGridView:(KMGridView *)gridView {
55     return kNumberOfColumns;
56 }
57 
58 - (KMGridViewCell *)gridView:(KMGridView *)gridView cellForRowAt:(NSUInteger)rowIndex andColumnIndexAt:(NSUInteger)columnIndex {
59     KMGridViewCell *cell = [gridView dequeueReusableCell];
60     if (!cell) {
61         cell = [[KMGridViewCell alloc] initWithSizeOfImage:CGSizeMake(kWidthOfImage, kHeightOfImage)
62                                             withSizeOfDesc:CGSizeMake(kWidthOfDesc, kHeightOfDesc)
63                                               withRowIndex:rowIndex
64                                            withColumnIndex:columnIndex];
65     }
66     
67     cell.imgVCustom.image = [UIImage imageNamed:[NSString stringWithFormat:@"Image%luForGridView", (columnIndex + 1)]];
68     cell.lblDesc.text = [NSString stringWithFormat:@"位置:(%lu, %lu)", (unsigned long)rowIndex, (unsigned long)columnIndex];
69     return cell;
70 }
71 
72 - (void)gridView:(KMGridView *)gridView didSelectRowAt:(NSUInteger)rowIndex andColumnIndexAt:(NSUInteger)columnIndex {
73     NSString *strMsg = [NSString stringWithFormat:@"选中的内容位置:(%lu, %lu)", (unsigned long)rowIndex, (unsigned long)columnIndex];
74     UIAlertView *alertV = [[UIAlertView alloc] initWithTitle:@"提示信息"
75                                                      message:strMsg
76                                                     delegate:nil
77                                            cancelButtonTitle:nil
78                                            otherButtonTitles:@"确定", nil];
79     [alertV show];
80 }
81 
82 @end

KMGridView.h

 1 #import <UIKit/UIKit.h>
 2 #import "KMGridViewDelegate.h"
 3 #import "KMGridViewCell.h"
 4 
 5 @interface KMGridView : UITableView<UITableViewDataSource, UITableViewDelegate> {
 6     KMGridViewCell *tempCell;
 7 }
 8 @property (weak, nonatomic) id<KMGridViewDelegate> gridViewDelegate;
 9 
10 - (KMGridViewCell *)dequeueReusableCell;
11 
12 @end

KMGridView.m

  1 #import "KMGridView.h"
  2 #import "KMGridViewRow.h"
  3 
  4 @implementation KMGridView
  5 #define kNumberOfCells [_gridViewDelegate numberOfCellsOfGridView:self]
  6 #define kNumberOfColumns [_gridViewDelegate numberOfColumnsOfGridView:self]
  7 #define kHeightOfRow [_gridViewDelegate gridView:self heightForRowAt:indexPath.row]+20.0
  8 
  9 - (id)initWithFrame:(CGRect)frame {
 10     if (self = [super initWithFrame:frame]) {
 11         self.dataSource = self;
 12         self.delegate = self;
 13         
 14         self.separatorStyle = UITableViewCellSeparatorStyleNone;
 15     }
 16     return self;
 17 }
 18 
 19 - (KMGridViewCell *)dequeueReusableCell {
 20     KMGridViewCell *cell = tempCell;
 21     tempCell = nil;
 22     return cell;
 23 }
 24 
 25 - (void)cellPressed:(KMGridViewCell *)sender {
 26     [_gridViewDelegate gridView:self
 27                  didSelectRowAt:sender.rowIndex
 28                andColumnIndexAt:sender.columnIndex];
 29 }
 30 
 31 #pragma mark - TableView
 32 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
 33     return 0;
 34 }
 35 
 36 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 37     return kHeightOfRow;
 38 }
 39 
 40 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
 41     return 1;
 42 }
 43 
 44 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 45     NSUInteger residueRow = kNumberOfCells % kNumberOfColumns > 0 ? 1 : 0;
 46     return kNumberOfCells / kNumberOfColumns + residueRow;
 47 }
 48 
 49 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 50     static NSString *rowIdentifier = @"rowIdentifier";
 51     KMGridViewRow *row = [tableView dequeueReusableCellWithIdentifier:rowIdentifier];
 52     if (!row) {
 53         row = [[KMGridViewRow alloc] initWithStyle:UITableViewCellStyleDefault
 54                                    reuseIdentifier:rowIdentifier];
 55     }
 56     
 57     CGFloat x = 0;
 58     for (NSUInteger i=0; i<kNumberOfColumns; i++) {
 59         if ((indexPath.row * kNumberOfColumns + i) >= kNumberOfCells) { //判断是否是最后一行里多余的列;是的话就隐藏,不再进行下面语句的操作
 60             if (row.contentView.subviews.count > i) {
 61                 ((KMGridViewCell *)row.contentView.subviews[i]).hidden = YES;
 62             }
 63             continue;
 64         }
 65         
 66         tempCell = row.contentView.subviews.count > i ? row.contentView.subviews[i] : nil; //判断当前行的内容视图包含的子视图个数是否大于当前列索引下标
 67         KMGridViewCell *cell = [_gridViewDelegate gridView:self
 68                                               cellForRowAt:indexPath.row
 69                                           andColumnIndexAt:i]; //这里实际会跟上面一句关联,获取到的是tempCell对象示例
 70         if (cell.superview != row.contentView) { //避免重复添加
 71             [cell removeFromSuperview];
 72             [row.contentView addSubview:cell];
 73             
 74             [cell addTarget:self
 75                      action:@selector(cellPressed:)
 76            forControlEvents:UIControlEventTouchUpInside];
 77         }
 78         
 79         cell.hidden = NO;
 80         cell.rowIndex = indexPath.row;
 81         cell.columnIndex = i;
 82         
 83         CGFloat widthOfColumn = [_gridViewDelegate gridView:self widthForColumnAt:i];
 84         CGFloat widthOfSpace = [_gridViewDelegate gridView:self widthOfSpaceForRowAt:indexPath.row];
 85         cell.frame = CGRectMake(x, 0, widthOfColumn, kHeightOfRow);
 86         x += (widthOfColumn + widthOfSpace);
 87     }
 88     
 89     row.frame = CGRectMake(row.frame.origin.x,
 90                            row.frame.origin.y,
 91                            x,
 92                            kHeightOfRow);
 93     return row;
 94 }
 95 
 96 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 97     
 98 }
 99 
100 @end

KMGridViewDelegate.h

 1 #import <Foundation/Foundation.h>
 2 @class KMGridView;
 3 @class KMGridViewCell;
 4 
 5 @protocol KMGridViewDelegate
 6 @optional
 7 - (void)gridView:(KMGridView *)gridView didSelectRowAt:(NSUInteger)rowIndex andColumnIndexAt:(NSUInteger)columnIndex;
 8 
 9 @required
10 - (CGFloat)gridView:(KMGridView *)gridView widthForColumnAt:(NSUInteger)columnIndex;
11 - (CGFloat)gridView:(KMGridView *)gridView heightForRowAt:(NSUInteger)rowIndex;
12 - (CGFloat)gridView:(KMGridView *)gridView widthOfSpaceForRowAt:(NSUInteger)rowIndex;
13 - (NSUInteger)numberOfCellsOfGridView:(KMGridView *)gridView;
14 - (NSUInteger)numberOfColumnsOfGridView:(KMGridView *)gridView;
15 - (KMGridViewCell *)gridView:(KMGridView *)gridView cellForRowAt:(NSUInteger)rowIndex andColumnIndexAt:(NSUInteger)columnIndex;
16 
17 @end

KMGridViewRow.h

1 #import <UIKit/UIKit.h>
2 @interface KMGridViewRow : UITableViewCell
3 @end

KMGridViewRow.m

 1 #import "KMGridViewRow.h"
 2 
 3 @implementation KMGridViewRow
 4 
 5 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
 6     if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
 7         self.selectionStyle = UITableViewCellSelectionStyleNone;
 8         self.userInteractionEnabled = YES;
 9     }
10     return self;
11 }
12 
13 @end

KMGridViewCell.h

 1 #import <UIKit/UIKit.h>
 2 
 3 @interface KMGridViewCell : UIButton
 4 @property (strong, nonatomic) UIImageView *imgVCustom;
 5 @property (strong, nonatomic) UILabel *lblDesc;
 6 @property (assign, nonatomic) NSUInteger rowIndex;
 7 @property (assign, nonatomic) NSUInteger columnIndex;
 8 
 9 - (id)initWithSizeOfImage:(CGSize)sizeOfImage withSizeOfDesc:(CGSize)sizeOfDesc withRowIndex:(NSUInteger)rowIndex withColumnIndex:(NSUInteger)columnIndex;
10 
11 @end

KMGridViewCell.m

 1 #import "KMGridViewCell.h"
 2 
 3 @implementation KMGridViewCell
 4 
 5 - (id)initWithSizeOfImage:(CGSize)sizeOfImage withSizeOfDesc:(CGSize)sizeOfDesc withRowIndex:(NSUInteger)rowIndex withColumnIndex:(NSUInteger)columnIndex; {
 6     if (self = [super init]) {
 7         self.backgroundColor = [UIColor whiteColor];
 8         
 9         _imgVCustom = [[UIImageView alloc] init];
10         _imgVCustom.frame = CGRectMake(0, 0, sizeOfImage.width, sizeOfImage.height);
11         _imgVCustom.layer.masksToBounds = YES;
12         _imgVCustom.layer.cornerRadius = 10.0;
13         [self addSubview:_imgVCustom];
14         
15         _lblDesc = [[UILabel alloc] initWithFrame:CGRectMake(0, sizeOfImage.height, sizeOfDesc.width, sizeOfDesc.height)];
16         _lblDesc.textColor = [UIColor brownColor];
17         _lblDesc.textAlignment = NSTextAlignmentCenter;
18         _lblDesc.adjustsFontSizeToFitWidth = YES;
19         [self addSubview:_lblDesc];
20         
21         _rowIndex = rowIndex;
22         _columnIndex = columnIndex;
23     }
24     return self;
25 }
26 
27 @end

AppDelegate.h

1 #import <UIKit/UIKit.h>
2 
3 @interface AppDelegate : UIResponder <UIApplicationDelegate>
4 @property (strong, nonatomic) UIWindow *window;
5 @property (strong, nonatomic) UINavigationController *navigationController;
6 
7 @end

AppDelegate.m

 1 #import "AppDelegate.h"
 2 #import "ViewController.h"
 3 
 4 @interface AppDelegate ()
 5 @end
 6 
 7 @implementation AppDelegate
 8 
 9 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
10     _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
11     ViewController *viewController = [[ViewController alloc] init];
12     _navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
13     _window.rootViewController = _navigationController;
14     //[_window addSubview:_navigationController.view]; //当_window.rootViewController关联时,这一句可有可无
15     [_window makeKeyAndVisible];
16     return YES;
17 }
18 
19 - (void)applicationWillResignActive:(UIApplication *)application {
20 }
21 
22 - (void)applicationDidEnterBackground:(UIApplication *)application {
23 }
24 
25 - (void)applicationWillEnterForeground:(UIApplication *)application {
26 }
27 
28 - (void)applicationDidBecomeActive:(UIApplication *)application {
29 }
30 
31 - (void)applicationWillTerminate:(UIApplication *)application {
32 }
33 
34 @end

 

posted @ 2015-06-17 18:02  KenmuHuang  阅读(251)  评论(0编辑  收藏  举报
如果您看完本篇博文,觉得对您有所收获,请点击右下角的 [推荐]
如果您想转载,请注明出处(原创内容,请尊重个人劳动成果)
如果您有任何意见或建议,欢迎留言
感谢您的阅读,敬请关注我的后续博客文章