IOS开发--横向流水布局实现

简介:
//
//  ViewController.m
//  自定义流水布局
//
//  Created by xmg on 16/1/15.
//  Copyright © 2016年 HeYang. All rights reserved.
//

#import "ViewController.h"
#import "PhotoCell.h"
#import "PhotoLayout.h"

/*
 // a , b , c a = b + c
 //    int d = (2,3,5);
 
 // 高聚合,低耦合
 int a = ({
 int b = 2;
 int c = 3;
 a = b + c;
 20;
 });
 */

/*
 UICollectionView注意点:
 1.初始化必须要传入布局,(流水布局:九宫格布局)
 2.UICollectionViewCell必须要注册
 3.必须自定义cell
 */


#define XMGScreenW [UIScreen mainScreen].bounds.size.width
static NSString * const ID = @"cell";
@interface ViewController ()<UICollectionViewDataSource>

@end

@implementation ViewController

// 思路:照片浏览布局:流水布局,在拖到的时候,在原来基础上重新计算下布局 -> 在原来功能上再添加功能,自定义流水布局
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 创建流水布局
    PhotoLayout *layout = ({
        layout = [[PhotoLayout alloc] init];
        // 尺寸
        layout.itemSize = CGSizeMake(180, 180);
        // 设置滚动方向:水平
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        // 设置额外滚动区域
        CGFloat inset = (XMGScreenW - 180) * 0.5;
        layout.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
        
        layout;
    });
    
    // 创建UICollectionView:默认为黑色
    UICollectionView *collectionView = ({
        collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
        collectionView.bounds = CGRectMake(0, 0, self.view.bounds.size.width, 200);
        collectionView.center = self.view.center;
        collectionView.backgroundColor = [UIColor cyanColor];
        collectionView.showsHorizontalScrollIndicator = NO;
        [self.view addSubview:collectionView];
        
        // 设置数据源
        collectionView.dataSource = self;
        collectionView;
    });
    
    // 注册cell
    [collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([PhotoCell class]) bundle:nil] forCellWithReuseIdentifier:ID];
}


#pragma mark -UICollectionViewDataSource
// 返回有多少个cell
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 20;
}

// 返回每个cell长什么样
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    
    PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
    
    NSString *imageName = [NSString stringWithFormat:@"%ld",indexPath.row + 1];
    
    cell.image = [UIImage imageNamed:imageName];
    
    return cell;
}

@end


前言:因为时间缘故,很少进行通俗易懂的算法思路讲解,这里先展示动态图片效果,然后后面的内容我就直接上关键源码了。

效果展示图;

源码百度云盘下载链接: http://pan.baidu.com/s/1eQOOixc 密码: duu8

源码:



//  PhotoCell.h
//  自定义流水布局
//
//  Created by xmg on 16/1/15.
//  Copyright © 2016年 HeYang. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface PhotoCell : UICollectionViewCell

@property (nonatomic, strong) UIImage *image;

@end

================两个文件的分水岭==================
//
//  PhotoCell.m
//  自定义流水布局
//
//  Created by xmg on 16/1/15.
//  Copyright © 2016年 HeYang. All rights reserved.
//

26 
#import "PhotoCell.h"

@interface PhotoCell ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end

@implementation PhotoCell

- (void)awakeFromNib {
    // Initialization code
}

- (void)setImage:(UIImage *)image
{
    _image = image;
    
    _imageView.image = image;
    
}

@end


//
//  PhotoLayout.h
//  自定义流水布局
//
//  Created by xmg on 16/1/15.
//  Copyright © 2016年 HeYang. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface PhotoLayout : UICollectionViewFlowLayout

@end


==============两个文件的分水岭================

//
//  PhotoLayout.m
//  自定义流水布局
//
//  Created by xmg on 16/1/15.
//  Copyright © 2016年 HeYang. All rights reserved.
//

#import "PhotoLayout.h"
#define XMGScreenW [UIScreen mainScreen].bounds.size.width
@implementation PhotoLayout

// 复杂效果: 分析 ->
// cell离中心点距离越近(delta越小),就越大,越远,就越小
// 距离中心点
// 知道哪些cell需要缩放:显示出来的cell才需要进行布局



// 给定一个区域,就返回这个区域内所有cell布局
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // 1.获取显示区域,bounds 而不是整个滚动区域,这样设置的子控件就控制在显示区域范围内了。
    CGRect visiableRect = self.collectionView.bounds;

    // 2.获取显示区域内的cell的布局
    NSArray *attributes = [super layoutAttributesForElementsInRect:visiableRect];
    
    
    
    // 3.遍历cell布局
    CGFloat offsetX = self.collectionView.contentOffset.x;
    for (UICollectionViewLayoutAttributes *attr in attributes) {
        // 3.1 计算下距离中心点距离
        CGFloat delta = fabs(attr.center.x - offsetX - XMGScreenW * 0.5);
        // 1 ~ 0.75
        CGFloat scale = 1 - delta / (XMGScreenW * 0.5) * 0.25;//1-(0~0.5) = 1~0.5 --> 1-(0~0.5)×0.25 = (1~0.75)
        attr.transform = CGAffineTransformMakeScale(scale, scale);
    }
    
    return attributes;
}

// Invalidate:刷新
// 是否允许在拖动的时候刷新布局
// 谨慎使用,YES:只要一滚动就会布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}


最后的关键代码:



//
//  ViewController.m
//  自定义流水布局
//
//  Created by xmg on 16/1/15.
//  Copyright © 2016年 HeYang. All rights reserved.
//

#import "ViewController.h"
#import "PhotoCell.h"
#import "PhotoLayout.h"

