UICollectionView(二)——應(yīng)用UICollectionView實(shí)現(xiàn)一個(gè)簡單的相冊

前言

趁著這幾天學(xué)習(xí)UICollectionView咐鹤,也跟著別人的例子自己做了下關(guān)于UICollectionView應(yīng)用的Demo闪萄。下面要講的就是通過UICollectionView實(shí)現(xiàn)一個(gè)簡單的相冊冈欢。上篇對理論知識已經(jīng)寫得比較完善了薇宠,所以本篇重點(diǎn)講例子的實(shí)現(xiàn)购对。


先看最終效果圖卢未。該相冊只有一行圖片岂座,可以左右滑動(dòng)瀏覽圖片态蒂,并且圖片滑到中間時(shí)會發(fā)生形變,到整個(gè)view的中點(diǎn)時(shí)達(dá)到峰值费什。而且體驗(yàn)更友好的一點(diǎn)是當(dāng)某圖片接近view中點(diǎn)時(shí)會自動(dòng)滑到view的中點(diǎn)钾恢,感覺像被吸過去一樣。

photos.gif

思路

  • 1.確定相冊的基本布局通過UICollectionView實(shí)現(xiàn)鸳址;
  • 2.自定義UICollectionViewFlowLayout布局視圖瘩蚪。我們可以看出某張圖片的大小(layoutAttribute的transform屬性值)是和它的位置有某種關(guān)系的稿黍。它們之間的算法我們在layoutAttributesForElementsInRect方法里完成疹瘦,從而正確的展示圖片大小。
  • 3.注意一定要實(shí)現(xiàn)下面這個(gè)方法巡球,不然滑動(dòng)時(shí)圖片大小是不會發(fā)生大小形變的言沐,因?yàn)槟J(rèn)這個(gè)方法返回NO。只有返回YES時(shí)酣栈,只要該layout哪里有布局屬性發(fā)生變化险胰,便會重新加載該layout,從而實(shí)現(xiàn)實(shí)時(shí)更新layout布局界面矿筝。
// 當(dāng)布局屬性改變時(shí)重新加載layout
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
  • 4.所謂圖片滑到view中點(diǎn)有吸附感起便,其實(shí)就是判斷某item滑動(dòng)終止時(shí)的位置距離view的center是否達(dá)到了一個(gè)臨界點(diǎn),若達(dá)到了就把該item的位置改為view的中點(diǎn)即可。

上代碼

布局UICollectionView缨睡,搭建相冊的基本界面鸟悴。

// create collectionView
- (void)loadCollectionView
{
    _flowLayout = [[YWPhotoFlowLayout alloc] init];
    _flowLayout.itemSize = CGSizeMake(200, 200);
    _flowLayout.minimumInteritemSpacing = 5.0f;
    _flowLayout.minimumLineSpacing = 5.0f;
    _flowLayout.sectionInset = UIEdgeInsetsMake(-50.f, 50.f, 5.f, 50.f);
    _flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    _collectionView = [[UICollectionView alloc] initWithFrame:(CGRect){0,150.f,self.view.frame.size.width, 250} collectionViewLayout:_flowLayout];
    _collectionView.backgroundColor = [UIColor lightGrayColor];
    _collectionView.dataSource = self;
    _collectionView.delegate = self;
    [self.view addSubview:_collectionView];
    
    [_collectionView registerClass:[YWPhotoCell class] forCellWithReuseIdentifier:photoCellId];
}


#pragma mark ---- UICollectionViewDataSource

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return _imgsArray.count;
}


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    YWPhotoCell *photoCell = [_collectionView dequeueReusableCellWithReuseIdentifier:photoCellId forIndexPath:indexPath];
    
    photoCell.image = (UIImage *)_imgsArray[indexPath.row];

    return photoCell;
}

創(chuàng)建自定義布局類YWPhotoFlowLayout,注釋在代碼中寫得比較詳細(xì)奖年,所以在這不解釋细诸。

#import "YWPhotoFlowLayout.h"

#define MinValue 100.f

@interface YWPhotoFlowLayout ()

@end


@implementation YWPhotoFlowLayout

- (id)init
{
    if(self = [super init])
    {
    }
    
    return self;
}


- (void)prepareLayout
{
    [super prepareLayout];
    
//  self.minimumInteritemSpacing = 5.0f;
//  self.minimumLineSpacing = 5.0f;
//  self.sectionInset = UIEdgeInsetsMake(0.f, 5.f, 5.f, 5.f);
//  self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    
}

// 當(dāng)布局改變時(shí)重新加載layout
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}


// 對layoutAttrute根據(jù)需要做調(diào)整,也許是frame,alpha,transform等
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // 獲取父類原先的(未放大形變的)attrsArray,我們要對其attr的frame屬性做下調(diào)整
    NSArray *attrsArray = [super layoutAttributesForElementsInRect:rect];
    CGFloat centerX = self.collectionView.frame.size.width*0.5 + self.collectionView.contentOffset.x;
    
    for(UICollectionViewLayoutAttributes *attr in attrsArray)
    {
        CGFloat length = 0.f;
        if(attr.center.x > centerX)
        {
            length = attr.center.x - centerX;
        }
        else
        {
            length = centerX - attr.center.x;
        }
        
        CGFloat scale = 1 - length / self.collectionView.frame.size.width;
        
        attr.transform = CGAffineTransformMakeScale(scale, scale);
    }
    
    return attrsArray;
}


- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    // 某cell滑動(dòng)停止時(shí)的最終rect
    CGRect rect;
    rect.origin.x = proposedContentOffset.x;
    rect.origin.y = 0.f;
    rect.size = self.collectionView.frame.size;
    
    // 計(jì)算collectionView最中心點(diǎn)的x值
    CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
    
    // 獲得super已經(jīng)計(jì)算好的布局屬性
    CGFloat offset = 0.0f;
    NSArray *attrsArray = [super layoutAttributesForElementsInRect:rect];
    for(UICollectionViewLayoutAttributes *attr in attrsArray)
    {
        if(attr.center.x - centerX > MinValue || centerX - attr.center.x > MinValue)
        {
            offset = attr.center.x - centerX; // 此刻陋守,cell的center的x和此刻CollectionView的中心點(diǎn)的距離
        }
    }
    
    proposedContentOffset.x += offset;
    
    return proposedContentOffset;
}


@end

補(bǔ)充

我在寫這個(gè)Demo的時(shí)候遇到了下圖這個(gè)很蛋疼的問題:
背景色為藍(lán)色的是layout震贵,它的布局是OK的。但是自定義的cell位置確實(shí)亂的水评。


IMG_0068.jpg

這個(gè)問題耽誤了好久猩系,才突然被我找到問題所在了。中燥。寇甸。重寫的初始化方法initWithFrame傳進(jìn)來的frame值的x和y值并不是0,所以在下面一行創(chuàng)建UIImageView的initWithFrame直接傳入這個(gè)frame當(dāng)然會有問題疗涉。把frame改為bounds就OK了拿霉。


屏幕快照 2015-12-04 下午6.21.28.png

感覺這是我個(gè)我很容易犯的毛病,所以記錄下來咱扣。下面是改正完善后的自定義cell的代碼:

#import "YWPhotoCell.h"

@interface YWPhotoCell ()
{
    UIImageView     *_imageView;
}
@end


@implementation YWPhotoCell


- (id)initWithFrame:(CGRect)frame
{
    if(self = [super initWithFrame:frame])
    {
        _imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        // 給UIImageView加個(gè)圖層绽淘,使其有相框的效果
        _imageView.layer.borderColor = [UIColor whiteColor].CGColor;
        _imageView.layer.borderWidth = 5.0f;
        _imageView.contentMode = UIViewContentModeScaleToFill;
        [self.contentView addSubview:_imageView];
        
        self.backgroundColor = [UIColor blueColor];
    }
    
    return self;
}


#pragma mark ---- setter/getter

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

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市闹伪,隨后出現(xiàn)的幾起案子沪铭,更是在濱河造成了極大的恐慌,老刑警劉巖偏瓤,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杀怠,死亡現(xiàn)場離奇詭異,居然都是意外死亡硼补,警方通過查閱死者的電腦和手機(jī)驮肉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來已骇,“玉大人,你說我怎么就攤上這事票编⊥蚀ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵慧域,是天一觀的道長鲤竹。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么辛藻? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任碘橘,我火速辦了婚禮,結(jié)果婚禮上吱肌,老公的妹妹穿的比我還像新娘痘拆。我一直安慰自己,他們只是感情好氮墨,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布纺蛆。 她就那樣靜靜地躺著,像睡著了一般规揪。 火紅的嫁衣襯著肌膚如雪桥氏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天猛铅,我揣著相機(jī)與錄音字支,去河邊找鬼。 笑死奸忽,一個(gè)胖子當(dāng)著我的面吹牛堕伪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播月杉,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼刃跛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了苛萎?” 一聲冷哼從身側(cè)響起桨昙,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腌歉,沒想到半個(gè)月后蛙酪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翘盖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年桂塞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馍驯。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阁危,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汰瘫,到底是詐尸還是另有隱情狂打,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布混弥,位于F島的核電站趴乡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晾捏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一蒿涎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惦辛,春花似錦劳秋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至市怎,卻和暖如春岁忘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背区匠。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工干像, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人驰弄。 一個(gè)月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓麻汰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戚篙。 傳聞我的和親對象是個(gè)殘疾皇子五鲫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件岔擂、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,029評論 4 62
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,512評論 25 707
  • 世上最好的事情 是愛有回應(yīng) 沒有人告訴我 長大以后的我們 會做著平凡的工作位喂,談一場不怎么樣的戀愛 上學(xué)的時(shí)候的確寫...
    李天樂閱讀 794評論 0 0
  • 晚冬來,風(fēng)雪皆至乱灵。枝上紅梅開塑崖,不怯寒。 初夏在痛倚,山雨欲來规婆。街頭紅顏好,且懼炎蝉稳。
    他眼里有星河閱讀 431評論 2 3
  • 第六章 勞動(dòng)關(guān)系管理 第四節(jié)企業(yè)勞動(dòng)爭議處理
    紅楓醉秋2閱讀 218評論 0 1