[iOS基础控件 - 5.5] 代理设计模式 (基于”APP列表"练习)

A.概述

在"[iOS基础控件 - 4.4] APP列表 进一步封装,初见MVC模式”上进一步改进,给“下载”按钮加上效果、功能

1.按钮点击后,显示为“已下载”,并且不可以再按

2.在屏幕中间弹出一个消息框,通知消息“xx已经被安装”,慢慢消失

3.消息框样式为圆角半透明

B.不使用代理模式,使用app空间组和主View之间的父子View关系

1.在主View中创建一个消息框

主View控制器:ViewController.m

 1  // 创建下载成功消息框
 2     CGFloat labelWidth = 200;
 3     CGFloat labelHeight = 50;
 4     CGFloat labelX = (self.view.frame.size.width - labelWidth) / 2;
 5     CGFloat labelY = (self.view.frame.size.height - labelHeight) / 2;
 6     UILabel *successMsgLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelX, labelY, labelWidth, labelHeight)];
 7
 8     // 设置圆角矩形样式
 9     successMsgLabel.layer.cornerRadius = 10.0;
10     successMsgLabel.layer.masksToBounds = YES;
11
12     // 设置全透明隐藏
13     successMsgLabel.alpha = 0;
14
15     successMsgLabel.textColor = [UIColor whiteColor];
16     successMsgLabel.backgroundColor = [UIColor grayColor];
17     [successMsgLabel setTextAlignment:NSTextAlignmentCenter];
18     successMsgLabel.tag = 10;
19
20     [self.view addSubview:successMsgLabel];

2.直接在app空间组的控制器中操作消息框,加入到父控件(主View)

app控件组View:AppView.m

 1 // 点击下载按钮
 2 - (IBAction)onDownloadButtonClick {
 3     // 更改“下载”按钮样式
 4     [self.downloadButton setTitle:@"已下载" forState:UIControlStateDisabled];
 5     self.downloadButton.enabled = NO;
 6
 7     // 拿到消息框
 8     UILabel *successMsgLabel = [self.superview viewWithTag:10];
 9     successMsgLabel.text = [NSString stringWithFormat:@"成功安装了%@", self.appData.name];
10     successMsgLabel.alpha = 0.7;
11
12     // 使用动画
13     [UIView beginAnimations:nil context:nil];
14     [UIView setAnimationDuration:2];
15     successMsgLabel.alpha = 0;
16     [UIView commitAnimations];
17 }

缺点:view的父子关系规定了这两个view的层次关系,依赖性、耦合性太强,导致各个view都不能自由修改

C.不使用代理模式,在app控件组的view中将主View作为一个成员

1.在控件组AppView中创建主View的引用

控件组 AppView.h

1 // 存储主View的引用
2 @property (nonatomic, weak) UIView *vcView;

2.在主View逐个加载控件组的时候,设置主View的引用

ViewController.m

 1  for (int index=0; index<self.apps.count; index++) {
 2         App *appData = self.apps[index];
 3
 4         // 1.创建View
 5         AppView *appView = [AppView appViewWithApp:appData];
 6
 7         // 2.定义每个app的位置、尺寸
 8         CGFloat appX = marginX + column * (marginX + APP_WIDTH);
 9         CGFloat appY = marginY + row * (marginY + APP_HEIGHT);
10         appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT);
11
12         // 设置每个app控件view的主view引用
13         appView.vcView = self.view;
14
15         // 3.加入此app信息到总view
16         [self.view addSubview:appView];
17
18         column++;
19         if (column == appColumnCount) {
20             column = 0;
21             row++;
22         }

3.控件组AppView使用主View引用代替父控件引用

AppView.m

 1 // 点击下载按钮
 2 - (IBAction)onDownloadButtonClick {
 3     // 更改“下载”按钮样式
 4     [self.downloadButton setTitle:@"已下载" forState:UIControlStateDisabled];
 5     self.downloadButton.enabled = NO;
 6
 7     // 创建消息框
 8     UILabel *successMsgLabel = [self.vcView viewWithTag:10];
 9     successMsgLabel.text = [NSString stringWithFormat:@"成功安装了%@", self.appData.name];
10     successMsgLabel.alpha = 0.7;
11
12     // 使用动画
13     [UIView beginAnimations:nil context:nil];
14     [UIView setAnimationDuration:2];
15     successMsgLabel.alpha = 0;
16     [UIView commitAnimations];
17 }

