亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

[iOS基礎控件-4.4]進一步封裝"APP列表”,初見MVC模式

2019-11-14 19:49:44
字體:
來源:轉載
供稿:網友


A.從ViewController分離View

     之前的代碼中,View的數據加載邏輯放在了總的ViewController中,增加了耦合性,應該對控制器ViewController隱藏數據加載到View的細節。
     封裝View的創建邏輯
     封裝View的數據加載邏輯到自定義的UIView中

 
B.思路
使用xib封裝自定義view的步驟:
1.新建一個繼承UIView的自定義view,這里的名字是“AppView”,用來封裝獨立控件組
每個AppView封裝了如下圖的控件組
Image(5)
 
2.新建一個xib文件來描述控件結構,就是上圖的控件組
3.在Controller中使用AppView作為每個獨立控件組的類型單位
4.將控件和View “AppView” 進行連線
5.View “AppView” 提供一個模型屬性
6.重寫模型屬性的setter,解析模型數據
7.設置模型數據到控件中
8.自定義View “AppView”的構造方法,屏蔽讀取xib文件的細節
 
其實這就是一種簡單的MVC模式
Model: App.h, App.m
View: AppView.h, AppView.m
Controller: ViewController.h, ViewController.m
 
Controller連接了View和Model,取得數據后加載到Model,然后傳給View進行解析并顯示
 
 
C.實現
1.新建UIView類”AppView",繼承自UIView
new file ==>
創建聲明文件”AppView.h”和“AppView.m”
a.
Image(6)
 
b.
Image(7)
 
c.
Image(8)
 
2.設置xib的class (默認是UIView) 為新建的”AppView"
Image(9)
 
 
3.在新建的UIView中編寫View的數據加載邏輯
(1)在”AppView.h”中創建Model成員
1 // 在Controller和View之間傳輸的Model數據2 @PRoperty(nonatomic, strong) App *appData;
 
(2)連接控件和”AppView",創建私有控件成員
Image(10)
 