/*
 // a , b , c a = b + c
 //    int d = (2,3,5);
 
 // 高聚合,低耦合
 int a = ({
 int b = 2;
 int c = 3;
 a = b + c;
 20;
 });
 */

/*
 UICollectionView注意点:
 1.初始化必须要传入布局,(流水布局:九宫格布局)
 2.UICollectionViewCell必须要注册
 3.必须自定义cell
 */


#define XMGScreenW [UIScreen mainScreen].bounds.size.width
static NSString * const ID = @"cell";
@interface ViewController ()<UICollectionViewDataSource>

@end

@implementation ViewController

// 思路:照片浏览布局:流水布局,在拖到的时候,在原来基础上重新计算下布局 -> 在原来功能上再添加功能,自定义流水布局
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 创建流水布局
    PhotoLayout *layout = ({
        layout = [[PhotoLayout alloc] init];
        // 尺寸
        layout.itemSize = CGSizeMake(180, 180);
        // 设置滚动方向:水平
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        // 设置额外滚动区域
        CGFloat inset = (XMGScreenW - 180) * 0.5;
        layout.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
        
        layout;
    });
    
    // 创建UICollectionView:默认为黑色
    UICollectionView *collectionView = ({
        collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
        collectionView.bounds = CGRectMake(0, 0, self.view.bounds.size.width, 200);
        collectionView.center = self.view.center;
        collectionView.backgroundColor = [UIColor cyanColor];
        collectionView.showsHorizontalScrollIndicator = NO;
        [self.view addSubview:collectionView];
        
        // 设置数据源
        collectionView.dataSource = self;
        collectionView;
    });
    
    // 注册cell
    [collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([PhotoCell class]) bundle:nil] forCellWithReuseIdentifier:ID];
}


#pragma mark -UICollectionViewDataSource
// 返回有多少个cell
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 20;
}

// 返回每个cell长什么样
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    
    PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
    
    NSString *imageName = [NSString stringWithFormat:@"%ld",indexPath.row + 1];
    
    cell.image = [UIImage imageNamed:imageName];
    
    return cell;
}

@end


相关文章
|
7天前
|
安全 数据处理 Swift
深入探索iOS开发中的Swift语言特性
本文旨在为开发者提供对Swift语言在iOS平台开发的深度理解,涵盖从基础语法到高级特性的全面分析。通过具体案例和代码示例,揭示Swift如何简化编程过程、提高代码效率,并促进iOS应用的创新。文章不仅适合初学者作为入门指南,也适合有经验的开发者深化对Swift语言的认识。
25 9
|
7天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
5天前
|
iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第39天】在苹果的生态系统中,SwiftUI框架以其声明式语法和易用性成为开发者的新宠。本文将深入SwiftUI的核心概念,通过实际案例展示如何利用这一框架快速构建用户界面,并探讨其对iOS应用开发流程的影响。
|
8天前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
13天前
|
设计模式 前端开发 Swift
探索iOS开发:从初级到高级的旅程
【10月更文挑战第31天】在这篇文章中,我们将一起踏上iOS开发的旅程。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。我们将从基础开始,逐步深入到更高级的技术和概念。让我们一起探索iOS开发的世界吧!
|
15天前
|
设计模式 前端开发 Swift
探索iOS开发:从初级到高级的旅程
【10月更文挑战第28天】在这篇技术性文章中,我们将一起踏上一段探索iOS开发的旅程。无论你是刚入门的新手,还是希望提升技能的开发者,这篇文章都将为你提供宝贵的指导和灵感。我们将从基础概念开始,逐步深入到高级主题,如设计模式、性能优化等。通过阅读这篇文章,你将获得一个清晰的学习路径,帮助你在iOS开发领域不断成长。
47 2
|
21天前
|
安全 API Swift
探索iOS开发中的Swift语言之美
【10月更文挑战第23天】在数字时代的浪潮中,iOS开发如同一艘航船,而Swift语言则是推动这艘船前进的风帆。本文将带你领略Swift的独特魅力,从语法到设计哲学,再到实际应用案例,我们将一步步深入这个现代编程语言的世界。你将发现,Swift不仅仅是一种编程语言,它是苹果生态系统中的一个创新工具,它让iOS开发变得更加高效、安全和有趣。让我们一起启航,探索Swift的奥秘,感受编程的乐趣。
|
23天前
|
Swift iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】在苹果生态系统中,SwiftUI的引入无疑为iOS应用开发带来了革命性的变化。本文将通过深入浅出的方式,带领读者了解SwiftUI的基本概念、核心优势以及如何在实际项目中运用这一框架。我们将从一个简单的例子开始,逐步深入到更复杂的应用场景,让初学者能够快速上手,同时也为有经验的开发者提供一些深度使用的技巧和策略。
45 1
|
11天前
|
存储 数据可视化 Swift
探索iOS开发之旅:从新手到专家
【10月更文挑战第33天】在这篇文章中,我们将一起踏上一场激动人心的iOS开发之旅。无论你是刚刚入门的新手,还是已经有一定经验的开发者,这篇文章都将为你提供宝贵的知识和技能。我们将从基础的iOS开发概念开始,逐步深入到更复杂的主题,如用户界面设计、数据存储和网络编程等。通过阅读这篇文章,你将获得成为一名优秀iOS开发者所需的全面技能和知识。让我们一起开始吧!
|
12天前
|
移动开发 Java Android开发
探索Android与iOS开发的差异性与互联性
【10月更文挑战第32天】在移动开发的大潮中,Android和iOS两大平台各领风骚。本文将深入浅出地探讨这两个平台的开发差异,并通过实际代码示例,展示如何在各自平台上实现相似的功能。我们将从开发环境、编程语言、用户界面设计、性能优化等多个角度进行对比分析,旨在为开发者提供跨平台开发的实用指南。
34 0