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

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

IOS開發學習筆記-基礎UI(10)九宮格布局,塊動畫,字典轉模型,Xib使用

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

大概如下圖示:九個應用圖標的樣子

功能分析
(1)以九宮格的形式展示應用信息
(2)點擊下載按鈕后,做出相應的操作
 
步驟分析
(1)加載應用信息
(2)根據應用的個數創建對應的view
(3)監聽下載按鈕點擊
 

思路整理

要在支持文件夾里,放入 plist 文件,且拖拽素材到 supporting files,注意勾選的項目的區別:

大多數情況,往項目中拖拽素材時,通常選擇 Destination, Folders:選擇第一項:創建組,這樣 xcode 導航顯式的是黃色文件夾,要知道,Xcode中資源素材是分文件夾存放的,但是在Bundle中所有素材所在,都在同一個文件夾下,這樣勾選的開發效率很高,但是,不能出現文件重名的情況,會讓美工不舒服。特點:可以直接使用[NSBundle mainBundle]作為資源路徑,效率高!可以使用[UIImage imageNamed:]加載圖像

如果選擇第二項, 創建文件家的引用:xcode顯得是藍色文件夾,此時資源在Xcode中分文件夾,在Bundle中也分文件夾,因此,可以出現文件重名的情況,特點:需要在[NSBundle mainBundle]的基礎上拼接實際的路徑,效率較差!不能使用[UIImage imageNamed:]加載圖像

 

app加載流程

1> app 從mainBundle中加載Plist

2> 按照plist中的數據數量先確定各個View的大小和位置

3> 不過,類似這樣的很多圖標,控件很多的 UI 設計,建議不使用故事板,而是使用代碼創建,否則后期維護也麻煩。

 

九宮格布局的計算方法

方法很多,不必死記硬背,要理解,不倫做什么,都是思想為主。九宮格的關鍵是要能夠順利計算出每一個小格子準確的坐標,建議:

1>  先創建若干小的視圖

2>  找到自己理解比較容易的計算方法

3>  編寫循環創建九宮格布局

要求:能夠公用的常量盡量給抽取出來,以便增加九宮格布局的靈活性,盡量保證做到:根據要顯示的數據自動調整小格子的位置和數量,一旦調整了要顯示的列數,僅需要修改少量的數值即可做到

 

 1 #import "ViewController.h" 2  3 @interface ViewController() 4 @PRoperty (nonatomic, strong) NSArray *appList; 5 @end 6  7 @implementation ViewController 8  9 - (NSArray *)appList10 {11     if (!_appList) {12         // 1. 從mainBundle加載13         NSBundle *bundle = [NSBundle mainBundle];14         NSString *path = [bundle pathForResource:@"app.plist" ofType:nil];15         _appList = [NSArray arrayWithContentsOfFile:path];16         17         NSLog(@"%@", _appList);18     }19     return _appList;20 }21 22 - (void)viewDidLoad23 {24     [super viewDidLoad];25     // 九宮格總共有3列26     int totalCol = 3;27     //每一個格子的寬度28     CGFloat viewW = 80;29     //每一個格子的高度30     CGFloat viewH = 90;31     //橫向間距的設定,把整個屏幕視圖的寬度減去三個格子的寬度,剩下的寬度平均分為四份32     CGFloat marginX = (self.view.bounds.size.width - totalCol * viewW) / (totalCol + 1);33     //縱向間距的設定34     CGFloat marginY = 10;35     //第一行方格的縱向坐標的開始位置36     CGFloat startY = 20;37     //self.appList.count一共需要繪制的方格的總數38     for (int i = 0; i < self.appList.count; i++) {39         // 行數 = 340         // i = 0, 1, 2  / 3 = 041         // i = 3, 4, 5  / 3 = 142         int row = i / totalCol;43         // 列數 = 344         // i = 0, 3, 6 % col 045         // i = 1, 4, 7 % col 146         // i = 2, 5, 8 % col 247         int col = i % totalCol;48         //設置方格的絕對坐標49         CGFloat x = marginX + (viewW + marginX) * col;50         CGFloat y = startY + marginY + (viewH + marginY) * row;51         //繪制方格52         UIView *appView = [[UIView alloc] initWithFrame:CGRectMake(x, y, viewW, viewH)];53         //把視圖控件添加到 appView54         [self.view addSubview:appView];55         56         // 創建appView內部的細節57         //讀取數組中的字典58         NSDictionary *dict = self.appList[i];59         60         // UIImageView61         UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, viewW, 50)];62         imageView.image = [UIImage imageNamed:dict[@"icon"]];63         // 按照比例顯示圖像64         imageView.contentMode = UIViewContentModeScaleaspectFit;65         66         [appView addSubview:imageView];67         68         //UILabel69         UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, imageView.bounds.size.height, viewW, 20)];70         // 設置文字71         label.text = dict[@"name"];72         label.font = [UIFont systemFontOfSize:12.0];73         label.textAlignment = NSTextAlignmentCenter;74         75         [appView addSubview:label];76         77         // UIButton78         // UIButtonTypeCustom和[[UIButton alloc] init]是等價的79         UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];80         button.frame = CGRectMake(15, 70, viewW - 30, 20);81         82         [button setTitle:@"下載" forState:UIControlStateNormal];83         // 不能使用如下代碼直接設置title84         // button.titleLabel.text = @"下載";85         // @property中readonly表示不允許修改對象的指針地址,但是可以修改對象的屬性86         button.titleLabel.font= [UIFont systemFontOfSize:14.0];87         88         [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];89         [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];90         91         [appView addSubview:button];92         93     }94 }

