zoukankan      html  css  js  c++  java
  • [iOS基础控件



    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信息到总view
    11         [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 @end
    12 
    13 @implementation AppView
    14 
    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.加载Model
    33     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
     
  • 相关阅读:
    Deep Learning入门
    基本技能(一)
    NNCRF之NNSegmentation, NNPostagging, NNNameEntity
    word2vector 使用方法 计算语义相似度
    Berkeley parser使用方法
    zpar使用方法之Chinese Word Segmentation
    【delphi】delphi出现‘尚未调用CoInitialize’异常
    VS05 VS08 VS10 工程之间的转换
    odbc数据源for mysql
    【delphi】Delphi过程、函数传递参数的八种方式
  • 原文地址:https://www.cnblogs.com/hellovoidworld/p/4121785.html
Copyright © 2011-2022 走看看