视图基础
- 视图是UIView对象 or UIView子类对象。
- 视图可以处理事件,如触摸。
- 视图按照层次结构排列。
UIWindow
- 任何一个应用有且只有一个UIWindow。
- UIWindow负责包含应用中的所有视图。
创建UIView子类
- 初始化
initWithFrame
- (instancetype)initWithFrame:(CGRect)aRect
该方法是UIView的指定初始化方法,带有一个CGRect结类型的参数,该参数会赋给UIView的frame属性。
@property (nonatomic) CGRect frame;
//视图的frame属性保存的是视图的大小和相对于父视图的位置
- CGRect
CGRect结构包含另外两个结构:origin和size。
- origin的类型是CGPoint。包含两个float类型成员:x和y。
表示视图的相对于父视图的位置。 - size的类型是CGSize。包含两个float类型成员:width和height。
表示视图的大小。
- origin的类型是CGPoint。包含两个float类型成员:x和y。
application:didFinishLaunchingWithOptions
方法
应用启动时会调用此方法。
app生命周期,启动前台时:
启动后台时:
- 初始化一个UIView并将其加入UIWindow对象
/** @brief CGRectMake函数用于创建CGRect
* CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
* @param x, y 矩形坐标
* @param width,height 矩形大小
*/
CGRect myRect = CGRectMake(199,199,199,199);
/** @brief 传入rect初始化
* CGRect占用的内存比大部分对象都小
* 因此不用传入指针,
* 传入的参数是CGRect,而不是CGRect *
*/
MyView myView = [[MyView alloc]initWithFrame:myRect];
// 定义myView定义为红色
myView.backgroundColor = [UIColor redColor];
// 加入UIWindow
[self.window addSubview:myView];
drawRect自定义视图
UIView子类可覆盖drawRect:方法完成自定义的绘图任务。
覆盖drawRect方法后,应先获得从UIView继承来的bounds属性,该属性定义了一个矩形范围,表示视图的绘制区域。
bounds与frame的区别
– frame表示矩形位于父视图的坐标系,用于确定与视图层次中其他视图的相对位置,从而将自己的涂层与其他的图层正确的组合到屏幕上。
– bounds表示的矩形位于自己的坐标系,用于确定绘制区域,避免将自己绘制到图层边界之外。
eg:绘制一个圆形
- (void)drawRect:(CGRect)rect
{
CGRect bounds = self.bounds;
// 根据bounds计算中心点
CGPoint center;
center.x = bounds.origin.x + bounds.size.width / 2.0;
center.y = bounds.origin.y + bounds.size.height / 2.0;
// 根据视图宽和高中较小值计算圆形的半径
float width = bounds.size.width;
float height = bounds.size.height;
float radius = (MIN(width, height) / 2.0);
// 使用UIBezierPath类绘制图形
UIBezierPath *path = [[UIBezier alloc] init];
// 以中心点为圆心,radius的值为半径,
// 定义一个0到M_PI * 2.0弧度的路径(整圆)
[path addArcWithCenter:center
radius:radius
startAngle:0.0
endAngle:M_PI * 2.0
clockwise:YES];
// 绘制路径
[path stroke];
}
UIBezierPath
使用UIBezierPath类可以创建基于矢量的路径。此类是Core Graphics框架关于path的一个封装。使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线段组成的形状。
// 设置线条宽度
path.lineWidth = 10;
// setStroke用于设置绘制颜色
[[UIColor lightGrayColor] setStroke];
// 透明色
[UIColor clearColor];
// moveToPoint 抬笔,绘制多个图形时要移动到正确的位置
[path moveToPoint:CGPointMake(x, y);
绘制图片
创建UI对象:
UIImage *image = [UIImage imageNamed:"image.png"];
此例图片放在项目根目录下。
绘制图片到视图上:
[image drawInRect:someRect];
设置someRect的大小可缩放图片。
视图重绘
类扩展(Class Extensions)
#import "BNRHypnosisView.h"
@interface BNRHypnosisView()
@property (strong, nonatomic) UIColor *circleColor;
@end
@implementation BNRHypnosisView
使用头文件的目的是向其他类公开该类声明的属性和方法,that is
to say,头文件中声明的属性和方法是对其他类可见的(visible)。
只在类内部使用的属性和方法应当声明在类扩展中。
运行循环(run loop)
运行循环的工作是监听事件,例如触摸。
当事件发生时,运行循环会为相应的事件找到处理方法。处理方法会调用其他方法,其他方法也许还会调用更多方法。当这些方法全部执行完毕后,控制权才会再次回到运行循环。
为了标记视图要重绘,必须向其发送setNeedsDisplay消息。
- iOS SDK中提供的视图对象会在显示内容发生改变时【自动】发送setNeedsDisplay重绘,例如,UILabel对象受到setText:消息后,就会自动重绘。
- 而对自定义的View子类,要【手动】向其发送setNeedsDisplay消息。
// 当视图改变时,向视图发送setNeedsDisplay消息。
[self setNeedsDisplay];
//只重绘指定(invalid)区域,不常用
[self setNeedsDisplayInRect:invalidRect];
UIScrollView
// 创建两个rect,小的作为scrollview窗口,大的为某一自定义view
CGRect screenRect = self.window.bounds;
CGRect bigRect = screenRect;
bigRect.size.width *= 2.0;
bigRect.size.height *= 2.0;
// 创建一个UIScrollView对象
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:screenRect];
[self.window addSubview:hypnosisView];
// 创建一个myView并将其加入UIScrollView对象
MyView *myView = [[MyView alloc]initWithFrame:bigRect];
[scrollView addSubView:myView];
// 告诉UIScrollView对象“取景”有多大
scrollView.contentSize = bigRect.size;