这就得自己封装控件
/*
网络图片显示问题的应用
1.首先需要网络请求到服务器上得数据
2.子类化集成自UIView的控件去创建,首先就得根据视图的宽度去匹配显示图片的高度,高度就得跟数据的个数一致,首先要定义一个方法,根据数据的个数宽度,返回高度,宽高的比例一比一
3.在数据的setter方法中对控件进行初始化,这里的小Bug,为防止多次setter,用for-in循环删除多余的视图,给定index返回一个frame
4.for循环建立这些控件,里面新建的控件需要子类化,继承自UIImageView,通过类目的方法给该类增加一些附属类,丰富类的属性和方法,在子类化时,需要传入手势和点击方法,所以在init方法中要初始化,并添加手势,添加到控件上,通过参数传递过来,需打开与用户的交互,UIImageView是不支持点击的
5.在for循环这些控件时,需要通过第三方框架,请求图片
6.在点击方法中present一个新的控制器,通过响应者链拿到控制器,把控制器呈现出来,期间不需要动画,并且在点击时完成数值的传值
7.在新呈现的控制器中初始化scrollView,并遵循代理协议,方便拿到下标值,scrollview需要设置内容视图的大小,并且再次用for循环初始化这些控件,并加在scrollview上,一开始隐藏滚动视图,在加载视图里完成
8.在viewDidload 里 需要转换坐标系 把当前点击的父视图调用。从当前转换为新呈现的frame,中间需要若干次的属性传值
//把item 移动到当前的视图上,并且放大视图
CGRect newFrame=[self.currentItem.superview convertRect:self.currentItem.frame toView:self.view];
//转换完坐标系,并换成新的坐标
[self.currentItem setFrame:newFrame];
[self.view addSubview:self.currentItem];
9.在视图已经出现时调用使图片放大,在viewDidAppear时调用
[UIView animateWithDuration:.25 animations:^{
[self.currentItem setFrame:self.view.bounds];
}completion:^(BOOL finished) {
//完成需完成的动作--恢复到原先的视图上
[self.currentItem setFrame:self.currentItem.originFrame];
[self.imgView addSubview:self.currentItem];
//显示滚动视图
_scrollView.hidden=NO;
[_scrollView scrollRectToVisible:CGRectMake(self.view.bounds.size.width*self.currentItem.index, 0, self.view.bounds.size.width, self.view.bounds.size.height) animated:NO];
10.添加手势需执行的代码
//获取当前的index 对应的item。放大,最后回味
CustomerImageItem *item=[self.imgView.items objectAtIndex:_index];
[item.superview bringSubviewToFront:item];
CGPoint point=[self.view convertPoint:CGPointZero toView:self.imgView];
[item setFrame:CGRectMake(point.x, point.y, self.view.bounds.size.width, self.view.bounds.size.height)];
[self dismissViewControllerAnimated:NO completion:^{
[UIView animateWithDuration:.25 animations:^{
[item setFrame:item.originFrame];
}];
}];
*/
网络图片显示问题的应用
1.首先需要网络请求到服务器上得数据
2.子类化集成自UIView的控件去创建,首先就得根据视图的宽度去匹配显示图片的高度,高度就得跟数据的个数一致,首先要定义一个方法,根据数据的个数宽度,返回高度,宽高的比例一比一
3.在数据的setter方法中对控件进行初始化,这里的小Bug,为防止多次setter,用for-in循环删除多余的视图,给定index返回一个frame
4.for循环建立这些控件,里面新建的控件需要子类化,继承自UIImageView,通过类目的方法给该类增加一些附属类,丰富类的属性和方法,在子类化时,需要传入手势和点击方法,所以在init方法中要初始化,并添加手势,添加到控件上,通过参数传递过来,需打开与用户的交互,UIImageView是不支持点击的
5.在for循环这些控件时,需要通过第三方框架,请求图片
6.在点击方法中present一个新的控制器,通过响应者链拿到控制器,把控制器呈现出来,期间不需要动画,并且在点击时完成数值的传值
7.在新呈现的控制器中初始化scrollView,并遵循代理协议,方便拿到下标值,scrollview需要设置内容视图的大小,并且再次用for循环初始化这些控件,并加在scrollview上,一开始隐藏滚动视图,在加载视图里完成
8.在viewDidload 里 需要转换坐标系 把当前点击的父视图调用。从当前转换为新呈现的frame,中间需要若干次的属性传值
//把item 移动到当前的视图上,并且放大视图
CGRect newFrame=[self.currentItem.superview convertRect:self.currentItem.frame toView:self.view];
//转换完坐标系,并换成新的坐标
[self.currentItem setFrame:newFrame];
[self.view addSubview:self.currentItem];
9.在视图已经出现时调用使图片放大,在viewDidAppear时调用
[UIView animateWithDuration:.25 animations:^{
[self.currentItem setFrame:self.view.bounds];
}completion:^(BOOL finished) {
//完成需完成的动作--恢复到原先的视图上
[self.currentItem setFrame:self.currentItem.originFrame];
[self.imgView addSubview:self.currentItem];
//显示滚动视图
_scrollView.hidden=NO;
[_scrollView scrollRectToVisible:CGRectMake(self.view.bounds.size.width*self.currentItem.index, 0, self.view.bounds.size.width, self.view.bounds.size.height) animated:NO];
10.添加手势需执行的代码
//获取当前的index 对应的item。放大,最后回味
CustomerImageItem *item=[self.imgView.items objectAtIndex:_index];
[item.superview bringSubviewToFront:item];
CGPoint point=[self.view convertPoint:CGPointZero toView:self.imgView];
[item setFrame:CGRectMake(point.x, point.y, self.view.bounds.size.width, self.view.bounds.size.height)];
[self dismissViewControllerAnimated:NO completion:^{
[UIView animateWithDuration:.25 animations:^{
[item setFrame:item.originFrame];
}];
}];
*/
//截图不全,代码奉上
// CustomerImage.m
// 图片显示
//
// Created by mac on 15/11/17.
// Copyright 2015年 mac. All rights reserved.
//
#import "CustomerImage.h"
#import "UIKit+AFNetworking.h"
#import "CollectionViewController.h"
#import "UIView+UIViewController.h"
static CGFloat margin=10;
@implementation CustomerImage
//根据数据的个数,和宽度更新高度
+ (CGFloat)heightForDataCount:(int)count withWidth:(CGFloat)width
{
if (count==4) {
return width;
}
if (count==1) {
return width;
}
int row=count/3;//第几行
if (count/3!=0) {
row+=1;
}
//图片的宽度
CGFloat itemW=(width-4 *margin)/3;
//图片的高度
CGFloat itemHeight=(itemW *row)+margin*(row+1);
return itemHeight;
}
//根据index 返回cgrect
- (CGRect)withIndex:(int)index
{
if (_data.count==1) {
CGFloat itemW=self.frame.size.width-margin *2;
return CGRectMake(margin, margin, itemW, itemW);
}
if (_data.count==4) {
CGFloat itemW=(self.frame.size.width-margin *3)/2;
CGFloat x=(index%2 *itemW)+(index %2 +1)*margin;
CGFloat y=(index/2*itemW)+(index/2+1)*margin;
return CGRectMake(x, y, itemW, itemW);
}
CGFloat itemW=(self.frame.size.width-margin *4)/3;
CGFloat x=(index%3 *itemW)+(index %3 +1)*margin;
CGFloat y=(index/3*itemW)+(index/3+1)*margin;
return CGRectMake(x, y, itemW, itemW);
}
- (void)setData:(NSArray *)data
{
/*
1.初始化在setter方法的原因因为在setter方法才有数据,在这里初始化便于给控件赋值
*/
//1.为了防止多次setter添加需移除
for (UIView *view in self.subviews) {
[view removeFromSuperview];
}
if (!self.items) {
_items=[[NSMutableArray alloc] init];
}
[self.items removeAllObjects];
_data=data;
//2.根据数据,计算本身宽高
CGFloat height=[CustomerImage heightForDataCount:(int)_data.count withWidth:self.frame.size.width];
NSLog(@"%f",height);
[self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, height)];
//3.for
for (int i=0; i<_data.count; i++) {
CustomerImageItem *image=[[CustomerImageItem alloc] initWithFrame:[self withIndex:i] target:self withAction:@selector(tapAct:)];
//把下标传给滚动视图,用index 存储下标值
image.index=i;
//存储原来的frame
image.originFrame=image.frame;
[image setImageWithURL:[NSURL URLWithString:_data[i]]];
//往items添加数据
[self.items addObject:image];
[self addSubview:image];
}
}
- (void)tapAct:(UITapGestureRecognizer *)tap
{
//拿到点击的view
CustomerImageItem *imageView=(CustomerImageItem *)tap.view;
CollectionViewController *vc=[[CollectionViewController alloc] init];
//传递数值
vc.currentItem=imageView;
//传值图片数组
vc.data=self.data;
//把视图传入
vc.imgView=self;
[self.viewController presentViewController:vc animated:NO completion:nil];
}
@end
@implementation CustomerImageItem
- (instancetype)initWithFrame:(CGRect)frame target:(nullable id)target withAction:(nullable SEL)sel
{
if (self=[super initWithFrame:frame]) {
//添加手势
self.userInteractionEnabled=YES;
//self.contentMode=UIViewContentModeScaleAspectFit;
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:target action:sel];
tap.numberOfTapsRequired=1;
[self addGestureRecognizer:tap];
}
return self;
}
@end
// CustomerImage.m
// 图片显示
//
// Created by mac on 15/11/17.
// Copyright 2015年 mac. All rights reserved.
//
#import "CustomerImage.h"
#import "UIKit+AFNetworking.h"
#import "CollectionViewController.h"
#import "UIView+UIViewController.h"
static CGFloat margin=10;
@implementation CustomerImage
//根据数据的个数,和宽度更新高度
+ (CGFloat)heightForDataCount:(int)count withWidth:(CGFloat)width
{
if (count==4) {
return width;
}
if (count==1) {
return width;
}
int row=count/3;//第几行
if (count/3!=0) {
row+=1;
}
//图片的宽度
CGFloat itemW=(width-4 *margin)/3;
//图片的高度
CGFloat itemHeight=(itemW *row)+margin*(row+1);
return itemHeight;
}
//根据index 返回cgrect
- (CGRect)withIndex:(int)index
{
if (_data.count==1) {
CGFloat itemW=self.frame.size.width-margin *2;
return CGRectMake(margin, margin, itemW, itemW);
}
if (_data.count==4) {
CGFloat itemW=(self.frame.size.width-margin *3)/2;
CGFloat x=(index%2 *itemW)+(index %2 +1)*margin;
CGFloat y=(index/2*itemW)+(index/2+1)*margin;
return CGRectMake(x, y, itemW, itemW);
}
CGFloat itemW=(self.frame.size.width-margin *4)/3;
CGFloat x=(index%3 *itemW)+(index %3 +1)*margin;
CGFloat y=(index/3*itemW)+(index/3+1)*margin;
return CGRectMake(x, y, itemW, itemW);
}
- (void)setData:(NSArray *)data
{
/*
1.初始化在setter方法的原因因为在setter方法才有数据,在这里初始化便于给控件赋值
*/
//1.为了防止多次setter添加需移除
for (UIView *view in self.subviews) {
[view removeFromSuperview];
}
if (!self.items) {
_items=[[NSMutableArray alloc] init];
}
[self.items removeAllObjects];
_data=data;
//2.根据数据,计算本身宽高
CGFloat height=[CustomerImage heightForDataCount:(int)_data.count withWidth:self.frame.size.width];
NSLog(@"%f",height);
[self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, height)];
//3.for
for (int i=0; i<_data.count; i++) {
CustomerImageItem *image=[[CustomerImageItem alloc] initWithFrame:[self withIndex:i] target:self withAction:@selector(tapAct:)];
//把下标传给滚动视图,用index 存储下标值
image.index=i;
//存储原来的frame
image.originFrame=image.frame;
[image setImageWithURL:[NSURL URLWithString:_data[i]]];
//往items添加数据
[self.items addObject:image];
[self addSubview:image];
}
}
- (void)tapAct:(UITapGestureRecognizer *)tap
{
//拿到点击的view
CustomerImageItem *imageView=(CustomerImageItem *)tap.view;
CollectionViewController *vc=[[CollectionViewController alloc] init];
//传递数值
vc.currentItem=imageView;
//传值图片数组
vc.data=self.data;
//把视图传入
vc.imgView=self;
[self.viewController presentViewController:vc animated:NO completion:nil];
}
@end
@implementation CustomerImageItem
- (instancetype)initWithFrame:(CGRect)frame target:(nullable id)target withAction:(nullable SEL)sel
{
if (self=[super initWithFrame:frame]) {
//添加手势
self.userInteractionEnabled=YES;
//self.contentMode=UIViewContentModeScaleAspectFit;
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:target action:sel];
tap.numberOfTapsRequired=1;
[self addGestureRecognizer:tap];
}
return self;
}
@end
.h文件
/*
1.图片展示点击在scrollView上
*/
#import <UIKit/UIKit.h>
#import "CustomerImage.h"
@interface CollectionViewController : UIViewController<UIScrollViewDelegate>
@property(nonatomic,strong)CustomerImageItem *currentItem;
@property(nonatomic,strong)NSArray *data;
@property(nonatomic,strong)CustomerImage *imgView;
@end
1.图片展示点击在scrollView上
*/
#import <UIKit/UIKit.h>
#import "CustomerImage.h"
@interface CollectionViewController : UIViewController<UIScrollViewDelegate>
@property(nonatomic,strong)CustomerImageItem *currentItem;
@property(nonatomic,strong)NSArray *data;
@property(nonatomic,strong)CustomerImage *imgView;
@end
.m文件
//
// CollectionViewController.m
// 图片显示
//
// Created by mac on 15/11/17.
// Copyright 2015年 mac. All rights reserved.
//
#import "CollectionViewController.h"
#import "UIKit+AFNetworking.h"
@interface CollectionViewController ()
{
UIScrollView *_scrollView;
int _index;//记住下标
}
@end
@implementation CollectionViewController
- (void)viewDidLoad {
[super viewDidLoad];
//加载视图
[self loadScroll];
//把item 移动到当前的视图上,并且放大视图
CGRect newFrame=[self.currentItem.superview convertRect:self.currentItem.frame toView:self.view];
//转换完坐标系,并换成新的坐标
[self.currentItem setFrame:newFrame];
[self.view addSubview:self.currentItem];
}
- (void)loadScroll
{
_scrollView=[[UIScrollView alloc] initWithFrame:self.view.bounds];
_scrollView.contentSize=CGSizeMake(self.view.frame.size.width *self.data.count, self.view.frame.size.height);
_scrollView.pagingEnabled=YES;
_scrollView.delegate=self;
[self.view addSubview:_scrollView];
_scrollView.hidden=YES;
for (int i=0; i<self.data.count; i++) {
//创建imgV
UIImageView *imgV=[[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width *i, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
imgV.userInteractionEnabled=YES;
imgV.contentMode=UIViewContentModeScaleAspectFit;
//加载图片---重新获取图片
[imgV setImageWithURL:[NSURL URLWithString:self.data[i]]];
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
tap.numberOfTapsRequired=1;
[imgV addGestureRecognizer:tap];
[_scrollView addSubview:imgV];
}
}
- (void)dismiss{
//获取当前的index 对应的item。放大,最后回味
CustomerImageItem *item=[self.imgView.items objectAtIndex:_index];
[item.superview bringSubviewToFront:item];
CGPoint point=[self.view convertPoint:CGPointZero toView:self.imgView];
[item setFrame:CGRectMake(point.x, point.y, self.view.bounds.size.width, self.view.bounds.size.height)];
[self dismissViewControllerAnimated:NO completion:^{
[UIView animateWithDuration:.25 animations:^{
[item setFrame:item.originFrame];
}];
}];
}
#pragma mark---当视图将要出现加载
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self zoomin];
}
//放大动画
- (void)zoomin
{
[UIView animateWithDuration:.25 animations:^{
[self.currentItem setFrame:self.view.bounds];
}completion:^(BOOL finished) {
//完成需完成的动作--恢复到原先的视图上
[self.currentItem setFrame:self.currentItem.originFrame];
[self.imgView addSubview:self.currentItem];
//显示滚动视图
_scrollView.hidden=NO;
[_scrollView scrollRectToVisible:CGRectMake(self.view.bounds.size.width*self.currentItem.index, 0, self.view.bounds.size.width, self.view.bounds.size.height) animated:NO];
}];
}
#pragma mark--scrollDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
_index=scrollView.contentOffset.x/scrollView.frame.size.width;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
// CollectionViewController.m
// 图片显示
//
// Created by mac on 15/11/17.
// Copyright 2015年 mac. All rights reserved.
//
#import "CollectionViewController.h"
#import "UIKit+AFNetworking.h"
@interface CollectionViewController ()
{
UIScrollView *_scrollView;
int _index;//记住下标
}
@end
@implementation CollectionViewController
- (void)viewDidLoad {
[super viewDidLoad];
//加载视图
[self loadScroll];
//把item 移动到当前的视图上,并且放大视图
CGRect newFrame=[self.currentItem.superview convertRect:self.currentItem.frame toView:self.view];
//转换完坐标系,并换成新的坐标
[self.currentItem setFrame:newFrame];
[self.view addSubview:self.currentItem];
}
- (void)loadScroll
{
_scrollView=[[UIScrollView alloc] initWithFrame:self.view.bounds];
_scrollView.contentSize=CGSizeMake(self.view.frame.size.width *self.data.count, self.view.frame.size.height);
_scrollView.pagingEnabled=YES;
_scrollView.delegate=self;
[self.view addSubview:_scrollView];
_scrollView.hidden=YES;
for (int i=0; i<self.data.count; i++) {
//创建imgV
UIImageView *imgV=[[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width *i, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
imgV.userInteractionEnabled=YES;
imgV.contentMode=UIViewContentModeScaleAspectFit;
//加载图片---重新获取图片
[imgV setImageWithURL:[NSURL URLWithString:self.data[i]]];
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
tap.numberOfTapsRequired=1;
[imgV addGestureRecognizer:tap];
[_scrollView addSubview:imgV];
}
}
- (void)dismiss{
//获取当前的index 对应的item。放大,最后回味
CustomerImageItem *item=[self.imgView.items objectAtIndex:_index];
[item.superview bringSubviewToFront:item];
CGPoint point=[self.view convertPoint:CGPointZero toView:self.imgView];
[item setFrame:CGRectMake(point.x, point.y, self.view.bounds.size.width, self.view.bounds.size.height)];
[self dismissViewControllerAnimated:NO completion:^{
[UIView animateWithDuration:.25 animations:^{
[item setFrame:item.originFrame];
}];
}];
}
#pragma mark---当视图将要出现加载
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self zoomin];
}
//放大动画
- (void)zoomin
{
[UIView animateWithDuration:.25 animations:^{
[self.currentItem setFrame:self.view.bounds];
}completion:^(BOOL finished) {
//完成需完成的动作--恢复到原先的视图上
[self.currentItem setFrame:self.currentItem.originFrame];
[self.imgView addSubview:self.currentItem];
//显示滚动视图
_scrollView.hidden=NO;
[_scrollView scrollRectToVisible:CGRectMake(self.view.bounds.size.width*self.currentItem.index, 0, self.view.bounds.size.width, self.view.bounds.size.height) animated:NO];
}];
}
#pragma mark--scrollDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
_index=scrollView.contentOffset.x/scrollView.frame.size.width;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
由于时间匆忙,工作比较忙,请谅解代码的糙, 截图加上代码,看不懂的可以留言,我看到会在第一时间给你回复