zoukankan      html  css  js  c++  java
  • ios 仿android gallery控件

    ios 上没有发现与android gallery类似的控件,因为在项目上须要使用到.採用UICollectionView实现



    ViewController.m

    #import "ViewController.h"
    #import "ImageCell.h"
    #import "LineLayout.h"
    
    @interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
    @property (nonatomic, strong) NSMutableArray *images;
    @property (nonatomic, weak) UICollectionView *collectionView;
    @end
    
    @implementation ViewController
    
    static NSString *const ID = @"image";
    
    - (NSMutableArray *)images
    {
        if (!_images) {
            self.images = [[NSMutableArray alloc] init];
            
            for (int i = 1; i<=20; i++) {
                [self.images addObject:[NSString stringWithFormat:@"%d", i]];
            }
        }
        return _images;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        CGFloat w = self.view.frame.size.width;
        CGRect rect = CGRectMake(0, 100, w, 200);
        UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:[[LineLayout alloc] init]];
        collectionView.dataSource = self;
        collectionView.delegate = self;
        [collectionView registerNib:[UINib nibWithNibName:@"ImageCell" bundle:nil] forCellWithReuseIdentifier:ID];
        [self.view addSubview:collectionView];
        self.collectionView = collectionView;
        // collectionViewLayout :
        // UICollectionViewLayout
        // UICollectionViewFlowLayout
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        if ([self.collectionView.collectionViewLayout isKindOfClass:[LineLayout class]]) {
            [self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES];
        } else {
            [self.collectionView setCollectionViewLayout:[[LineLayout alloc] init] animated:YES];
        }
    }
    
    #pragma mark - <UICollectionViewDataSource>
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
        return self.images.count;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
        cell.image = self.images[indexPath.item];
        return cell;
    }
    
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
        // 删除模型数据
        [self.images removeObjectAtIndex:indexPath.item];
        
        // 删UI(刷新UI)
        [collectionView deleteItemsAtIndexPaths:@[indexPath]];
    }
    
    @end
    

    LineLayout.m

    #import "LineLayout.h"
    
    static const CGFloat ItemWH = 100;
    
    @implementation LineLayout
    
    - (instancetype)init
    {
        if (self = [super init]) {
        }
        return self;
    }
    
    /**
     *  仅仅要显示的边界发生改变就又一次布局:
     内部会又一次调用prepareLayout和layoutAttributesForElementsInRect方法获得全部cell的布局属性
     */
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    {
        return YES;
    }
    
    /**
     *  用来设置collectionView停止滚动那一刻的位置
     *
     *  @param proposedContentOffset 原本collectionView停止滚动那一刻的位置
     *  @param velocity              滚动速度
     */
    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
    {
        // 1.计算出scrollView最后会停留的范围
        CGRect lastRect;
        lastRect.origin = proposedContentOffset;
        lastRect.size = self.collectionView.frame.size;
        
        // 计算屏幕最中间的x
        CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
        
        // 2.取出这个范围内的全部属性
        NSArray *array = [self layoutAttributesForElementsInRect:lastRect];
        
        // 3.遍历全部属性
        CGFloat adjustOffsetX = MAXFLOAT;
        for (UICollectionViewLayoutAttributes *attrs in array) {
            if (ABS(attrs.center.x - centerX) < ABS(adjustOffsetX)) {
                adjustOffsetX = attrs.center.x - centerX;
            }
        }
        
        return CGPointMake(proposedContentOffset.x + adjustOffsetX, proposedContentOffset.y);
    }
    
    /**
     *  一些初始化工作最好在这里实现
     */
    - (void)prepareLayout
    {
        [super prepareLayout]; 
        
        // 每个cell的尺寸
        self.itemSize = CGSizeMake(ItemWH, ItemWH);
        CGFloat inset = (self.collectionView.frame.size.width - HMItemWH) * 0.5;
        self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
        // 设置水平滚动
        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        self.minimumLineSpacing = ItemWH * 0.7;
        
        // 每个cell(item)都有自己的UICollectionViewLayoutAttributes
        // 每个indexPath都有自己的UICollectionViewLayoutAttributes
    }
    
    /** 有效距离:当item的中间x距离屏幕的中间x在HMActiveDistance以内,才会開始放大, 其他情况都是缩小 */
    static CGFloat const ActiveDistance = 150;
    /** 缩放因素: 值越大, item就会越大 */
    static CGFloat const ScaleFactor = 0.6;
    
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        // 0.计算可见的矩形框
        CGRect visiableRect;
        visiableRect.size = self.collectionView.frame.size;
        visiableRect.origin = self.collectionView.contentOffset;
        
        // 1.取得默认的cell的UICollectionViewLayoutAttributes
        NSArray *array = [super layoutAttributesForElementsInRect:rect];
        // 计算屏幕最中间的x
        CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
        
        // 2.遍历全部的布局属性
        for (UICollectionViewLayoutAttributes *attrs in array) {
            // 假设不在屏幕上,直接跳过
            if (!CGRectIntersectsRect(visiableRect, attrs.frame)) continue;
            
            // 每个item的中点x
            CGFloat itemCenterX = attrs.center.x;
            
            // 差距越小, 缩放比例越大
            // 依据跟屏幕最中间的距离计算缩放比例
            CGFloat scale = 1 + ScaleFactor * (1 - (ABS(itemCenterX - centerX) / ActiveDistance));
            attrs.transform = CGAffineTransformMakeScale(scale, scale);
        }
        
        return array;
    }
    
    @end
    

    ImageCell.m

    #import "ImageCell.h"
    
    @interface ImageCell()
    @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    @end
    
    @implementation ImageCell
    
    - (void)awakeFromNib {
        self.imageView.layer.borderWidth = 3;
        self.imageView.layer.borderColor = [UIColor whiteColor].CGColor;
        self.imageView.layer.cornerRadius = 3;
        self.imageView.clipsToBounds = YES;
    }
    
    - (void)setImage:(NSString *)image
    {
        _image = [image copy];
        
        self.imageView.image = [UIImage imageNamed:image];
    }
    
    @end
    


  • 相关阅读:
    Android开发环境搭建全程演示(jdk+eclip+android sdk)
    mysql UDF接口 网络编程(代码改进版非阻塞,超时重传)
    HTTP_POST———使用mysql_udf与curl库完成http_post通信模块(mysql_udf,multi_curl,http,post)
    Linux自动更新时间
    CentOS下设置Mysql的root密码
    CentOS yum安装LAMP环境
    Nagios远程监控软件的安装与配置详解
    Android开发之旅:环境搭建及HelloWorld
    CentOS 6.3安装配置LAMP服务器(Apache+PHP5+MySQL)
    c#,winform,show,showdialog,子窗体,父窗体,传值,输入正确
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7118090.html
Copyright © 2011-2022 走看看