缺点:控件组AppView的下载事件中取得控制器来弹出消息框,还是依赖于主View,耦合性强

D.暴露控件组AppView的“下载”按钮,在主控制器中编写“下载”事件方法,绑定方法

1.AppView暴露“下载”按钮控件给外部

AppView.h

1 // 将“下载”按钮控件移到 .h 文件中暴露
2 @property (weak, nonatomic) IBOutlet UIButton *downloadButton;

2.在控制器中编写“下载”单击事件方法

ViewController.m

 1 // 控制器创建“下载”按钮点击事件
 2 - (IBAction)onAppViewDownloadButtonClick:(UIButton *) downloadButton {
 3     // 更改“下载”按钮样式
 4     [downloadButton setTitle:@"已下载" forState:UIControlStateDisabled];
 5     downloadButton.enabled = NO;
 6
 7     // 创建消息框
 8     UILabel *successMsgLabel = [self.view viewWithTag:99];
 9
10     App *app = self.apps[downloadButton.tag];
11     successMsgLabel.text = [NSString stringWithFormat:@"成功安装了%@", app.name];
12     successMsgLabel.alpha = 0.7;
13
14     // 使用动画
15     [UIView beginAnimations:nil context:nil];
16     [UIView setAnimationDuration:2];
17     successMsgLabel.alpha = 0;
18     [UIView commitAnimations];
19 }
20
21 @end

3.给每个AppView的“下载”按钮绑定方法

 1  for (int index=0; index<self.apps.count; index++) {
 2         App *appData = self.apps[index];
 3
 4         // 1.创建View
 5         AppView *appView = [AppView appViewWithApp:appData];
 6
 7         // 2.定义每个app的位置、尺寸
 8         CGFloat appX = marginX + column * (marginX + APP_WIDTH);
 9         CGFloat appY = marginY + row * (marginY + APP_HEIGHT);
10         appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT);
11
12         // 存储每个AppView对应的AppData数据索引在tag中
13         appView.downloadButton.tag = index;
14
15         // 绑定每个AppView中的“下载”按钮点击事件
16         [appView.downloadButton addTarget:self action:@selector(onAppViewDownloadButtonClick:) forControlEvents:UIControlEventTouchUpInside];
17
18         // 3.加入此app信息到总view
19         [self.view addSubview:appView];
20
21         column++;
22         if (column == appColumnCount) {
23             column = 0;
24             row++;
25         }
26     }

缺点:依赖于AppView暴露的“下载”按钮,不能被修改

E.代理模式

1.原则:谁拥有资源,谁调用

添加label到控制器的逻辑:控制器来做

当点击“下载”按钮的时候,控件组AppView的按钮点击事件应该通知控制器,要执行添加label到控制器view的操作

控制器监听控件组AppView的下载按钮的点击

1.声明代理

AppView.h

1 // 定义代理的协议
2 @protocol AppViewDelegate <NSObject>
3 // “下载”按钮被点击事件
4 @optional
5 - (void) appViewClickedDownloadButton:(AppView *) appView;
6 @end

2.在AppView中创建代理引用

AppView.h

1 @interface AppView : UIView
2 // 代理
3 @property(nonatomic, weak) id<AppViewDelegate> delegate;
4 ...
5 @end

3.控制器遵守AppViewDelegate,使其拥有称为代理的资格

1 ViewController.m
2 @interface ViewController () <AppViewDelegate>
3 ...
4 @end

4.实现代理方法

ViewController.m

 1 // “下载”按钮点击的代理方法
 2 - (void)appViewClickedDownloadButton:(AppView *)appView {
 3     // 创建下载成功消息框
 4     CGFloat labelWidth = 200;
 5     CGFloat labelHeight = 50;
 6     CGFloat labelX = (self.view.frame.size.width - labelWidth) / 2;
 7     CGFloat labelY = (self.view.frame.size.height - labelHeight) / 2;
 8     UILabel *successMsgLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelX, labelY, labelWidth, labelHeight)];
 9
