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
时间: 2024-11-11 18:19:06

ios 仿android gallery控件的相关文章

Android UI设计——Gallery控件

?Gallery Gallery完结的功用是将闪现的内容支配滑动.举例来说,有时我们下载一个APP运用的时分,会在运用商场中查看他的特性和界面,我们查看的内容通过支配滑动的方法来展示,这正本即是以Gallery控件来完结的. Gallery的完结也需求运用Adapter.首先我们来看一下Gallery的几个常用特色: spacing特色:支配两个Item脱离多少距离: unselectAlpha特色:设置透明度:当在基地的Item获取到焦点时,将不会闪现闪现透明度的特色. Gallery的监听通

自定义Gallery控件实现简单3D图片浏览器

本篇文章主要介绍如何使用自定义的Gallery控件,实现3D效果的图片浏览器的效果. 话不多说,先看效果. 上面是一个自定义的Gallery控件,实现倒影和仿3D的效果,下面是一个图片查看器,点击上面的小图片,可以在下面查看大图片. 下面重点说一下,实现图片查看器的思路. 1.手机中图片路径的获取 首先,先不管图片如何展示,如果我们想实现图片查看器的功能,我们首先需要做的是获取到所有的图片的路径信息,只有这样,我们才能实现对图片的查看. 我们可以使用下面的代码实现 private List<St

Android基础控件使用汇总

平时写代码总会遇到一些问题,准备写一个比较基础的控件使用汇总系列!本系列持续不定期更新,希望能够帮到需要的朋友!get! Android基础控件使用细节--TextView Android基础控件使用细节--Button Android基础控件使用细节--EditText Android基础控件使用细节--ImageView Android基础控件使用细节--WebView Android基础控件使用细节--ListView Android基础控件使用细节--Menu Android基础控件使用

Android常用控件:进度条

各种进度条属于 ProgressBar的子类 Sytle: 水平风格:Horizontal小风格:Small大风格:Large反向风格:Inverse小反向风格:Small.Inverse大反向风格:Large.Inverse 设置style:   style="?android:attr/progressBarStyle..." 主要属性:最大值:max当前进度:progress次要进度值:SecondaryProgress --效果类似于看电影那些缓冲 判断进度条是转圈还是水平的方

ArcGIS for Android地图控件的5大常见操作

原文地址: ArcGIS for Android地图控件的5大常见操作 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/arcgis_mobile/article/details/7801467   GIS的开发中,什么时候都少不了地图操作.ArcGIS for Android中,地图组件就是MapView,MapView是基于Android中ViewGroup的一个类(参考),也是ArcGIS Runtime SDK for

Android 标签控件

版本:1.0 日期:2014.7.24 版权:© 2014 kince 转载注明出处 在有的应用中可能需要设置一些标签来方便用去去查询某些信息,比如手机助手或者购物软件之类都会有一些标签.对于软件开发初期来说,直接使用TextView.Button实现是最为简单的一种方式.但是这种方法也有其局限性,比如不能控制换行.耦合性低等缺点.所以除了解决这些问题之外,最好能够封装一个类库出来,方便以后使用. 首先新建一个Tag类, import java.io.Serializable; public c

[Android]界面控件

1. 引用系统自带样式 字体大小 对于能够显示文字的控件(如TextView EditText RadioButton Button CheckBox Chronometer等等),你有时需要控制字体的大小.Android平台定义了三种字体大小. "?android:attr/textAppearanceLarge" "?android:attr/textAppearanceMedium" "?android:attr/textAppearanceSmal

WinForm 仿360界面控件

因为经常要做一些1.2千行的小工具,WinForm自带的TabCtrl又不美观,所以想做成360的样子,在网上找来找去,都只有散乱的代码,没有可以通用的结构,所以自己写了一个简易的通用控件. 控件主要功能 添加按钮和对应的Userctrl页面,或者相应的Action函数:整个控件是透明背景,窗体的背景将被作为整体背景,即支持类似换肤功能:可自定义按钮的遮罩函数. 支持Userctrl页面切换 支持Action(无参数无返回值)委托 主要类型实现 切换按钮派生自RatioButton,因为已经实现

IOS开发自定义CheckBox控件

IOS本身没有系统的CheckBox组件,但是实际开发中会经常用到,所以专门写了一个CheckBox控件,直接上代码 效果图: UICheckBoxButton.h文件如下: #import #import "Common.h" @interface UICheckBoxButton : UIControl { UILabel *label; UIImageView *icon; BOOL checked; id delegate; } @property (retain, nonat