//VRefreshHeadView.h文件
// // VRefreshHeadView.h // 下拉刷新控件 // // Created by Vie on 2016/10/10. // Copyright © 2016年 Vie. All rights reserved. // #import <UIKit/UIKit.h> typedef NS_ENUM(NSUInteger, VRefreshType) { VRefreshTypeDefault = 0,//默认下拉刷新样式 }; @interface VRefreshHeadView : UIView typedef void (^beginRefreshBlock) (VRefreshHeadView *vrefresh);//刷新事件回调 @property(nonatomic,assign) NSUInteger type;//刷新视图样式 /** 创建下拉刷新视图 @param scrollView 滚动视图 @param beginRefreshBlock 开始刷新回调 @return 刷新视图对象 */ -(instancetype)initWithScrollView:(UIScrollView *)scrollView beginRefreshBlock:(beginRefreshBlock)beginRefreshBlock; //停止刷新 -(void)endRefresh; @end
//VRefreshHeadView.m文件
// // VRefreshHeadView.m // 下拉刷新控件 // // Created by Vie on 2016/10/10. // Copyright © 2016年 Vie. All rights reserved. // #import "VRefreshHeadView.h" #define vRefreshHeadViewHeight 40 #define navBarHeight 64 //竖屏导航栏和控制器高度(竖屏导航栏高度44,竖屏状态栏高度为20、打电话或者某些情况为40) @interface VRefreshHeadView () @property (nonatomic,copy) beginRefreshBlock beginRefreshBlock; @property(nonatomic,weak) UIScrollView *scrollView; /** *头部提示语 */ @property(nonatomic,weak) UILabel *headTipLable; /** * 加载提示 */ @property (nonatomic, weak) UIActivityIndicatorView *indicatorView; /** *是否处于刷新状态 */ @property(nonatomic,assign) BOOL isRefresh; @end @implementation VRefreshHeadView #pragma mark - init方法 -(instancetype)initWithScrollView:(UIScrollView *)scrollView beginRefreshBlock:(beginRefreshBlock)beginRefreshBlock{ self=[super initWithFrame:CGRectMake(0, -vRefreshHeadViewHeight, scrollView.frame.size.width, vRefreshHeadViewHeight)]; if (self) { _scrollView=scrollView; _beginRefreshBlock=beginRefreshBlock; //把当前视图加载到scrollView的UI [_scrollView addSubview:self]; //设置背景颜色 self.backgroundColor=[UIColor clearColor]; //默认不在刷新状态 self.isRefresh=false; //注册观察者,监听下拉刷新改变 [_scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; } return self; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"contentOffset"]) { if (_scrollView.contentOffset.y<(-navBarHeight-vRefreshHeadViewHeight)&&!self.isRefresh&&_scrollView.dragging) { [self.indicatorView startAnimating]; self.isRefresh=true; self.headTipLable.text=@"加载中.."; _scrollView.contentInset = UIEdgeInsetsMake(vRefreshHeadViewHeight+navBarHeight, 0, 0, 0); if (_beginRefreshBlock) { _beginRefreshBlock(self); } } } } //停止刷新 -(void)endRefresh{ [UIView animateWithDuration:0.3 animations:^{ // _scrollView.contentInset = UIEdgeInsetsZero; _scrollView.contentInset = UIEdgeInsetsMake(navBarHeight, 0, 0, 0); } completion:^(BOOL finished) { [self.indicatorView stopAnimating]; self.isRefresh=false; _headTipLable.text=@"下拉刷新数据"; }]; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. */ - (void)drawRect:(CGRect)rect { // Drawing code if (_type) { }else{ //没有指定type用默认视图 [self setDefaultView]; } } //默认样式 -(void)setDefaultView{ [self headTipLable]; } #pragma mark - 懒加载创建控件 - (UIActivityIndicatorView *)indicatorView { if (!_indicatorView) { UIActivityIndicatorView *act = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(50, 0, 30, self.frame.size.height)]; act.color = [UIColor grayColor]; [self addSubview:act]; _indicatorView = act; } return _indicatorView; } -(UILabel *)headTipLable{ if (!_headTipLable) { UILabel *lb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width,self.frame.size.height)]; lb.textAlignment = NSTextAlignmentCenter; lb.textColor = [UIColor grayColor]; lb.font = [UIFont systemFontOfSize:13]; lb.text = @"下拉刷新数据"; [self addSubview:lb]; _headTipLable = lb; } return _headTipLable; } -(void)dealloc{ [_scrollView removeObserver:self forKeyPath:@"contentOffset"]; } @end
//使用
#import "VRefreshHeadView.h" @property(nonatomic,strong) VRefreshHeadView *vrefresh; -(VRefreshHeadView *)vrefresh{ __weak typeof(self) weakSelf = self; if (!_vrefresh) { _vrefresh=[[VRefreshHeadView alloc] initWithScrollView:weakSelf.tbView beginRefreshBlock:^(VRefreshHeadView *vrefresh) { NSLog(@"进入刷新回调"); [self performSelector:@selector(endVrefresh) withObject:nil afterDelay:3.0f]; }]; } return _vrefresh; } [self vrefresh];
//VLoadMoreFootView.h文件
// // VLoadMoreFootView.h // 上拉加载更多控件 // // Created by Vie on 2016/10/17. // Copyright © 2016年 Vie. All rights reserved. // #import <UIKit/UIKit.h> typedef NS_ENUM(NSUInteger, VLoadMoreType) { VLoadMoreTypeDefault = 0,//默认上拉加载样式 }; @interface VLoadMoreFootView : UIView typedef void (^beginLoadMoreBlock) (VLoadMoreFootView *vrefresh);//加载更多事件回调 @property(nonatomic,assign) NSUInteger type;//加载更多视图样式 /** 创建上拉加载新视图 @param scrollView 滚动视图 @param beginLoadMoreBlock 开始加载更多回调 @return 加载视图对象 */ -(instancetype)initWithScrollView:(UIScrollView *)scrollView beginLoadMoreBlock:(beginLoadMoreBlock)beginLoadMoreBlock; //停止加载 -(void)endLoadMore; @end
//VLoadMoreFootView.m文件
// // VLoadMoreFootView.m // 上拉加载更多控件 // // Created by Vie on 2016/10/17. // Copyright © 2016年 Vie. All rights reserved. // #import "VLoadMoreFootView.h" #define vLoadMoreBottomViewHeight 40 #define navBarHeight 64 //竖屏导航栏和控制器高度(竖屏导航栏高度44,竖屏状态栏高度为20、打电话或者某些情况为40) @interface VLoadMoreFootView() @property(nonatomic,copy) beginLoadMoreBlock beginLoadMoreBlock; @property(nonatomic,weak) UIScrollView *scrollView; /** *底部提示语 */ @property(nonatomic,weak) UILabel *bottomTipLable; /** *加载提示 */ @property(nonatomic,weak) UIActivityIndicatorView *indicatorView; /** *是否处于加载状态 */ @property(nonatomic,assign) BOOL isLoad; @end @implementation VLoadMoreFootView #pragma mark - init方法 -(instancetype)initWithScrollView:(UIScrollView *)scrollView beginLoadMoreBlock:(beginLoadMoreBlock)beginLoadMoreBlock{ self=[super initWithFrame:CGRectMake(0, 0, scrollView.frame.size.width, vLoadMoreBottomViewHeight)]; if (self) { _scrollView=scrollView; _beginLoadMoreBlock=beginLoadMoreBlock; //把当前视图加载到scrollView的UI [_scrollView addSubview:self]; //设置背景颜色 self.backgroundColor=[UIColor clearColor]; //默认不在加载状态 self.isLoad=false; //注册观察这,监听上拉加载改变 [_scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; } return self; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"contentOffset"]) { if (_scrollView.contentOffset.y>(_scrollView.contentSize.height-_scrollView.frame.size.height)&&!self.isLoad&&_scrollView.dragging) { [self.indicatorView startAnimating]; self.isLoad=true; self.bottomTipLable.text=@"加载中.."; _scrollView.contentInset = UIEdgeInsetsMake(0, 0, vLoadMoreBottomViewHeight, 0); if (_beginLoadMoreBlock) { _beginLoadMoreBlock(self); } } } } //停止加载 -(void)endLoadMore{ [UIView animateWithDuration:0.3 animations:^{ // _scrollView.contentInset = UIEdgeInsetsZero; _scrollView.contentInset = UIEdgeInsetsMake(navBarHeight, 0, 0, 0); } completion:^(BOOL finished) { [self.indicatorView stopAnimating]; self.isLoad=false; _bottomTipLable.text = @"上拉加载更多数据"; }]; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. */ - (void)drawRect:(CGRect)rect { // Drawing code if (_type) { }else{ //没有指定type用默认视图 [self setDefaultView]; } } //默认样式 -(void)setDefaultView{ [self bottomTipLable]; } -(UILabel *)bottomTipLable{ if (!_bottomTipLable) { UILabel *lb = [[UILabel alloc] initWithFrame:CGRectMake(0, _scrollView.contentSize.height, self.frame.size.width,self.frame.size.height)]; lb.textAlignment = NSTextAlignmentCenter; lb.textColor = [UIColor grayColor]; lb.font = [UIFont systemFontOfSize:13]; lb.text = @"上拉加载更多数据"; [self addSubview:lb]; _bottomTipLable = lb; } return _bottomTipLable; } #pragma mark - 懒加载创建控件 - (UIActivityIndicatorView *)indicatorView { if (!_indicatorView) { UIActivityIndicatorView *act = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(50, _scrollView.contentSize.height, 30, self.frame.size.height)]; act.color = [UIColor grayColor]; [self addSubview:act]; _indicatorView = act; } return _indicatorView; } -(void)dealloc{ [_scrollView removeObserver:self forKeyPath:@"contentOffset"]; } @end
//使用
#import "VLoadMoreFootView.h" @property(nonatomic,strong) VLoadMoreFootView *vload; -(VLoadMoreFootView *)vload{ __weak typeof(self) weakSelf=self; if (!_vload) { _vload=[[VLoadMoreFootView alloc] initWithScrollView:weakSelf.tbView beginLoadMoreBlock:^(VLoadMoreFootView *vrefresh) { NSLog(@"进入上拉加载"); [self performSelector:@selector(endVload) withObject:nil afterDelay:3.0f]; }]; } return _vload; } -(void)endVload{ [_vload endLoadMore]; } [self vload];
//TKIMAlertView.h文件
// // TKIMAlertView.h // 泰隆微信 // 自定义alertview // Created by Vie on 2017/1/18. // Copyright © 2017年 liupm. All rights reserved. // #import <UIKit/UIKit.h> @interface TKIMAlertView : UIAlertView @property(nonatomic, assign) NSTextAlignment textAlignment;//文本对齐方式 @end
//TKIMAlertView.m文件
// // TKIMAlertView.m // 泰隆微信 // 自定义alertview // Created by Vie on 2017/1/18. // Copyright © 2017年 liupm. All rights reserved. // #import "TKIMAlertView.h" @implementation TKIMAlertView //iOS7以后获取alertview的subviews为空 -(void)show{ [super show]; float alertWith=268; float textLabelX=20; //文本占用空间 CGSize messageSize=[self.message boundingRectWithSize:CGSizeMake(alertWith-textLabelX-5, 500) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil].size; messageSize.height+=15; //文本 UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(textLabelX, 0, alertWith-textLabelX, messageSize.height)]; textLabel.font = [UIFont systemFontOfSize:15]; textLabel.textColor = [UIColor blackColor]; textLabel.backgroundColor = [UIColor clearColor]; textLabel.lineBreakMode =NSLineBreakByWordWrapping; textLabel.numberOfLines =0; textLabel.textAlignment =_textAlignment; textLabel.text =self.message; //文本背景视图 UIScrollView *view=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, alertWith, messageSize.height)]; view.contentSize=CGSizeMake(alertWith, messageSize.height); //指定控件是否只能在一个方向上滚动(默认为NO) view.directionalLockEnabled=YES; [view addSubview:textLabel]; [self setValue:view forKey:@"accessoryView"]; self.message=@""; } @end
//使用
TKIMAlertView *alert= [[TKIMAlertView alloc] initWithTitle:[NSString stringWithFormat:@"新版本升级 %@",self.versionModel.version] message:@"1.新版 2.修复Bug " delegate:self cancelButtonTitle:nil otherButtonTitles:@"升级", nil]; alert.textAlignment=NSTextAlignmentLeft; [alert show];
//ChoosePhotosCollectionViewCell.h文件
// // ChoosePhotosCollectionViewCell.h // CustomChoosePhotoDemo // 照片展示器单元格 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import <UIKit/UIKit.h> #import "ChoosePhotosBlock.h" @interface ChoosePhotosCollectionViewCell : UICollectionViewCell @property (strong, nonatomic)UIImageView * photoImageView;//展示缩略图 @property (nonatomic, assign) BOOL chooseFlag;//是否被选中,初始化为否 @property (nonatomic, copy) ChoosePhotosFlag chooseBlock; //未被选中 -(void)didUncheck; //被选中 -(void)didSelected; @end
//ChoosePhotosCollectionViewCell.m文件
// // ChoosePhotosCollectionViewCell.m // CustomChoosePhotoDemo // 照片展示器单元格 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import "ChoosePhotosCollectionViewCell.h" @interface ChoosePhotosCollectionViewCell () @property (strong, nonatomic) UIButton *chooseBtn;//选中按钮 @end @implementation ChoosePhotosCollectionViewCell #pragma mark 懒加载 -(UIImageView *)photoImageView{ if (!_photoImageView) { _photoImageView = [[UIImageView alloc]init]; _photoImageView.translatesAutoresizingMaskIntoConstraints = false; _photoImageView.contentMode = UIViewContentModeScaleAspectFill; _photoImageView.layer.masksToBounds = true; } return _photoImageView; } //显示选择按钮的视图 - (UIButton *)chooseBtn { if (_chooseBtn == nil) { _chooseBtn= [UIButton buttonWithType:UIButtonTypeCustom]; _chooseBtn.translatesAutoresizingMaskIntoConstraints = false; [_chooseBtn addTarget:self action:@selector(chooseAction:) forControlEvents:UIControlEventTouchUpInside]; _chooseBtn.translatesAutoresizingMaskIntoConstraints = false; [_chooseBtn setImage:[UIImage imageNamed:@"uncheck.png"] forState:UIControlStateNormal]; } return _chooseBtn; } #pragma mark 处理界面 -(instancetype)initWithFrame:(CGRect)frame{ self=[super initWithFrame:frame]; if (self) { [self loadView]; [self layoutVFL]; } return self; } /*加载视图*/ -(void)loadView{ [self addSubview:self.photoImageView]; [self addSubview:self.chooseBtn]; } /*VFL约束*/ -(void)layoutVFL{ /*photoImageView的约束*/ //水平约束 NSArray * photoImageViewHorizotal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_photoImageView]-0-|" options:0 metrics:nil views:@{@"_photoImageView":_photoImageView}]; [self addConstraints:photoImageViewHorizotal]; //垂直约束 NSArray * photoImageViewVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_photoImageView]-0-|" options:0 metrics:nil views:@{@"_photoImageView":_photoImageView}]; [self addConstraints:photoImageViewVertical]; NSArray * chooseBtnViewHorizotal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[_chooseBtn(22)]-5-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_chooseBtn)]; [self addConstraints:chooseBtnViewHorizotal]; NSArray * chooseBtnViewVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[_chooseBtn(22)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_chooseBtn)]; [self addConstraints:chooseBtnViewVertical]; } #pragma mark 事件处理 -(void)chooseAction:(UIButton *)sender{ if (self.chooseFlag) { [_chooseBtn setImage:[UIImage imageNamed:@"uncheck.png"] forState:UIControlStateNormal]; self.chooseFlag=false; }else{ [_chooseBtn setImage:[UIImage imageNamed:@"selected.png"] forState:UIControlStateNormal]; self.chooseFlag=true; } _chooseBlock(self.chooseFlag); } -(void)didUncheck{ [_chooseBtn setImage:[UIImage imageNamed:@"uncheck.png"] forState:UIControlStateNormal]; self.chooseFlag=false; } -(void)didSelected{ [_chooseBtn setImage:[UIImage imageNamed:@"selected.png"] forState:UIControlStateNormal]; self.chooseFlag=true; } @end
//ChoosePhotoGroupTableViewCell.h文件
// // ChoosePhotoGroupTableViewCell.h // CustomChoosePhotoDemo // 相册簿组群单元格 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import <UIKit/UIKit.h> #import <AssetsLibrary/AssetsLibrary.h> @interface ChoosePhotoGroupTableViewCell : UITableViewCell @property (nonatomic ,strong) ALAssetsGroup * group;//相册簿组群 @end
//ChoosePhotoGroupTableViewCell.m文件
// // ChoosePhotoGroupTableViewCell.m // CustomChoosePhotoDemo // 相册簿组群单元格 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import "ChoosePhotoGroupTableViewCell.h" @interface ChoosePhotoGroupTableViewCell() @property (nonatomic, strong) UIImageView *headImgView;//相册簿群组缩略图 @property (nonatomic, strong) UILabel *groupNameLable;//相册簿群组名称 @property (nonatomic, strong) UILabel *numberLable;//相册簿群组照片数量 @end @implementation ChoosePhotoGroupTableViewCell -(void)setGroup:(ALAssetsGroup *)group{ if (group) { //获得当前的预览图 CGImageRef imageRef = [group posterImage]; UIImage * image = [UIImage imageWithCGImage:imageRef]; self.headImgView.image=image; self.groupNameLable.text=NSLocalizedString([group valueForProperty:ALAssetsGroupPropertyName],@""); self.numberLable.text=[NSString stringWithFormat:@"%@",@([group numberOfAssets])]; } } #pragma mark 懒加载 -(UIImageView *)headImgView{ if (!_headImgView) { _headImgView=[[UIImageView alloc] init]; _headImgView.translatesAutoresizingMaskIntoConstraints=NO; } return _headImgView; } -(UILabel *)groupNameLable{ if (!_groupNameLable) { _groupNameLable=[[UILabel alloc] init]; _groupNameLable.translatesAutoresizingMaskIntoConstraints=NO; _groupNameLable.font=[UIFont systemFontOfSize:14]; } return _groupNameLable; } -(UILabel *)numberLable{ if (!_numberLable) { _numberLable=[[UILabel alloc] init]; _numberLable.translatesAutoresizingMaskIntoConstraints=NO; _numberLable.font=[UIFont systemFontOfSize:12]; } return _numberLable; } #pragma mark 视图处理 -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self loadView]; [self layoutVFL]; } return self; } /*加载视图*/ -(void)loadView{ [self addSubview:self.headImgView]; [self addSubview:self.groupNameLable]; [self addSubview:self.numberLable]; } /*VFL约束*/ -(void)layoutVFL{ //相册簿群组缩略图约束 /*Horizontal距离左边20*/ NSArray *headImgViewHorizotal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[_headImgView]" options:0 metrics:nil views:@{@"_headImgView":_headImgView}]; [self addConstraints:headImgViewHorizotal]; /*Vertical距离顶部和底部各10个距离等于设置了高度*/ NSArray *headImgViewVertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_headImgView]-10-|" options:0 metrics:nil views:@{@"_headImgView":_headImgView}]; [self addConstraints:headImgViewVertical]; /*设置headImgView宽等于高度*/ NSLayoutConstraint *headImgViewConstraint=[NSLayoutConstraint constraintWithItem:_headImgView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_headImgView attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; [self addConstraint:headImgViewConstraint]; //相册簿群组名称约束groupNameLable /*_groupNameLable距离左边_headImgView20个单位,距离右边20个距离,等于设置了宽度*/ NSArray *groupNameLableHorizontal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:[_headImgView]-20-[_groupNameLable]-20-|" options:0 metrics:nil views:@{@"_headImgView":_headImgView,@"_groupNameLable":_groupNameLable}]; [self addConstraints:groupNameLableHorizontal]; /*_groupNameLable距离顶部10个单位,高度为21*/ NSArray *groupNameLableVertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_groupNameLable(21)]" options:0 metrics:nil views:@{@"_groupNameLable":_groupNameLable}]; [self addConstraints:groupNameLableVertical]; //相册簿群组照片数量约束 /*_numberLable左边距离_headImgView20个距离,距离右边20个距离,等于设置了宽度*/ NSArray *numberLableHorizontal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:[_headImgView]-20-[_numberLable]-20-|" options:0 metrics:nil views:@{@"_headImgView":_headImgView,@"_numberLable":_numberLable}]; [self addConstraints:numberLableHorizontal]; /*_numberLable顶部距离_groupNameLable有0个距离,高度15*/ NSArray *numberLableVertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_groupNameLable]-0-[_numberLable(15)]" options:0 metrics:nil views:@{@"_groupNameLable":_groupNameLable,@"_numberLable":_numberLable}]; [self addConstraints:numberLableVertical]; } - (void)awakeFromNib { [super awakeFromNib]; // Initialization code } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } @end
//ChoosePhotosBlock.h文件
// // ChoosePhotosBlock.h // CustomChoosePhotoDemo // block定义 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #ifndef ChoosePhotosBlock_h #define ChoosePhotosBlock_h typedef void(^ChoosePhotosFlag)(BOOL flag) ;//是否选中状态回调 typedef void(^ReturnImagesArray)(NSArray<UIImage *>* choosedImages);//选中照片返回 #endif /* ChoosePhotosBlock_h */
//BrowseChooseImgViewController.h文件
// // BrowseChooseImgViewController.h // CustomChoosePhotoDemo // 浏览点击的图片 // Created by Vie on 2017/2/16. // Copyright © 2017年 Vie. All rights reserved. // #import <UIKit/UIKit.h> @interface BrowseChooseImgViewController : UIViewController @property (nonatomic, strong) UIImageView * tempImgView;//显示一个当前点击的图 @end
//BrowseChooseImgViewController.m文件
// // BrowseChooseImgViewController.m // CustomChoosePhotoDemo // 浏览点击的图片 // Created by Vie on 2017/2/16. // Copyright © 2017年 Vie. All rights reserved. // #import "BrowseChooseImgViewController.h" @interface BrowseChooseImgViewController () @end @implementation BrowseChooseImgViewController -(instancetype)init{ self=[super init]; if (self) { [self.view addSubview:self.tempImgView]; [self layoutVFL]; } return self; } #pragma mark 懒加载 -(UIImageView *)tempImgView{ if (!_tempImgView) { _tempImgView = [[UIImageView alloc] init]; _tempImgView.contentMode = UIViewContentModeScaleAspectFit; _tempImgView.backgroundColor = [UIColor blackColor]; _tempImgView.translatesAutoresizingMaskIntoConstraints=NO; } return _tempImgView; } #pragma mark 界面处理 - (void)viewDidLoad { [super viewDidLoad]; } -(void)layoutVFL{ /*tableview水平方法距离两边各0距离等于设了x值和宽度*/ NSArray *tableViewHorizontal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_tempImgView]-0-|" options:0 metrics:nil views:@{@"_tempImgView":_tempImgView}]; [self.view addConstraints:tableViewHorizontal]; /*tableview垂直方向距离两边各0距离等于设置了y值和高度*/ NSArray *tableViewVertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_tempImgView]-0-|" options:0 metrics:nil views:@{@"_tempImgView":_tempImgView}]; [self.view addConstraints:tableViewVertical]; } @end
//ChoosePhotosCollectionViewController.h文件
// // ChoosePhotosCollectionViewController.h // CustomChoosePhotoDemo // 照片展示器 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import <UIKit/UIKit.h> #import <AssetsLibrary/AssetsLibrary.h> #import "ChoosePhotosBlock.h" @interface ChoosePhotosCollectionViewController : UIViewController @property (nonatomic, strong) NSMutableArray <ALAsset *> * photos;//存储ALAsset对象的数组 @property (nonatomic, copy) ReturnImagesArray returnImagesArray;//确认选中照片回调 @end
//ChoosePhotosCollectionViewController.m文件
// // ChoosePhotosCollectionViewController.m // CustomChoosePhotoDemo // 照片展示器 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import "ChoosePhotosCollectionViewController.h" #import "ChoosePhotosCollectionViewCell.h" #import "BrowseChooseImgViewController.h" @interface ChoosePhotosCollectionViewController ()<UICollectionViewDelegate,UICollectionViewDataSource> @property (nonatomic, strong) UICollectionView *collectionView; @property (nonatomic, assign) CGFloat cellLength; //标准大小 @property (nonatomic, strong) NSMutableArray<UIImage *> *choosedImages;//存放选中的图片对象 @property (nonatomic, strong) NSMutableArray<NSNumber *> *imagesFlag;//所以图片的标志位,记录是否被选中,避免在cell记录导致重用错乱问题 @property (nonatomic, strong) NSMutableArray<UIImage *> *allImages;//全部图片 @end @implementation ChoosePhotosCollectionViewController -(void)setPhotos:(NSMutableArray<ALAsset *> *)photos{ if (photos) { _photos=photos; [self loadImagesFlag:_photos.count]; [self loadAllImages]; [self.collectionView reloadData]; } } /*初始化标识为计数数组*/ -(void)loadImagesFlag:(NSInteger)count{ self.imagesFlag=[[NSMutableArray alloc] init]; for (int i=0; i<count; i++) { [self.imagesFlag addObject:[NSNumber numberWithBool:false]]; } } /*加载所有的图片对象*/ - (void)loadAllImages { self.allImages=[[NSMutableArray alloc] init]; //进行资源处理 for (ALAsset * asset in self.photos) { //这里就不要用thumbnail属性了,太模糊 [self.allImages addObject:[UIImage imageWithCGImage:asset.aspectRatioThumbnail]]; } } #pragma mark 懒加载 -(UICollectionView *)collectionView{ if (!_collectionView) { UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init]; _collectionView= [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout]; _collectionView.translatesAutoresizingMaskIntoConstraints=NO; _collectionView.dataSource=self; _collectionView.delegate=self; //注册单元格使用的类型,必须先注册,否则会报异常 [_collectionView registerClass:[ChoosePhotosCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([ChoosePhotosCollectionViewCell class])]; //注册头 [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"]; //注册脚 [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer"]; } return _collectionView; } -(NSMutableArray<UIImage *> *)choosedImages{ if (!_choosedImages) { _choosedImages=[[NSMutableArray alloc] init]; } return _choosedImages; } #pragma mark 视图处理 - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"选择" style:UIBarButtonItemStylePlain target:self action:@selector(endChooseReturnArray)]; //初始化数据,适配横屏 CGFloat minLength = MIN(self.view.bounds.size.width, self.view.bounds.size.height); self.cellLength = (minLength - 3) / 4.0f; [self.view addSubview:self.collectionView]; [self layoutVFL]; } /*使用VIF设置界面自动布局*/ -(void)layoutVFL{ /*tableview水平方法距离两边各0距离等于设了x值和宽度*/ NSArray *tableViewHorizontal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_collectionView]-0-|" options:0 metrics:nil views:@{@"_collectionView":_collectionView}]; [self.view addConstraints:tableViewHorizontal]; /*tableview垂直方向距离两边各0距离等于设置了y值和高度*/ NSArray *tableViewVertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_collectionView]-0-|" options:0 metrics:nil views:@{@"_collectionView":_collectionView}]; [self.view addConstraints:tableViewVertical]; } #pragma mark UICollectionViewDelegate /*设置分区*/ -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ return 1; } /*设置分区内单元格数*/ -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return self.photos.count; } /*设置每个分区的边距*/ -(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{ return UIEdgeInsetsMake(0, 0, 0, 0); } /*item垂直间距*/ - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { return 1; } /*item水平间距*/ - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { return 1; } /*设置每个item大小*/ -(CGSize)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(nonnull NSIndexPath *)indexPath{ return CGSizeMake(self.cellLength, self.cellLength); } /*设置item*/ -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath{ //设置的单元格要与Identifier注册的一致 ChoosePhotosCollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([ChoosePhotosCollectionViewCell class]) forIndexPath:indexPath]; //检查cell是否被选中 [self cellIsSelect:cell flag:self.imagesFlag[indexPath.row].boolValue]; cell.chooseBlock=^(BOOL flag){ //记录选中图片状态 [self.imagesFlag replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:flag]]; if (flag) { NSLog(@"***********选中第%ld张图片",indexPath.row+1); //添加选中图片 [self.choosedImages addObject:self.allImages[indexPath.item]]; }else{ NSLog(@"***********取消第%ld张图片",indexPath.row+1); //移除选中图片 [self.choosedImages removeObject:self.allImages[indexPath.item]]; } }; //这里尽量不用thumbnail属性,因为太模糊了,可以用aspectRatioThumbnail比例缩略图代替 cell.photoImageView.image = [UIImage imageWithCGImage:self.photos[indexPath.row].aspectRatioThumbnail]; return cell; } /*点击item*/ -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ //获取当前的资源对象 ALAsset * asset = self.photos[indexPath.item]; //创建浏览控制器 BrowseChooseImgViewController * ctr = [[BrowseChooseImgViewController alloc] init]; UIImage *image=[UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage]; //设置大图 ctr.tempImgView.image = [UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage]; //弹出 [self.navigationController pushViewController:ctr animated:true]; } #pragma mark 事件处理 /*检查item是否被点击过*/ -(void)cellIsSelect:(ChoosePhotosCollectionViewCell *)cell flag:(BOOL)flag{ if (flag) { [cell didSelected]; }else{ [cell didUncheck]; } } /*选取照片完成*/ -(void)endChooseReturnArray{ _returnImagesArray(self.choosedImages); //向前返回2个页面,返回到直接选择照片的页面 [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:([self.navigationController.viewControllers count]-3)] animated:YES]; } @end
//ChoosePhotoGroupViewController.h文件
// // ChoosePhotoGroupViewController.h // CustomChoosePhotoDemo // 相册薄组群展示器 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import <UIKit/UIKit.h> #import "ChoosePhotosBlock.h" @interface ChoosePhotoGroupViewController : UIViewController @property (nonatomic, copy) ReturnImagesArray returnImagesArray;//确认选中照片回调 @end
//ChoosePhotoGroupViewController.m文件
// // ChoosePhotoGroupViewController.m // CustomChoosePhotoDemo // 相册薄组群展示器 // Created by Vie on 2017/2/15. // Copyright © 2017年 Vie. All rights reserved. // #import "ChoosePhotoGroupViewController.h" #import <AssetsLibrary/AssetsLibrary.h> #import "ChoosePhotoGroupTableViewCell.h" #import "ChoosePhotosCollectionViewController.h" @interface ChoosePhotoGroupViewController ()<UITableViewDelegate,UITableViewDataSource> @property (nonatomic, strong) ALAssetsLibrary *assetsLibrary;//访问控制的视频和照片的照片实例 @property (nonatomic, strong) NSMutableArray <ALAssetsGroup *> *photoAlbumGroups;//存放相册簿组群的数组对象 @property (nonatomic, strong) UITableView *tableView;//表格视图 @end @implementation ChoosePhotoGroupViewController #pragma mark 懒加载 -(ALAssetsLibrary *)assetsLibrary{ if (!_assetsLibrary) { _assetsLibrary=[[ALAssetsLibrary alloc] init]; } return _assetsLibrary; } -(NSMutableArray<ALAssetsGroup *>*)photoAlbumGroups{ if (!_photoAlbumGroups) { _photoAlbumGroups=[[NSMutableArray alloc] init]; [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) { //如果返回的组群存在,分次返回,所以在这里收到数据时候重载画面 if (group) { //对group进行过滤只要照片 [group setAssetsFilter:[ALAssetsFilter allPhotos]]; [_photoAlbumGroups addObject:group]; } /*获得相册簿群组后重载数据*/ [self.tableView reloadData]; } failureBlock:^(NSError *error) { NSLog(@"获得相册簿组群失败"); }]; } return _photoAlbumGroups; } -(UITableView *)tableView{ if (!_tableView) { _tableView=[[UITableView alloc] init]; _tableView.delegate=self; _tableView.dataSource=self; /*禁用autoresizing*/ _tableView.translatesAutoresizingMaskIntoConstraints=NO; } return _tableView; } #pragma mark 界面处理 - (void)viewDidLoad { [super viewDidLoad]; /*要在加载到父视图上后设置VFL才有参照系*/ [self.view addSubview:self.tableView]; [self layoutVFL]; } /*使用VIF设置界面自动布局*/ -(void)layoutVFL{ /*tableview水平方法距离两边各0距离等于设了x值和宽度*/ NSArray *tableViewHorizontal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_tableView]-0-|" options:0 metrics:nil views:@{@"_tableView":_tableView}]; [self.view addConstraints:tableViewHorizontal]; /*tableview垂直方向距离两边各0距离等于设置了y值和高度*/ NSArray *tableViewVertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_tableView]-0-|" options:0 metrics:nil views:@{@"_tableView":_tableView}]; [self.view addConstraints:tableViewVertical]; } #pragma mark UITableViewDelegate /*设置每个分区多少行*/ -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.photoAlbumGroups.count; } /*设置分区*/ -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } /*单元格选中事件*/ -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ ChoosePhotosCollectionViewController *collectionCtr=[[ChoosePhotosCollectionViewController alloc] init]; collectionCtr.returnImagesArray=^(NSArray<UIImage *>* choosedImages){ NSLog(@"*******共选中%ld张图片",choosedImages.count); _returnImagesArray(choosedImages); }; [self.navigationController pushViewController:collectionCtr animated:YES]; NSMutableArray *photos=[[NSMutableArray alloc] init]; //获取group模型 ALAssetsGroup *group = self.photoAlbumGroups[indexPath.row]; dispatch_async(dispatch_get_main_queue(), ^{ //开始读取 [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { //如果不为空或者媒体为图片 if (result != nil && [[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) { //添加数据 [photos addObject:result]; //数目达标后统一进行赋值 if (index == group.numberOfAssets - 1) { collectionCtr.photos=photos; } } }]; }); } /*设置单元格*/ -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ ChoosePhotoGroupTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"%ld",indexPath.row]]; if (!cell) { cell=[[ChoosePhotoGroupTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:@"%ld",indexPath.row]]; } //获得当前的数据 ALAssetsGroup * group = self.photoAlbumGroups[indexPath.row]; cell.group=group; return cell; } /*设置单元格高度*/ -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 80; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
//图片资源
//使用
#import "ChoosePhotoGroupViewController.h" #import "ChoosePhotosBlock.h" /*加载照片群组控制器*/ ChoosePhotoGroupViewController *photoCtr=[[ChoosePhotoGroupViewController alloc] init]; photoCtr.returnImagesArray=^(NSArray<UIImage *>* choosedImages){ NSLog(@"***********一共选中%ld张图片",choosedImages.count); }; [self.navigationController pushViewController:photoCtr animated:YES];
//效果展示