前提
对手机应用的使用, 点击, 触碰, 扫划. 统称为为交互.
看到的图像, 图片是应用的界面.
手机应用, 最重要的就是界面和交互.
应用大体分为
展示类, 地图类, 多媒体类, 即时通讯(微信, QQ等)类
不同于OC使用的Foundation框架(Foundation的类型名通常由NS开头), UI使用的框架是UIKit. UI控件的类型名通常是UI开头的
UI工程的main函数方法只有简单的一个方法
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
AppDelegate是遵守了<UIApplicationDelegate>
协议的UIResponder类的子类.
AppDelegate是系统自动生成的.
也可以选择自己创建一个UIResponder类的子类, 并遵守<UIApplicationDelegate>
协议的类.
作为应用启动类
<UIApplicationDelegate>
中定义了以下方法:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
本函数是应用加载完成后触发的.
UI工程的绝大多数的操作都是从本函数开始.
一个界面的显示区域是由window决定的, 通常将window的大小设置成屏幕大小.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible]; // 显示窗口
window的默认颜色是黑色.
这三句语句通常来说是万年不变的
window只是提供了一个可视化的窗口, 而具体的显示内容是由其他控件来实现的
只有控件或者它的父视图被添加在了window上才可以在屏幕中显示
UIView
UIView 表示一个视图, 默认是矩形(CGRect)的.
在APP上 矩形试图由两个结构体构成, CGPoint, 和CGSize
CGPoint表示点由点的坐标x, y组成, CGRect里表示原点(左上角的点)
CGSize表示大小, 由width和height组成
在手机上, 屏幕的原点(0, 0)是在手机的左上角. 横向为x轴, 纵向为y轴, 和常见的坐标轴有点不太相同的是x轴向右增大, y轴向下增大.
如何将一个view添加到窗口上之frame
// 创建一个视图控件, 并初始化其坐标和大小
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
view.backgroundColor = [UIColor blueColor]; // 将视图的背景色改成蓝色
[self.window addSubview:view];
// window将view添加在其之上作为window自身的子视图. 此时称window是view的父视图
注: CGRectMake()四个参数的作用分别是: 原点横坐标(orgin.x), 原点纵坐标(orgin.y), 矩形宽度(size.width), 矩形高度(size.height)(横向为宽, 纵向为高)
// 再创建一个视图控件
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
view2.backgroundColor = [UIColor yellowColor]; // 背景设为黄色
[view addSubview:view2]; // 将视图控件view2添加到view上, 作为view的子视图
添加到父视图上, 实际上就是添加到一个数组中.所以在addSubview后面可以将子视图的内存释放
[view release];
[view2 release];
取出子视图的方法:
NSArray *subView = self.window.subviews;
本句语句是获得self.window的子视图, 比如此时self.window的子视图只有一个view
view也有一个子视图view2, view2不属于self.window的子视图
p.s. 值得注意的是, 此时view2的原点(10,10) 是相对父类视图的原点, 此时view2是添加在view上的, 所以view2的父视图是view而不是window. 所以相对于window view2此时的原点坐标应该是(110, 110).
但是如果view2的坐标大小超出了父视图, 比如给view2的原点位置实在view之外的一个点, 虽然view2也能显示, 但是会造成无法对view2进行交互的问题.
- 结论1: 子类视图的坐标原点位置是根据父视图的原点位置而确定的. 这确保了在父视图的位置变化了的情况下子视图相对父视图的位置保持不变.
center
除了原点origin, 还有一个点很重要:CGPoint center
.它表示控件的中心点.它的值是相对父类视图的坐标.
通过修改center, 同样可以改变控件的位置.
CGPoint centerView = view.center; // 获得view的center
NSLog(@"%@", NSStringFromCGPoint(centerView)); // 查看
centerView = self.window.center; // 将view的中心点设置成center的中心点
view.center = centerView; // 结果是view移到了window的中心
- 结论2: 改变视图自身的位置有两种, 1. 改变原点的坐标 2. 改变中心点center的坐标.
bounds
bounds 边界. 可以控制子视图的坐标系.
改变bounds, 本类视图不会发生变化, 但是会改变子类视图的坐标系.
默认的bounds的原点是(0, 0) 宽高等于视图本身的宽高. 子类视图是参照父类视图的bounds来确定自身的位置的. 如果改变了原点本视图的bounds.orgin 比如设置view.bounds.orgin = CGPointMake(10, 10);
意思是将原来view的坐上角的点变成了从(0, 0)变成(10, 10). 这样(0, 0)点的位置应该在原来的(0, 0)的向左10, 向上10的位置. 而子视图的默认起始点是(0, 0). 此时相当于将子视图往左上角进行移动了.
改变bounds的时候 自身是不会发生变化的, 但是子视图会根据父视图bounds的变化而变化.
- 结论3: 改变父视图的bounds, 父视图的本身是不会发生变化的(包括父类视图的frame和center都不会被改变), 但是子视图会根据bounds的变化而变化.
bounds, frame, center三者的联系和差异
通过表格来两两对比一下
通过比较, bounds的原点改变, frame的原点不变, 所以父视图本身的位置不变, 但子视图的位置变化. bounds的size改变, 父视图的大小跟着改变. center随着frame一同不变
frame的原点改变, bounds的原点不变, center变化, 父视图分身的位置发生变化.
结论是bounds主要改变子视图的位置和自身的大小, frame和center相互控制, frame和center改变父视图的位置, frame也可改变父类视图的大小. 但是frame和center都不影响子视图
创建视图的步骤
- 开辟空间, 给定一个位置
- 给视图设置一些属性(例如背景颜色)
- 添加视图到其父视图上
- 释放内存
管理子视图的常用方法
实际上, 在一个视图上添加一些子视图的时候, 是将这些子视图添加到了一个数组里. 每个子视图都有各自的下标. 可以通过父视图的方法获得这个数组.
NSArray *subview = superview.subviews;
superview是父视图的名字
可以通过父视图调用这个数组关系对子视图进行操作.
如
- insertView: atIndex:
作用: 在数组中的某个下标中插入一个子视图 - insertView: aboveSubview:
作用: 在数组中的某个子视图之前插入一个子视图 - insertView: belowSubview:
作用: 在数组中的某个子视图之后插入一个子视图
当数组中有多个子视图的时候, 还可以通过如下方法管理
- bringSubviewToFont:
作用: 将某个子视图放到父视图的最上层显示 - sendSubviewToBack:
作用: 将某个子视图放到父视图的最下层 - exchangeSubviewAtIndex: withSubviewAtIndex:
作用: 交换两个下标的子视图位置
当然子视图也可以决定自身是否要离开父视图, 或者控制自己的显示与否等
- removeFromSuperview:
某个子视图将自己从父视图上移除 - hidden属性
subview.hidden = YES;
子视图subview将自己隐藏
当然父视图也可以调用这个属性hidden的setter方法
当superview.hidden = YES;
的时候, 父视图会带着它自己的子视图一同隐藏 alpha属性
子视图可以通过alpha属性控制自身的透明度.
subview.alpha = 0;
alpha默认是1, 取值为0 ~ 1, 1为全显示, 0为全透明
当alpha = 0的时候相当于 subview.hidden = YES;
如果父视图将自己的alpha修改为0, 那么它的所有子视图的透明度也会跟随着父视图一起改变.通过子视图获得其父视图方法
UIView *superView = [subView superView];
这样可以通过子视图调用superView方法, 获得父视图
如果不知道当前需要操作的子视图在父视图的数组中的下标位置甚至都不知道该子视图的指针名(或者获取不到该子视图的指针名的时候), 但是又想取出它进行操作的时候
可以通过设置tag的方法
redView.tag = 100; // 对子视图设置tag标签
UIView *view = [superview viewWithTag:100];
这种方法在同一个方法中操作不一定常用, 但是在跨方法的操作当中经常用.
tag的值为一个NSInteger型的整数. 同个父视图的子视图设置的tag不能重复. 同时注意不能给tag设置成0, 因为window默认值是0
UILabel
常用属性:
text // 类型为NSString *, 用于设置文本的文字
font // 类型为UIFont *, 用于设置文本的字号和字体
常用方法如下:// 改字体大小 + (UIFont *)systemFontOfSize:(CGFloat)fontSize; // 改字体大小并加粗 + (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize; // 设置字体大小及字体类型名 + (UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize; // 获取系统的所有安装的字体方法: + (NSArray *)familyNames;
textColor // 类型为UIColor * 用于设置文字颜色
- shadowColor // 类型为UIColor * 用于设置阴影文字的颜色
shadowOffset // 类型为CGSize 用于设置阴影文字的偏移量
// 文字的对齐方式 默认是NSTextAlignmentLeft左对齐 NSTextAlignment 枚举
- textAlignment // 返回值为NSTextAlignment 枚举 用于设置文字对齐方式
NSLineBreakMode // 用于设置断行显示的模式
// 控制文本显示多少行. 0和-1是自动换行, 超过label的行数范围无法显示.
- numberOfLines
整理
作为程序员在开发APP的时候常用的UIView里的方法有
view.backgroundColor = [UIColor xxxxColor];
// 设置背景色
view.frame = CGRectMake(80, 100, 150, 160);
// 设置view的框架
[self.window addSubview:view];
// 将子视图添加到父视图上的方法
view.center = CGPointMake(50, 50);
// 修改视图的center方法
默认计算center(中心点)的方式
center.x = frame.origin.x + frame.size.width/2;
center.y = frame.origin.y + frame.size.height/2;
view.bounds = CGRectMake(-10, -10, 100, 100);
// 修改bounds方法
改变父视图的bounds是改变子视图的坐标系的起点, 父视图的位置不变.
NSArray *subview = super.subviews;
// 从父视图中取出子视图的方法
值得一提的是, 在UIKit框架中, UIView 是所有可视化控件的父类. 所以以上关于UIView的方法, 任何可视化控件都可以使用.
添加视图方法:
管理视图层次
还有hidden 和alpha可以控制视图的显示状态
tag可以便于获取指定视图并操作
UIView UILabel常用初始化方法
- (instancetype)initWithFrame:(CGRect)frame;
MRC模式下用这个初始化方法的时候注意
在将创建出来的视图添加到了父视图上以后要及时release
修改frame可以通过
view.frame = CGRectMake( CGFloat value1,CGFloat value2,CGFloat value3,CGFloat value4);
的方法
UILabel常用方法
label.text = @"";
label.font = [UIFont systemFontSize:20];// 设置字体大小系统默认是17
label.numberOfLines = -1; // 文本在不超出label框架的时候自动换行
label.textAlignment = NSTextAlignmentCenter; // 设置居中对齐
label.backgroundColor = [UIColor clearColor]; // 设置文本框背景色clearColor透明
label.textColor = [UIColor blackColor]; // 设置文字颜色