最終效果圖:
ViewController.m文件
#import "ViewController.h"
#import "HMAppView.h"
#import "HMAppModel.h"
@interface ViewController ()
/// 保存所有數據
@property (nonatomic, strong) NSArray *appData;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1.加載數據
[self loadAppData];
// 格子的寬和高
CGFloat appW = 100;
CGFloat appH = 120;
// 格子之間間距
CGFloat margin = 10;
// 列數
NSInteger columnCount = 3;
// 最左邊邊距 = (屏幕的寬 - (三個格子的寬) - (列數 - 1) * 間距) * 0.5;
CGFloat leftMargin = (self.view.bounds.size.width - (appW * columnCount) -(columnCount - 1) * margin) * 0.5;
// 頂部邊距
CGFloat topMargin = leftMargin;
for (NSInteger i = 0; i < self.appData.count; i++) {
// 創建appView
HMAppView *appView = [HMAppView appView];
// 計算列號
NSInteger col = i % columnCount;
// 計算格子的X = leftMargin + (格子的寬 + 格子之間間距) * col"列號"
CGFloat appX = leftMargin + (appW + margin) * col;
// 計算行號
NSInteger row = i / columnCount;
// 計算格子的Y = topMargin + (格子的高 + 間距) * 行號
CGFloat appY = topMargin + (appH + margin) * row;
// 設置格子的frame
appView.frame = CGRectMake(appX, appY, appW, appH);
// 把appView添加到父控件上
[self.view addSubview:appView];
// 給appView傳模型數據
appView.appModel = self.appData[i];
}
}
}
#pragma mark - 加載數據
- (void)loadAppData {
// 加載plist文件
NSArray *dictArr = [NSArray arrayWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"apps.plist" withExtension:nil]];
// 創建可變數組用來保存所有模型對象
NSMutableArray *arrM = [NSMutableArray array];
// 遍歷數組中的字典,把字典換成模型對象
for (NSDictionary *dict in dictArr) {
// 字典轉模型
HMAppModel *appModel = [HMAppModel appModelWithDict:dict];
// 把處理好的模型添加到數組
[arrM addObject:appModel];
}
// 把裝有模型的數組賦值給控制器的屬性
_appData = arrM;
}
@end
/** 用xib自定義視圖的步驟:
1.創建一個xib文件用來描述局部視圖 “freeform”
2.向xib中拖入相應的子控件,並且設置好frame
3.創建一個類,用來管理xib文件”管理xib文件的類名,最好和xib文件名稱一樣”,管理xib的類,要繼承至什麼取決於,xib文件中最上層”頂層”視圖的類型
4.指定xib文件中最上層”頂層”視圖的class,不指定class無法連線
5.把需要設置數據及監聽點擊的控件連線到管理xib類的.m中去
6.在管理xib類的.h中定義一個屬性,用來接收控制器傳遞的模型數據,”strong”,在.m中重寫此屬性的set方法,在此方法給控件設置數據
7.在管理xib類的.h中聲明一個類方法,把加載xib的細節封裝在管理xib類裏面
*/
HMAppView.h文件
#import <UIKit/UIKit.h>
@class HMAppModel;
@interface HMAppView : UIView
// 用來接收控制器傳遞過來的數據
//@property (nonatomic, strong) NSDictionary *dict;
// 模型屬性
@property (nonatomic, strong) HMAppModel *appModel;
// 聲明一個用來加載xib創建appView的方法
+ (instancetype)appView;
@end
HMAppView.m文件
#import "HMAppView.h"
#import "HMAppModel.h"
@interface HMAppView ()
/// 圖標
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
/// 名稱
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@end
@implementation HMAppView
+ (instancetype)appView {
// 加載xib文件
UINib *nib = [UINib nibWithNibName:@"HMAppView" bundle:nil];
// 把xib文件轉換成控件
return [[nib instantiateWithOwner:nil options:nil] firstObject];
}
// 重寫set方法攔截數據傳遞過程,只要set方法調用就說明有人給屬性賦值了
//- (void)setDict:(NSDictionary *)dict {
// _dict = dict;
//
// self.iconView.image = [UIImage imageNamed:dict[@"icon"]];
//
// self.nameLabel.text = dict[@"name"];
//
//
//}
// 重寫模型屬性的set方法給子控件設置數據
- (void)setAppModel:(HMAppModel *)appModel {
_appModel = appModel;
self.iconView.image = [UIImage imageNamed:appModel.icon];
self.nameLabel.text = appModel.name;
}
@end
HMAppModel.h文件
#import <Foundation/Foundation.h>
@interface HMAppModel : NSObject
/// 名稱
@property (nonatomic, copy) NSString *name;
/// 圖標名稱
@property (nonatomic, copy) NSString *icon;
+ (instancetype)appModelWithDict:(NSDictionary *)dict;
@end
HMAppModel.m文件
@implementation HMAppModel
+ (instancetype)appModelWithDict:(NSDictionary *)dict {
// 創建模型對象
id obj = [[self alloc] init];
// 用KVC給對象中的屬性賦值
[obj setValuesForKeysWithDictionary:dict];
return obj;
}