麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

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

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拿到模型數據后給內部的子控件設置對應的數據


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久草在线视频首页 | 国产黄色毛片 | 久久影院一区二区三区 | 欧美hdfree性xxxx | 看a级毛片 | 国产精品一区网站 | 久久久久女人精品毛片九一 | 91在线精品亚洲一区二区 | 九九热精| 日韩一级精品 | 99亚洲国产精品 | 99这里精品 | 国人精品视频在线观看 | 国产精品成人av片免费看最爱 | 国产91影院| 日韩视频在线一区二区三区 | 欧美黄 片免费观看 | 蜜桃视频最新网址 | 毛片在线视频观看 | 中午字幕无线码一区2020 | 中日无线码1区 | 国产成人精品区 | 日韩精品中文字幕一区 | 欧美粗暴analvideos | 成人免费观看av | 一区二区精品在线 | 小视频免费在线观看 | 久久精品国产99久久6动漫亮点 | 中国洗澡偷拍在线播放 | 国产福利不卡一区二区三区 | 国产一级免费在线视频 | 免费看欧美黑人毛片 | 欧美成人精品一区二区男人小说 | 日韩在线激情 | 成人免费观看49www在线观看 | 轻点插视频 | 国产一区二区欧美 | 国产精品视频导航 | 羞羞视频免费观看入口 | 欧美在线黄色 | 九九热精品在线 |