(3)在”AppView.m”中解析加載數據
1 - (void)setAppData:(App *)appData {2     _appData = appData;3    4     // 1.設置圖片5     self.iconView.image = [UIImage imageNamed:appData.icon];6     // 2.設置名字7     self.nameLabel.text = appData.name;8 }
 
(4)自定義構造方法
AppView.h:
1 // 自定義將Model數據加載到View的構造方法2 - (instancetype) initWithApp:(App *) appData;3 // 自定義構造的類方法4 + (instancetype) appViewWithApp:(App *) appData;5 // 返回一個不帶Model數據的類構造方法6 + (instancetype) appView;
 
AppView.m:
 1 // 自定義將Model數據加載到View的構造方法 2 - (instancetype) initWithApp:(App *) appData { 3     // 1.從NIB取得控件 4     UINib *nib = [UINib nibWithNibName:@"app" bundle:[NSBundle mainBundle]]; 5     NSArray *viewArray = [nib instantiateWithOwner:nil options:nil]; 6     AppView *appView = [viewArray lastObject]; 7     8     // 2.加載Model 9     appView.appData = appData;10    11     return appView;12 }13 14 // 自定義構造的類方法15 + (instancetype) appViewWithApp:(App *) appData {16     return [[self alloc] initWithApp:appData];17 }18 19 // 返回一個不帶Model數據的類構造方法20 + (instancetype) appView {21     return [self appViewWithApp:nil];22 }

 

 
(5)在Controller中創建”AppView”并加載數據
 1         // 1.創建View 2         AppView *appView = [AppView appViewWithApp:appData]; 3         4         // 2.定義每個app的位置、尺寸 5         CGFloat appX = marginX + column * (marginX + APP_WIDTH); 6         CGFloat appY = marginY + row * (marginY + APP_HEIGHT); 7         appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT); 8  9        10         // 3.加入此app信息到總view11         [self.view addSubview:appView];
 
 
主要代碼
  1 ViewController.m  2 #import "ViewController.h"  3 #import "App.h"  4 #import "AppView.h"  5   6 #define ICON_KEY @"icon"  7 #define NAME_KEY @"name"  8 #define APP_WIDTH 85  9 #define APP_HEIGHT 90 10 #define MARGIN_HEAD 20 11 #define ICON_WIDTH 50 12 #define ICON_HEIGHT 50 13 #define NAME_WIDTH APP_WIDTH 14 #define NAME_HEIGHT 20 15 #define DOWNLOAD_WIDTH (APP_WIDTH - 20) 16 #define DOWNLOAD_HEIGHT 20 17  18 @interface ViewController () 19  20 /** 存放應用信息 */ 21 @property(nonatomic, strong) NSArray *apps; // 應用列表 22  23 @end 24  25 @implementation ViewController 26  27 - (void)viewDidLoad { 28     [super viewDidLoad]; 29     // Do any additional setup after loading the view, typically from a nib. 30     31     [self loadApps]; 32 } 33  34 - (void)didReceiveMemoryWarning { 35     [super didReceiveMemoryWarning]; 36     // Dispose of any resources that can be recreated. 37 } 38  39 #pragma mark 取得應用列表 40 - (NSArray *) apps { 41     if (nil == _apps) { 42         // 1.獲得plist的全路徑 43         NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]; 44         45         // 2.加載數據 46         NSArray *dictArray  = [NSArray arrayWithContentsOfFile:path]; 47         48         // 3.將dictArray里面的所有字典轉成模型,放到新數組中 49         NSMutableArray *appArray = [NSMutableArray array]; 50         for (NSDictionary *dict in dictArray) { 51             // 3.1創建模型對象 52             App *app = [App appWithDictionary:dict]; 53             54             // 3.2 添加到app數組中 55             [appArray addObject:app]; 56         } 57         58         _apps = appArray; 59     } 60  61     return _apps; 62 } 63  64 #pragma mark 加載全部應用列表 65 - (void) loadApps { 66     int appColumnCount = [self appColumnCount]; 67     int appRowCount = [self appRowCount]; 68     69     CGFloat marginX = (self.view.frame.size.width - APP_WIDTH * appColumnCount) / (appColumnCount + 1); 70     CGFloat marginY = (self.view.frame.size.height - APP_HEIGHT * appRowCount) / (appRowCount + 1) + MARGIN_HEAD; 71     72     int column = 0; 73     int row = 0; 74     for (int index=0; index<self.apps.count; index++) { 75         App *appData = self.apps[index]; 76  77         // 1.創建View 78         AppView *appView = [AppView appViewWithApp:appData]; 79         80         // 2.定義每個app的位置、尺寸 81         CGFloat appX = marginX + column * (marginX + APP_WIDTH); 82         CGFloat appY = marginY + row * (marginY + APP_HEIGHT); 83         appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT); 84  85         86         // 3.加入此app信息到總view 87         [self.view addSubview:appView]; 88         89         column++; 90         if (column == appColumnCount) { 91             column = 0; 92             row++; 93         } 94     } 95 } 96  97  98 #pragma mark 計算列數 99 - (int) appColumnCount {100     int count = 0;101     count = self.view.frame.size.width / APP_WIDTH;102    103     if ((int)self.view.frame.size.width % (int)APP_WIDTH == 0) {104         count--;105     }106    107     return count;108 }109 110 #pragma mark 計算行數111 - (int) appRowCount {112     int count = 0;113     count = (self.view.frame.size.height - MARGIN_HEAD) / APP_HEIGHT;114    115     if ((int)(self.view.frame.size.height - MARGIN_HEAD) % (int)APP_HEIGHT == 0) {116         count--;117     }118    119     return count;120 }121 122 @end

 

AppView.m:

 1 #import "AppView.h" 2 #import "App.h" 3  4 // 封裝私有屬性 5 @interface AppView() 6  7 // 封裝View中的控件,只允許自己訪問 8 @property (weak, nonatomic) IBOutlet UIImageView *iconView; 9 @property (weak, nonatomic) IBOutlet UILabel *nameLabel;10 11 @end12 13 @implementation AppView14 15 - (void)setAppData:(App *)appData {16     // 1.賦值Medel成員17     _appData = appData;18    19     // 2.設置圖片20     self.iconView.image = [UIImage imageNamed:appData.icon];21     // 3.設置名字22     self.nameLabel.text = appData.name;23 }24 25 // 自定義將Model數據加載到View的構造方法26 - (instancetype) initWithApp:(App *) appData {27     // 1.從NIB取得控件28     UINib *nib = [UINib nibWithNibName:@"app" bundle:[NSBundle mainBundle]];29     NSArray *viewArray = [nib instantiateWithOwner:nil options:nil];30     AppView *appView = [viewArray lastObject];31    32     // 2.加載Model33     appView.appData = appData;34    35     return appView;36 }37 38 // 自定義構造的類方法39 + (instancetype) appViewWithApp:(App *) appData {40     return [[self alloc] initWithApp:appData];41 }42 43 // 返回一個不帶Model數據的類構造方法44 + (instancetype) appView {45     return [self appViewWithApp:nil];46 }47 48 @end

 

App.m
 1 #import "App.h" 2  3 #define ICON_KEY @"icon" 4 #define NAME_KEY @"name" 5  6 @implementation App 7  8 - (instancetype) initWithDictionary:(NSDictionary *) dictionary { 9     if (self = [super init]) {10         self.name = dictionary[NAME_KEY];11         self.icon = dictionary[ICON_KEY];12     }13    14     return self;15 }16 17 18 + (instancetype) appWithDictionary:(NSDictionary *) dictionary {19     // 使用self代表類名代替真實類名,防止子類調用出錯20     return [[self alloc] initWithDictionary:dictionary];21 }22 23 @end
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人综合久久| 午夜精品一区二区三区在线播放| 成人免费高清完整版在线观看| 91精品久久久久久久久久| 色中色综合影院手机版在线观看| 一本色道久久综合狠狠躁篇怎么玩| 久久亚洲国产成人| 日韩在线视频观看正片免费网站| 午夜精品美女自拍福到在线| 97久久精品在线| 日韩av最新在线| 国产成人精品一区二区三区| 日韩高清中文字幕| 91丝袜美腿美女视频网站| 欧美电影免费观看| 亚洲跨种族黑人xxx| 91禁国产网站| 国产69精品99久久久久久宅男| 91精品国产高清久久久久久久久| 日韩精品在线观看网站| 欧美黄网免费在线观看| 揄拍成人国产精品视频| 欧美日韩亚洲一区二| 国产69精品久久久久9999| 国产一区香蕉久久| 亚洲欧美成人一区二区在线电影| 久久久久久中文| 亚洲美女av在线| 成人免费视频xnxx.com| 国产日韩欧美一二三区| 91av在线视频观看| 日韩欧美在线免费观看| 在线视频欧美日韩精品| 国产精品嫩草影院久久久| 久热精品视频在线| 亚洲国产精品一区二区三区| 日韩一区二区在线视频| 亚洲欧美国产另类| 亚洲自拍av在线| 国产精品一区二区电影| 欧美另类暴力丝袜| 国产精品香蕉国产| 日韩亚洲欧美中文在线| 欧美日韩亚洲国产一区| 日韩欧美中文字幕在线播放| 国产精品视频xxxx| 国产精品女人久久久久久| 91在线免费网站| 欧美成人中文字幕| 中文精品99久久国产香蕉| 亚洲精品久久久久久久久久久久久| 国产精品三级美女白浆呻吟| 欧美激情手机在线视频| 美女扒开尿口让男人操亚洲视频网站| 色多多国产成人永久免费网站| 欧美高清视频一区二区| 成人欧美一区二区三区黑人孕妇| 亚洲精品国产精品久久清纯直播| 亚洲视频在线观看| 国产精品自产拍高潮在线观看| 97超视频免费观看| 亚洲性视频网站| 国产精品影片在线观看| 亚洲韩国欧洲国产日产av| 久久久精品2019中文字幕神马| 亚洲香蕉伊综合在人在线视看| 久久精品国产99国产精品澳门| 最新国产成人av网站网址麻豆| 国产精品网红直播| 在线成人激情黄色| 91国产视频在线播放| 亚洲香蕉成视频在线观看| 欧美成人亚洲成人日韩成人| 国产在线98福利播放视频| 日韩精品电影网| 91香蕉亚洲精品| 亚洲日韩中文字幕在线播放| 欧美色视频日本版| 亚洲大胆人体在线| 久久97精品久久久久久久不卡| 欧美另类极品videosbestfree| 欧美国产日韩一区| 欧美日韩亚洲91| 久久大大胆人体| 精品日韩视频在线观看| 91av网站在线播放| 久久久国产精品免费| 亚洲最大中文字幕| 日韩美女视频免费在线观看| 国产婷婷97碰碰久久人人蜜臀| 欧美自拍大量在线观看| 2020久久国产精品| 91免费看片网站| 欧洲成人性视频| 欧美裸体视频网站| 久久综合伊人77777蜜臀| 欧美国产视频一区二区| 国产成人精品a视频一区www| 国产一区二区日韩精品欧美精品| 成人亲热视频网站| 欧美理论电影在线观看| 亚洲欧美另类在线观看| 亚洲欧洲一区二区三区久久| 一区二区成人av| 亚洲福利视频二区| 日韩免费观看视频| 91精品国产综合久久久久久蜜臀| 国产最新精品视频| 国产在线拍揄自揄视频不卡99| 国产精品中文字幕久久久| 国产精品免费福利| 成人信息集中地欧美| 亚洲欧美自拍一区| 91网站在线看| 欧美午夜丰满在线18影院| 中文字幕亚洲专区| 日韩av免费观影| 青青a在线精品免费观看| 欧美激情欧美激情在线五月| 欧美日韩在线一区| 亚洲一区二区免费在线| 91免费综合在线| 日韩美女视频免费在线观看| 亚洲免费av网址| 国产视频精品在线| 欧美天天综合色影久久精品| 91国内产香蕉| 欧美性猛交xxxx黑人猛交| 国产丝袜精品第一页| 亚洲人成网站777色婷婷| 亚洲成人av资源网| 亚洲精品视频播放| 欧美成人在线免费| 亚洲人成毛片在线播放| 亚洲午夜精品久久久久久性色| 91国偷自产一区二区三区的观看方式| 日韩欧美中文免费| 欧美电影第一页| 国产精品最新在线观看| 亚洲欧美在线磁力| 亚洲第一天堂av| 久久色在线播放| 亚洲午夜久久久影院| 日韩欧美999| 国产97色在线|日韩| 欧美电影免费观看高清完整| 日韩不卡在线观看| 亚洲а∨天堂久久精品9966| 国产亚洲一区精品| 日韩福利视频在线观看| 在线视频一区二区| 91最新国产视频| 亚洲自拍av在线| 欧美日韩日本国产| 欧美日韩一区免费| 国产精品99久久久久久久久| 国产成人精品视频在线观看| 久久成人这里只有精品| 国产亚洲视频在线| 欧美一级片久久久久久久| 日韩免费av片在线观看| 国产精品电影网站| 久久人人爽人人| 97在线精品视频|