10     // 设置圆角矩形样式
11     successMsgLabel.layer.cornerRadius = 10.0;
12     successMsgLabel.layer.masksToBounds = YES;
13
14     // 设置全透明隐藏
15     successMsgLabel.alpha = 0;
16
17     successMsgLabel.textColor = [UIColor whiteColor];
18     successMsgLabel.backgroundColor = [UIColor grayColor];
19     [successMsgLabel setTextAlignment:NSTextAlignmentCenter];
20
21     successMsgLabel.text = [NSString stringWithFormat:@"成功安装了%@", appView.appData.name];
22     successMsgLabel.alpha = 0.7;
23
24     // 使用动画
25     [UIView beginAnimations:nil context:nil];
26     [UIView setAnimationDuration:2];
27     successMsgLabel.alpha = 0;
28     [UIView commitAnimations];
29
30     [self.view addSubview:successMsgLabel];
31 }

5.给每一个AppView设置代理

ViewController.m

 1   for (int index=0; index<self.apps.count; index++) {
 2         App *appData = self.apps[index];
 3
 4         // 1.创建View
 5         AppView *appView = [AppView appViewWithApp:appData];
 6
 7         // 2.定义每个app的位置、尺寸
 8         CGFloat appX = marginX + column * (marginX + APP_WIDTH);
 9         CGFloat appY = marginY + row * (marginY + APP_HEIGHT);
10         appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT);
11
12         // 设置代理
13         appView.delegate = self;
14
15         // 3.加入此app信息到总view
16         [self.view addSubview:appView];
17
18         column++;
19         if (column == appColumnCount) {
20             column = 0;
21             row++;
22         }
23     }

6.点击“下载”按钮的时候,通知代理

AppView.m

 1 // 点击下载按钮
 2 - (IBAction)onDownloadButtonClick {
 3     // 更改“下载”按钮样式
 4     [self.downloadButton setTitle:@"已下载" forState:UIControlStateDisabled];
 5     self.downloadButton.enabled = NO;
 6
 7     // 通知代理
 8     // 检查是否实现了代理方法
 9     if ([self.delegate respondsToSelector:@selector(appViewClickedDownloadButton:)]) {
10         [self.delegate appViewClickedDownloadButton:self];
11     }
12 }

主要代码:

Model:

 1 App.h
 2 //
 3 //  App.h
 4 //  01-应用管理
 5 //
 6 //  Created by hellovoidworld on 14/11/25.
 7 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 8 //
 9
10 #import <Foundation/Foundation.h>
11
12 @interface App : NSObject
13
14 /**
15 copy : NSString
16 strong: 一般对象
17 weak: UI控件
18 assign: 基本数据类型
19 */
20
21 /**
22 名称
23 */
24 @property(nonatomic, copy) NSString *name;
25
26 /**
27 图标
28 */
29 @property(nonatomic, copy) NSString *icon;
30
31 /**
32 自定义构造方法
33 通过字典来初始化模型对象
34 */
35 - (instancetype) initWithDictionary:(NSDictionary *) dictionary;
36
37 + (instancetype) appWithDictionary:(NSDictionary *) dictionary;
38
39 @end

App.m

 1 //
 2 //  App.m
 3 //  01-应用管理
 4 //
 5 //  Created by hellovoidworld on 14/11/25.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8
 9 #import "App.h"
10
11 #define ICON_KEY @"icon"
12 #define NAME_KEY @"name"
13
14 @implementation App
15
16 - (instancetype) initWithDictionary:(NSDictionary *) dictionary {
17     if (self = [super init]) {
18         self.name = dictionary[NAME_KEY];
19         self.icon = dictionary[ICON_KEY];
20     }
21
22     return self;
23 }
24
25
26 + (instancetype) appWithDictionary:(NSDictionary *) dictionary {
27     // 使用self代表类名代替真实类名,防止子类调用出错
28     return [[self alloc] initWithDictionary:dictionary];
29 }
30
31 @end

View:

 1 AppView.h
 2 //
 3 //  AppView.h
 4 //  01-应用管理
 5 //
 6 //  Created by hellovoidworld on 14/11/25.
 7 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 8 //
 9
10 #import <UIKit/UIKit.h>
11
12 @class App, AppView;
13
14 // 定义代理的协议
15 @protocol AppViewDelegate <NSObject>
16 // “下载”按钮被点击事件
17 @optional
18 - (void) appViewClickedDownloadButton:(AppView *) appView;
19 @end
20
21 @interface AppView : UIView
22
23 // 代理
24 @property(nonatomic, weak) id<AppViewDelegate> delegate;
25
26 // 在Controller和View之间传输的Model数据
27 @property(nonatomic, strong) App *appData;
28
29
30 // 自定义将Model数据加载到View的构造方法
31 - (instancetype) initWithApp:(App *) appData;
32 // 自定义构造的类方法
33 + (instancetype) appViewWithApp:(App *) appData;
34 // 返回一个不带Model数据的类构造方法
35 + (instancetype) appView;
36
37
38 @end

