1.加载视图层次结构的方法
1.LoadView的方法
用纯代码开发的时候 简历视图层次结构, 与 Storard &Xib 是等价的
一旦实现了此方法,SB&XIB无效
- (void)loadView{
_scrllView = [[UIScrollView alloc]init];
_scrllView.backgroundColor = [UIColor orangeColor];
self.view =_scrllView;
UIImageView *imageView = [[UIImageView alloc]init];
[self.view addSubview:imageView];
_scrllView = [[UIScrollView alloc]init];
_scrllView.backgroundColor = [UIColor orangeColor];
self.view =_scrllView;
UIImageView *imageView = [[UIImageView alloc]init];
[self.view addSubview:imageView];
_imageView = imageView;
}
视图加载完毕后执行
- 如果纯代码开发,可以加载一些数据
- 如果sb开发,可以动态添加一些控件,以及加载数据
- (void)viewDidLoad {
[super viewDidLoad];
//url ->统一资源定位符,能够唯一定位网络上的一个资源
资源 html 图片 MP3 视频 flash
NSURL *url =[NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/e4dde71190ef76c666af095f9e16fdfaaf516741.jpg"];
// 加载网络数据(所有从网络上传输的数据,都市二进制的数据)
NSData *data = [NSData dataWithContentsOfURL:url];
//把二进制数据转换成图像
UIImage *image= [UIImage imageWithData:data];
//设置图像
self.image = image;
}
//image 的setter 方法
- (void)setImage:(UIImage *)image{
//设置图像视图
//设置图像视图
self.imageView.image = image;
// sizeToFit 可以将图像视图的大小和图像的大小一致
[self.imageView sizeToFit];
}
更新:
有的时候,不在主线程更新 UI 也不会出现问题,但是”一定要记住在主线程更新UI"
在实际开发中,如果出现,设置UI的动作执行之后,过一段时间之后,UI才会变化,那就说明 更新了UI线程,不在主线程内
比较常见的alertView
在主线程更新 UI
参数:
1. selctor 方法
2. 传递的对象
3. waitUntilDon : 是否等待完成
- NO 不等待 主线程的 selector 方法执行完毕
- YES 等待 主线程 selector 方法执行完毕
[self performSelectorOnMainThread:@selector(setImage:) withObject:nil waitUntilDone:NO];
在主线程中加载
二. 复习UI 细节
1.UIImage & UImageView 有什么区别?
UIimage是二进制的数据,理解成图片
UIimageView是一个视图 理解成相框
2. 为什么scrollView 是strong 如果改成weak 会怎么样
- 每一个视图控制器都有一个根视图
- vc 对跟视图强引用
- 改成weak 会让load View 循环
3. 为什么imageView 是weak
iv 默认是strong
- addSubView 方法之后,self.view 会对iv 进行强引用
4,为什么 setImage 方法中没有使用 _image = image;
- 是因为后续没有任何地方 getter image
- 需要使用 成员变量记录的原因:后续仍然需要使用
5image 可以设置成 weak 嘛??/
- 可以
- vc 对image 落引用
imageView 会对image 强引用
提示 仍对模型用strong
6 scrollView 是如何 imageView 进行缩放
- 设置代理
- 设置最大&最小缩放比例
- 实现方法
// 告诉滚动视图缩放谁?- vc 不负责缩放,scrollView 负责缩放
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
// 只要缩放就会被调用
/**
旋转由 a,b,c,d 一起控制
struct CGAffineTransform {
CGFloat a(缩放), b, c, d(缩放);
CGFloat tx(位移), ty(位移);
};
*/
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// transform 视图形变的仿射矩阵
NSLog(@"%@", NSStringFromCGAffineTransform(self.imageView.transform));
/**
旋转由 a,b,c,d 一起控制
struct CGAffineTransform {
CGFloat a(缩放), b, c, d(缩放);
CGFloat tx(位移), ty(位移);
};
*/
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// transform 视图形变的仿射矩阵
NSLog(@"%@", NSStringFromCGAffineTransform(self.imageView.transform));
}
加载视图层次结构的方法
用纯代码开发的时候,建立视图层次结构的,与 Storyboard & XIB 是等价的
用纯代码开发的时候,建立视图层次结构的,与 Storyboard & XIB 是等价的
一旦实现了此方法,SB & XIB 都无效
*/
- ( void)loadView {
_scrollView = [[UIScrollView alloc] init];
_scrollView.backgroundColor = [UIColor orangeColor];
_scrollView.delegate = self;
_scrollView.minimumZoomScale = 0.5;
_scrollView.maximumZoomScale = 2;
// 让根视图是 滚动视图 - "setter" 是给 view 设置数值,并没有判断 view 是否存在
self.view = _scrollView;
// 在 OC 中,对象默认都是 strong
UIImageView *iv = [[UIImageView alloc] init];
// self.view 是 getter 方法,会判断 view 是否存在
// addSubView 方法之后,self.view 会对 iv 进行强引用
[[self view] addSubview:iv];
// 与下一句等价
// [self.view addSubview:iv];
// 记录图像视图
_imageView = iv;
}
/**
视图加载完毕后执行的
- 如果是纯代码开发,可以加载一些数据
- 如果是 sb 开发,可以动态添加一些控件,以及加载数据
*/
- (void)viewDidLoad {
[super viewDidLoad];
// [self downloadImage];
// 多线程的目的,是将耗时操作放在后台
[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
}
// MARK: - 下载网络图像
- (void)downloadImage {
NSLog(@"%s %@", __FUNCTION__, [NSThread currentThread]);
// 1. url -> 统一资源定位符,能够唯一定位网络上的一个资源
// 资源:html,图片,mp3,视频,flash...
NSURL *url = [NSURL URLWithString:@"http://a.hiphotos.baidu.com/image/pic/item/d52a2834349b033ba3fb92da17ce36d3d539bdbb.jpg"];
// 2. 加载网络数据(所有从网络上传输的数据,都是二进制的数据)
NSData *data = [NSData dataWithContentsOfURL:url];
// 3. 把二进制数据转换成图像
UIImage *image = [UIImage imageWithData:data];
// 4. 设置图像
// 有的时候,不在主线程更新 UI 也不会出问题,但是:"一定记住在主线程更新 UI"
// 在实际开发中,如果出现,设置 UI 的动作执行之后,过一段时间之后, UI 才会变化,就说明是在后台更新了 UI
// 比较常见的:alertView
// 在主线程更新 UI
// self.image = image;
/**
performSelectorOnMainThread 在主线程执行 selector 方法
*** 线程间通讯,让主线程更新 UI
参数:
1. selector 方法
2. 传递的对象
3. waitUntilDone: 是否等待完成
- NO 不等待 主线程的 selector 方法执行完毕
- YES 等待 主线程的 selector 方法执行完毕
绝大多数,传递参数给主线程之后,就可以销毁了,因此,大多设置成 NO
*/
[self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
// 在子线程执行
NSLog(@"come here %@", [NSThread currentThread]);
}
/**
* image 的 setter 方法
*/
- (void)setImage:(UIImage *)image {
NSLog(@"%s %@", __FUNCTION__, [NSThread currentThread]);
// 1. 设置图像视图-会对 image 强引用
self.imageView.image = image;
// 2. sizeToFit 可以将图像视图的大小和图像的大小一致
[self.imageView sizeToFit];
// 3. 设置滚动视图的 contentSize - 就可以滚动了!
self.scrollView.contentSize = image.size;
}
// getter 方法直接返回 imageView 中的 image,不需要使用成员变量来记录 image
- (UIImage *)image {
return self.imageView.image;
- ( void)loadView {
_scrollView = [[UIScrollView alloc] init];
_scrollView.backgroundColor = [UIColor orangeColor];
_scrollView.delegate = self;
_scrollView.minimumZoomScale = 0.5;
_scrollView.maximumZoomScale = 2;
// 让根视图是 滚动视图 - "setter" 是给 view 设置数值,并没有判断 view 是否存在
self.view = _scrollView;
// 在 OC 中,对象默认都是 strong
UIImageView *iv = [[UIImageView alloc] init];
// self.view 是 getter 方法,会判断 view 是否存在
// addSubView 方法之后,self.view 会对 iv 进行强引用
[[self view] addSubview:iv];
// 与下一句等价
// [self.view addSubview:iv];
// 记录图像视图
_imageView = iv;
}
/**
视图加载完毕后执行的
- 如果是纯代码开发,可以加载一些数据
- 如果是 sb 开发,可以动态添加一些控件,以及加载数据
*/
- (void)viewDidLoad {
[super viewDidLoad];
// [self downloadImage];
// 多线程的目的,是将耗时操作放在后台
[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
}
// MARK: - 下载网络图像
- (void)downloadImage {
NSLog(@"%s %@", __FUNCTION__, [NSThread currentThread]);
// 1. url -> 统一资源定位符,能够唯一定位网络上的一个资源
// 资源:html,图片,mp3,视频,flash...
NSURL *url = [NSURL URLWithString:@"http://a.hiphotos.baidu.com/image/pic/item/d52a2834349b033ba3fb92da17ce36d3d539bdbb.jpg"];
// 2. 加载网络数据(所有从网络上传输的数据,都是二进制的数据)
NSData *data = [NSData dataWithContentsOfURL:url];
// 3. 把二进制数据转换成图像
UIImage *image = [UIImage imageWithData:data];
// 4. 设置图像
// 有的时候,不在主线程更新 UI 也不会出问题,但是:"一定记住在主线程更新 UI"
// 在实际开发中,如果出现,设置 UI 的动作执行之后,过一段时间之后, UI 才会变化,就说明是在后台更新了 UI
// 比较常见的:alertView
// 在主线程更新 UI
// self.image = image;
/**
performSelectorOnMainThread 在主线程执行 selector 方法
*** 线程间通讯,让主线程更新 UI
参数:
1. selector 方法
2. 传递的对象
3. waitUntilDone: 是否等待完成
- NO 不等待 主线程的 selector 方法执行完毕
- YES 等待 主线程的 selector 方法执行完毕
绝大多数,传递参数给主线程之后,就可以销毁了,因此,大多设置成 NO
*/
[self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
// 在子线程执行
NSLog(@"come here %@", [NSThread currentThread]);
}
/**
* image 的 setter 方法
*/
- (void)setImage:(UIImage *)image {
NSLog(@"%s %@", __FUNCTION__, [NSThread currentThread]);
// 1. 设置图像视图-会对 image 强引用
self.imageView.image = image;
// 2. sizeToFit 可以将图像视图的大小和图像的大小一致
[self.imageView sizeToFit];
// 3. 设置滚动视图的 contentSize - 就可以滚动了!
self.scrollView.contentSize = image.size;
}
// getter 方法直接返回 imageView 中的 image,不需要使用成员变量来记录 image
- (UIImage *)image {
return self.imageView.image;
}