關于UIButton的一些補充

按鈕的類型,iOS的控件中,只有UIButton提供了類方法,可以在實例化按鈕時指定按鈕的不同類型。

UIButtonTypeCustom和[[UIButton alloc] init]是等價的

修改按鈕字體

在UIButton中定義有兩個readonly的屬性:

1> titleLabel

2> imageView

@property中readonly表示不允許修改這兩個屬性的指針地址,但是可以修改其屬性

 注意:由于按鈕的字體大小是所有狀態共用的,因此可以通過

button.titleLabel.font= [UIFont systemFontOfSize:14.0];

修改按鈕標簽文本的字體大小,但是不能使用以下代碼設置按鈕標簽的文本內容

button.titleLabel.text = @"下載";

因為按鈕標簽的文本內容是跟按鈕的狀態向關的

 

首尾式動畫

如果只是修改控件的屬性,使用首尾式動畫還是比較方便的,但是如果需要在動畫完成后做后續處理,就不是那么方便了

[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:1.0];// 修改屬性的動畫代碼// ......[UIView commitAnimations];

 

塊動畫

塊動畫相對來說比較靈活,尤為重要的是能夠將動畫相關的代碼編寫在一起,便于代碼的閱讀和理解

 

[UIView animateWithDuration:2.0 animations:^{    // 修改控件屬性動畫    label.alpha = 0.0;} completion:^(BOOL finished) {    // 刪除控件    [label removeFromSuperview];}];

 

 

字典轉模型的好處:

1> 降低代碼的耦合度

2> 所有字典轉模型部分的代碼統一集中在一處處理,降低代碼出錯的幾率

3> 在程序中直接使用模型的屬性操作,提高編碼效率

 

模型應該提供一個可以傳入字典參數的構造方法

- (instancetype)initWithDict:(NSDictionary *)dict;+ (instancetype)xxxWithDict:(NSDictionary *)dict;

 

instancetype & id

1> instancetype在類型表示上,跟id一樣,可以表示任何對象類型

2> instancetype只能用在返回值類型上,不能像id一樣用在參數類型上

3> instancetype比id多一個好處:編譯器會檢測instancetype的真實類型

 

在模型中添加readonly屬性

// 定義屬性時,會生成getter&setter方法,還會生成一個帶下劃線的成員變量// 而如果是readonly屬性,則只會生成getter方法,同時沒有成員變量@property (nonatomic, strong, readonly) UIImage *image;@interface AppInfo(){    UIImage *_imageABC;}
- (UIImage *)image{ if (!_imageABC) { _imageABC = [UIImage imageNamed:self.icon]; } return _imageABC;}

在模型中合理地使用只讀屬性,可以進一步降低代碼的耦合度。使用數據模型的好處:調用方不用關心模型內部的任何處理細節!

 

  1 #import "ViewController.h"  2 #import "AppInfo.h"  3   4 @interface ViewController ()  5 @property (nonatomic, strong) NSArray *appList;  6 @end  7   8 @implementation ViewController  9 // 字典轉模型 10 - (NSArray *)appList 11 { 12     if (!_appList) { 13         // 1. 從mainBundle加載 14         NSBundle *bundle = [NSBundle mainBundle]; 15         NSString *path = [bundle pathForResource:@"app.plist" ofType:nil]; 16         //_appList = [NSArray arrayWithContentsOfFile:path]; 17          18         NSArray *array = [NSArray arrayWithContentsOfFile:path]; 19         // 將數組轉換成模型,意味著self.appList中存儲的是AppInfo對象 20         // 1. 遍歷數組,將數組中的字典依次轉換成AppInfo對象,添加到一個臨時數組 21         // 2. self.appList = 臨時數組 22         NSMutableArray *arrayM = [NSMutableArray array]; 23  24         for (NSDictionary *dict in array) { 25             [arrayM addObject:[AppInfo appInfoWithDict:dict]]; 26         } 27          28         _appList = arrayM; 29     } 30     return _appList; 31 } 32  33 - (void)viewDidLoad 34 { 35     [super viewDidLoad]; 36      37     // 總共有3列 38     int totalCol = 3; 39     CGFloat viewW = 80; 40     CGFloat viewH = 90; 41      42     CGFloat marginX = (self.view.bounds.size.width - totalCol * viewW) / (totalCol + 1); 43     CGFloat marginY = 10; 44     CGFloat startY = 20; 45      46     for (int i = 0; i < self.appList.count; i++) { 47         // 行數 48         // i = 0, 1, 2  / 3 = 0 49         // i = 3, 4, 5  / 3 = 1 50         int row = i / totalCol; 51         // 列數 52         // i = 0, 3, 6 col 0 53         // i = 1, 4, 7 col 1 54         // i = 2, 5, 8 col 2 55         int col = i % totalCol; 56          57         CGFloat x = marginX + (viewW + marginX) * col; 58         CGFloat y = startY + marginY + (viewH + marginY) * row; 59          60         UIView *appView = [[UIView alloc] initWithFrame:CGRectMake(x, y, viewW, viewH)]; 61          62         [self.view addSubview:appView]; 63          64         // 創建appView內部的細節 65         // 讀取數組中的AppInfo 66         // NSDictionary *dict = self.appList[i]; 67         AppInfo *appInfo = self.appList[i]; 68          69         // UIImageView 70         UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, viewW, 50)]; 71         imageView.image = appInfo.image; 72         // 按照比例顯示圖像 73         imageView.contentMode = UIViewContentModeScaleAspectFit; 74          75         [appView addSubview:imageView]; 76          77         // UILabel 78         UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, imageView.bounds.size.height, viewW, 20)]; 79         // 設置文字 80         label.text = appInfo.name; 81         label.font = [UIFont systemFontOfSize:12.0]; 82         label.textAlignment = NSTextAlignmentCenter; 83          84         [appView addSubview:label]; 85          86         // UIButton 87         // UIButtonTypeCustom和[[UIButton alloc] init]是等價的 88         UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 89         button.frame = CGRectMake(15, 70, viewW - 30, 20); 90          91         [button setTitle:@"下載" forState:UIControlStateNormal]; 92         // 不能使用如下代碼直接設置title 93         // button.titleLabel.text = @"下載"; 94         // @property中readonly表示不允許修改對象的指針地址,但是可以修改對象的屬性 95         button.titleLabel.font= [UIFont systemFontOfSize:14.0]; 96          97         [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal]; 98         [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted]; 99         100         [appView addSubview:button];101         button.tag = i;102         103         [button addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];104     }105 }106 107 - (void)downloadClick:(UIButton *)button108 {109     NSLog(@"%d", button.tag);110     // 實例化一個UILabel顯示在視圖上,提示用戶下載完成111     UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(80, 400, 160, 40)];112     label.textAlignment = NSTextAlignmentCenter;113     label.backgroundColor = [UIColor lightGrayColor];114     115     LFAppInfo *appInfo = self.appList[button.tag];116     label.text = [NSString stringWithFormat:@"下載%@完成", appInfo.name];117     label.font = [UIFont systemFontOfSize:13.0];118     label.alpha = 1.0;119     [self.view addSubview:label];120     121     // 動畫效果122     // 動畫效果完成之后,將Label從視圖中刪除123     // 首尾式動畫,只能做動畫,要處理完成后的操作不方便124 //    [UIView beginAnimations:nil context:nil];125 //    [UIView setAnimationDuration:1.0];126 //    label.alpha = 1.0;127 //    [UIView commitAnimations];128     129     // block動畫比首尾式動畫簡單,而且能夠控制動畫結束后的操作130     // 在iOS中,基本都使用首尾式動畫131     [UIView animateWithDuration:2.0 animations:^{132         label.alpha = 0.0;133     } completion:^(BOOL finished) {134         // 刪除label135         [label removeFromSuperview];136     }];137 }138 139 @end

模型

#import <Foundation/Foundation.h>@interface AppInfo : NSObject// 應用程序名稱@property (nonatomic, copy) NSString *name;// 應用程序圖標名稱@property (nonatomic, copy) NSString *icon;// 圖像// 定義屬性時,會生成getter&setter方法,還會生成一個帶下劃線的成員變量// 如果是readonly屬性,只會生成getter方法,同時沒有成員變量@property (nonatomic, strong, readonly) UIImage *image;// instancetype會讓編譯器檢查實例化對象的準確類型// instancetype只能用于返回類型,不能當做參數使用- (instancetype)initWithDict:(NSDictionary *)dict;/** 工廠方法 */+ (instancetype)appInfoWithDict:(NSDictionary *)dict;@end

m 文件

#import "AppInfo.h"@interface AppInfo(){    UIImage *_imageABC;}@end@implementation AppInfo- (instancetype)initWithDict:(NSDictionary *)dict{    self = [super init];    if (self) {        self.name = dict[@"name"];        self.icon = dict[@"icon"];    }    return self;}+ (instancetype)appInfoWithDict:(NSDictionary *)dict{    return [[self alloc] initWithDict:dict];}- (UIImage *)image{    if (!_imageABC) {        _imageABC = [UIImage imageNamed:self.icon];    }    return _imageABC;}@end

 

XIB:Xib文件可以用來描述某一塊局部的UI界面

XIB & Storyboard

相同點:

1>  都用來描述軟件界面

2>  都用Interface Builder工具來編輯

不同點

1>  Xib是輕量級的,用來描述局部的UI界面

2>  Storyboard是重量級的,用來描述整個軟件的多個界面,并且能展示多個界面之間的跳轉關系

 

7. View的封裝思路

1>  如果一個view內部的子控件比較多,一般會考慮自定義一個view,把它內部子控件的創建屏蔽起來,不讓外界關心

2>  外界可以傳入對應的模型數據給view,view拿到模型數據后給內部的子控件設置對應的數據


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线视频一区| 久久久999精品视频| 欧美日韩免费观看中文| 久久久国产精彩视频美女艺术照福利| 国产黑人绿帽在线第一区| 中文字幕亚洲天堂| 日韩黄色在线免费观看| 日韩电视剧在线观看免费网站| 成人午夜激情网| 欧美性在线观看| 成人性生交大片免费观看嘿嘿视频| 日韩电影网在线| 国产精品久久色| 亚洲欧美资源在线| 国产精品美女999| 久久久噜噜噜久久中文字免| 亚洲精品视频久久| 黄色成人在线免费| 久久免费视频网| 日韩精品在线影院| 欧美一级视频一区二区| www.精品av.com| 亚洲男人天堂视频| 亚洲免费中文字幕| 51精品国产黑色丝袜高跟鞋| 日韩av中文字幕在线免费观看| 欧美激情精品久久久久久黑人| 97激碰免费视频| 日本a级片电影一区二区| 日韩风俗一区 二区| 国产丝袜精品视频| 成人久久久久久久| 欧美另类在线观看| 中文字幕精品www乱入免费视频| 欧洲永久精品大片ww免费漫画| 亚洲永久免费观看| 成人免费网站在线看| 国产精品99久久久久久白浆小说| 欧美精品在线免费观看| 91精品国产综合久久香蕉最新版| 亚洲精品综合久久中文字幕| 国模视频一区二区三区| 热门国产精品亚洲第一区在线| 欧美性极品xxxx娇小| 精品视频在线观看日韩| 国产精品一二三在线| 国产成人拍精品视频午夜网站| 亚洲成人中文字幕| 欧美性xxxx在线播放| 日本19禁啪啪免费观看www| 欧美精品在线视频观看| 日韩精品久久久久久久玫瑰园| 久久天天躁狠狠躁老女人| 日韩精品视频观看| 高清在线视频日韩欧美| 3344国产精品免费看| 日韩在线免费高清视频| 高清一区二区三区日本久| 久久影院免费观看| 亚洲欧美日本另类| 国产成人精品日本亚洲专区61| 国产做受69高潮| 日韩中文视频免费在线观看| 伊人久久免费视频| 欧美在线观看一区二区三区| 国产午夜精品免费一区二区三区| 精品国产一区二区三区久久久| 中文字幕日本精品| 2019中文字幕在线| 欧美在线视频网站| 亚洲在线观看视频| 97精品一区二区三区| 国产精品综合网站| 日本高清久久天堂| 久久精品电影网站| 精品视频中文字幕| 成人激情av在线| 在线成人中文字幕| 精品magnet| 国产成人欧美在线观看| 欧美激情精品久久久久久变态| 久久久久久久久久亚洲| 91av视频导航| 成人妇女免费播放久久久| 日韩在线观看高清| 欧美日韩精品中文字幕| 欧美在线视频免费观看| 精品国产老师黑色丝袜高跟鞋| 尤物yw午夜国产精品视频明星| 国精产品一区一区三区有限在线| 97国产一区二区精品久久呦| 亚洲欧洲国产一区| 91免费精品视频| 亚洲日韩欧美视频一区| 这里精品视频免费| 精品无人区太爽高潮在线播放| 都市激情亚洲色图| 久久人人爽人人爽人人片亚洲| 欧美日韩国产限制| 久久人人爽人人爽人人片av高清| 超碰日本道色综合久久综合| 亚洲影影院av| 日韩三级影视基地| 日韩高清a**址| 91国产视频在线播放| 日韩av在线不卡| 亚洲字幕在线观看| 日韩欧美中文第一页| 久久久国产精品x99av| 欧美日韩美女在线| 日韩av在线网址| 尤物yw午夜国产精品视频明星| 久久人人97超碰精品888| 久热99视频在线观看| 日韩精品久久久久久福利| 国产精品久久久久国产a级| 国产成人精品综合久久久| 亚洲欧美精品一区| 亚洲精品国偷自产在线99热| 国产欧美在线观看| 欧美肥臀大乳一区二区免费视频| 欧美国产日韩xxxxx| 国产日韩专区在线| 在线日韩欧美视频| 国产精品视频自在线| 亚洲免费电影在线观看| 国产精品久久婷婷六月丁香| 精品成人乱色一区二区| 色久欧美在线视频观看| 国产精品亚洲视频在线观看| 九九九久久国产免费| 欧美中文在线视频| 国产亚洲欧洲黄色| 亚洲欧美综合精品久久成人| 日韩高清a**址| 国产小视频91| 欧美日本精品在线| 国产精品香蕉国产| 国产亚洲欧洲黄色| 色妞一区二区三区| 成人欧美一区二区三区黑人| 欧美精品精品精品精品免费| 国产亚洲精品一区二555| 久久久噜噜噜久久中文字免| 欧美综合激情网| 国产精品免费视频xxxx| 亚洲欧美日韩中文在线制服| 91成人在线视频| 亚洲第一综合天堂另类专| 亚洲片在线资源| 欧美特级www| 亚洲a级在线播放观看| 久久精品国产欧美激情| 欧美成人在线免费| 国产91精品在线播放| 亚洲人成在线观看| 欧美性xxxx极品高清hd直播| 亚洲精品国产综合区久久久久久久| 亚洲国模精品一区| 欧美激情久久久久久| 色综合久久悠悠| 欧美专区中文字幕| 久久男人资源视频| www.午夜精品|