AppView.m

 1 //
 2 //  AppView.m
 3 //  01-应用管理
 4 //
 5 //  Created by hellovoidworld on 14/11/25.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8
 9 #import "AppView.h"
10 #import "App.h"
11
12 // 封装私有属性
13 @interface AppView()
14
15 // 封装View中的控件,只允许自己访问
16 @property (weak, nonatomic) IBOutlet UIImageView *iconView;
17 @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
18 @property (weak, nonatomic) IBOutlet UIButton *downloadButton;
19
20
21
22 - (IBAction)onDownloadButtonClick;
23
24 @end
25
26 @implementation AppView
27
28 - (void)setAppData:(App *)appData {
29     // 1.赋值Medel成员
30     _appData = appData;
31
32     // 2.设置图片
33     self.iconView.image = [UIImage imageNamed:appData.icon];
34     // 3.设置名字
35     self.nameLabel.text = appData.name;
36 }
37
38 // 自定义将Model数据加载到View的构造方法
39 - (instancetype) initWithApp:(App *) appData {
40     // 1.从NIB取得控件
41     UINib *nib = [UINib nibWithNibName:@"app" bundle:[NSBundle mainBundle]];
42     NSArray *viewArray = [nib instantiateWithOwner:nil options:nil];
43     AppView *appView = [viewArray lastObject];
44
45     // 2.加载Model
46     appView.appData = appData;
47
48     return appView;
49 }
50
51 // 自定义构造的类方法
52 + (instancetype) appViewWithApp:(App *) appData {
53     return [[self alloc] initWithApp:appData];
54 }
55
56 // 返回一个不带Model数据的类构造方法
57 + (instancetype) appView {
58     return [self appViewWithApp:nil];
59 }
60
61 // 点击下载按钮
62 - (IBAction)onDownloadButtonClick {
63     // 更改“下载”按钮样式
64     [self.downloadButton setTitle:@"已下载" forState:UIControlStateDisabled];
65     self.downloadButton.enabled = NO;
66
67     // 通知代理
68     // 检查是否实现了代理方法
69     if ([self.delegate respondsToSelector:@selector(appViewClickedDownloadButton:)]) {
70         [self.delegate appViewClickedDownloadButton:self];
71     }
72 }
73
74 @end

Controller:

