zoukankan      html  css  js  c++  java
  • iOS,自定义控件

    1.下拉刷新控件

    2.上拉加载更多控件

    3.自定义UIAlertView

    4.自定义照片选择器(可多选)

    下拉刷新控件

     //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];

     自定义UIAlertView

    //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];

    //效果展示

  • 相关阅读:
    Mysql与Sql Server查询数据库中表以及表字段
    linux系统常用命令
    linux tomcat安装以及配置
    mysql 5.7 设置root远程访问
    linux jdk安装
    ubuntu系统阅读CHM文档的最终解决方案
    ubuntu18.04完全卸载mysql的命令
    linux下使用cd命令进入wine容器中的windows路径
    Python中yield关键字的用法及运行逻辑
    Ubuntu18..04.2服务器版设置redis开机启动遇到的问题
  • 原文地址:https://www.cnblogs.com/douniwanxia/p/5969808.html
Copyright © 2011-2022 走看看