ViewController.m

  1 //
  2 //  ViewController.m
  3 //  01-应用管理
  4 //
  5 //  Created by hellovoidworld on 14/11/24.
  6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
  7 //
  8
  9 #import "ViewController.h"
 10 #import "App.h"
 11 #import "AppView.h"
 12
 13 #define ICON_KEY @"icon"
 14 #define NAME_KEY @"name"
 15 #define APP_WIDTH 85
 16 #define APP_HEIGHT 90
 17 #define MARGIN_HEAD 20
 18 #define ICON_WIDTH 50
 19 #define ICON_HEIGHT 50
 20 #define NAME_WIDTH APP_WIDTH
 21 #define NAME_HEIGHT 20
 22 #define DOWNLOAD_WIDTH (APP_WIDTH - 20)
 23 #define DOWNLOAD_HEIGHT 20
 24
 25 @interface ViewController () <AppViewDelegate>
 26
 27 /** 存放应用信息 */
 28 @property(nonatomic, strong) NSArray *apps; // 应用列表
 29
 30 @end
 31
 32 @implementation ViewController
 33
 34 - (void)viewDidLoad {
 35     [super viewDidLoad];
 36     // Do any additional setup after loading the view, typically from a nib.
 37
 38     [self loadApps];
 39 }
 40
 41 - (void)didReceiveMemoryWarning {
 42     [super didReceiveMemoryWarning];
 43     // Dispose of any resources that can be recreated.
 44 }
 45
 46 #pragma mark 取得应用列表
 47 - (NSArray *) apps {
 48     if (nil == _apps) {
 49         // 1.获得plist的全路径
 50         NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];
 51
 52         // 2.加载数据
 53         NSArray *dictArray  = [NSArray arrayWithContentsOfFile:path];
 54
 55         // 3.将dictArray里面的所有字典转成模型,放到新数组中
 56         NSMutableArray *appArray = [NSMutableArray array];
 57         for (NSDictionary *dict in dictArray) {
 58             // 3.1创建模型对象
 59             App *app = [App appWithDictionary:dict];
 60
 61             // 3.2 添加到app数组中
 62             [appArray addObject:app];
 63         }
 64
 65         _apps = appArray;
 66     }
 67
 68     return _apps;
 69 }
 70
 71 #pragma mark 加载全部应用列表
 72 - (void) loadApps {
 73     int appColumnCount = [self appColumnCount];
 74     int appRowCount = [self appRowCount];
 75
 76     CGFloat marginX = (self.view.frame.size.width - APP_WIDTH * appColumnCount) / (appColumnCount + 1);
 77     CGFloat marginY = (self.view.frame.size.height - APP_HEIGHT * appRowCount) / (appRowCount + 1) + MARGIN_HEAD;
 78
 79     int column = 0;
 80     int row = 0;
 81     for (int index=0; index<self.apps.count; index++) {
 82         App *appData = self.apps[index];
 83
 84         // 1.创建View
 85         AppView *appView = [AppView appViewWithApp:appData];
 86
 87         // 2.定义每个app的位置、尺寸
 88         CGFloat appX = marginX + column * (marginX + APP_WIDTH);
 89         CGFloat appY = marginY + row * (marginY + APP_HEIGHT);
 90         appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT);
 91
 92         // 设置代理
 93         appView.delegate = self;
 94
 95         // 3.加入此app信息到总view
 96         [self.view addSubview:appView];
 97
 98         column++;
 99         if (column == appColumnCount) {
100             column = 0;
101             row++;
102         }
103     }
104
105 }
106
107
108 #pragma mark 计算列数
109 - (int) appColumnCount {
110     int count = 0;
111     count = self.view.frame.size.width / APP_WIDTH;
112
113     if ((int)self.view.frame.size.width % (int)APP_WIDTH == 0) {
114         count--;
115     }
116
117     return count;
118 }
119
120 #pragma mark 计算行数
121 - (int) appRowCount {
122     int count = 0;
123     count = (self.view.frame.size.height - MARGIN_HEAD) / APP_HEIGHT;
124
125     if ((int)(self.view.frame.size.height - MARGIN_HEAD) % (int)APP_HEIGHT == 0) {
126         count--;
127     }
128
129     return count;
130 }
131
132 // “下载”按钮点击的代理方法
133 - (void)appViewClickedDownloadButton:(AppView *)appView {
134     // 创建下载成功消息框
135     CGFloat labelWidth = 200;
136     CGFloat labelHeight = 50;
137     CGFloat labelX = (self.view.frame.size.width - labelWidth) / 2;
138     CGFloat labelY = (self.view.frame.size.height - labelHeight) / 2;
139     UILabel *successMsgLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelX, labelY, labelWidth, labelHeight)];
140
141     // 设置圆角矩形样式
142     successMsgLabel.layer.cornerRadius = 10.0;
143     successMsgLabel.layer.masksToBounds = YES;
144
145     // 设置全透明隐藏
146     successMsgLabel.alpha = 0;
147
148     successMsgLabel.textColor = [UIColor whiteColor];
149     successMsgLabel.backgroundColor = [UIColor grayColor];
150     [successMsgLabel setTextAlignment:NSTextAlignmentCenter];
151
152     successMsgLabel.text = [NSString stringWithFormat:@"成功安装了%@", appView.appData.name];
153     successMsgLabel.alpha = 0.7;
154
155     // 使用动画
156     [UIView beginAnimations:nil context:nil];
157     [UIView setAnimationDuration:2];
158     successMsgLabel.alpha = 0;
159     [UIView commitAnimations];
160
161     [self.view addSubview:successMsgLabel];
162 }
163
164 @end
时间: 2024-08-02 02:47:41

[iOS基础控件 - 5.5] 代理设计模式 (基于”APP列表"练习)的相关文章

iOS基础控件UINavigationController中的传值

iOS基础控件UINavigationController中的传值,代理传值,正向传值,反向传值 #import <UIKit/UIKit.h> //声明一个协议 @protocol SendValue<NSObject> //定义一个方法 - (void)sendBtnTitle:(NSString *)title; @end @interface FirstViewController : UIViewController // 定义代理 @property (nonatomi

[iOS基础控件 - 6.6] 展示团购数据 自定义TableViewCell

A.需求 1.头部广告 2.自定义cell:含有图片.名称.购买数量.价格 3.使用xib设计自定义cell,自定义cell继承自UITableViewCell 4.尾部“加载更多按钮”,以及其被点击之后的数据加载刷新.动画效果 B.实现 1.使用MVC M:团购Model V:总View.cell的View(包含类和界面) C:ViewController 2.分类管理代码文件 3.尾部footerView “加载更多"功能 1 // 设置尾部控件 2 self.tableView.table

ios基础控件之开关按钮(UISwitch)

UISwitch控件是iOS开发的基础控件,是非常简单的一个控件,因为它的方法比较少.UISwitch继承于UIControl基类,因此可以当成活动控件使用. 注意:开关状态通过它的on属性进行读取,该属性是一个BOOL属性 创建: UISwitch* mySwitch = [[ UISwitch alloc]initWithFrame:CGRectMake(0.150.0f,100.0f,0.0f,0.0f)]; 可能你会疑问为什么它的大小都设置为0?没错,它的大小你设置是无效的,系统会为你分

ios基础控件 之展示团购数据 UITableViewCell &lt;代理,xib封装view&gt;

1.主控制器: 1 // 2 // ViewController.m 3 // GroupPurchase 4 // 5 // Created by hellovoidworld on 14/12/3. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "GroupPurchase.h" 11 #im

iOS 基础控件(下)

上篇介绍了UIButton.UILabel.UIImageView和UITextField,这篇就简短一点介绍UIScrollView和UIAlertView. UIScrollView 顾名思义也知道这个是和滚动相关的控件,在Android开发时遇到过ScrollView,当内容的尺寸超出了屏幕范围之后,用ScrollView则可以通过滚动的方式使得超出屏幕的那部分内容通过滚动的方式显示出来,在Android里面有水平的ScrollView和垂直的ScrollView,在iOS里面就只有一个S

[iOS基础控件 - 6.9] 聊天界面Demo

A.需求 做出一个类似于QQ.微信的聊天界面 1.每个cell包含发送时间.发送人(头像).发送信息 2.使用对方头像放在左边,我方头像在右边 3.对方信息使用白色背景对话框,我方信息使用蓝色背景对话框 4.隐藏相同的发送时间 5.底部功能按钮:语音按钮.消息输入框.表情按钮.附加按钮 6.响应键盘事件,呼出键盘.隐藏键盘时对上述的视图作出上移操作 7.键盘的发送事件处理 B.实现点 1.底层视图搭建 上部分聊天信息框:UITableView 下部分功能区:UIButton 信息输入框使用无边框

[iOS基础控件 - 6.11.3] 私人通讯录Demo 控制器的数据传递、存储

A.需求 1.搭建一个“私人通讯录”Demo 2.模拟登陆界面 账号 密码 记住密码开关 自动登陆开关 登陆按钮 3.退出注销 4.增删改查 5.恢复数据(取消修改) B.基本架构 1. 5个控制器 (1)导航控制器 NavigationController (2)登陆 UIViewController 输入账号密码 记住密码.自动登录开关 登陆跳转按钮 (3)联系人列表 TableViewController 注销功能 添加联系人跳转按钮 (4)添加联系人 UIView (5)查看.编辑 UI

[iOS基础控件 - 7.0] UIWebView

A.基本使用 1.概念 iOS内置的浏览器控件 Safari浏览器就是通过UIWebView实现的 2.用途:制作简易浏览器 (1)基本请求 创建请求 加载请求 (2)代理监听webView加载,例如提示正在加载 (3)前进.后退 使用NavigationController,在底部加上导航栏(勾选showToolBar),加上回退和前进按钮 (4)给顶部导航栏加上地址栏 UISearchBar 代理监听“搜索”按钮,提取地址栏文本 1 // 2 // ViewController.m 3 //

【iOS基础控件 - 11】【Demo】模仿qq ,微信 UI 聊天界面

A.需求 做出一个类似于QQ.微信的聊天界面 1.每个cell包含发送时间.发送人(头像).发送信息 2.使用对方头像放在左边,我方头像在右边 3.对方信息使用白色背景对话框,我方信息使用蓝色背景对话框 4.隐藏相同的发送时间 5.底部功能按钮:语音按钮.消息输入框.表情按钮.附加按钮 6.响应键盘事件,呼出键盘.隐藏键盘时对上述的视图作出上移操作 7.键盘的发送事件处理 Code Source: B.实现点 1.底层视图搭建 上部分聊天信息框:UITableView 下部分功能区:UIButt