iOS实现书架布局样式【一些电子书的首页】

  本文实现了类似电子书首页,用来展示图书或小说的布局页面,书架列表【iPhone6模拟器】,屏幕尺寸还没进行适配,只是做个简单的demo【纯代码实现方式】

实现采用的是UICollectionView和UICollectionViewFlowLayout。关于UICollectionView的详细讲解请参考http://blog.csdn.net/meegomeego/article/details/16953489

一、实现layout的DecorationView

//
//  FWBookShelfDecarationViewCollectionReusableView.h
//  FWPersonalApp
//
//  Created by hzkmn on 16/2/18.
//  Copyright © 2016年 ForrstWoo. All rights reserved.
//

#import <UIKit/UIKit.h>

extern NSInteger const kDecorationViewHeight;


@interface FWBookShelfDecarationView : UICollectionReusableView

@end
FWBookShelfDecarationView.h
//
//  FWBookShelfDecarationViewCollectionReusableView.m
//  FWPersonalApp
//
//  Created by hzkmn on 16/2/18.
//  Copyright © 2016年 ForrstWoo. All rights reserved.
//



#import "FWBookShelfDecarationView.h"

NSInteger const kDecorationViewHeight = 216;

@implementation FWBookShelfDecarationView

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, kDecorationViewHeight)];
        img.image = [UIImage imageNamed:@"boolshelf.png"];
        [self addSubview:img];
    }
    
    return self;
}
@end
FWBookShelfDecarationView.m

FWBookShelfDecarationView类非常简单只是定义了Decarationview的背景图片,图上。

二、下载及导入可重新排序的第三方layout,用于我们移动图书后重新布局

详见http://www.cnblogs.com/salam/p/5205919.html

三、实现自己的layout

首先继承LXReorderableCollectionViewFlowLayout,让该类具有重新排序功能。

//
//  FWBookshelfCollectionViewLayout.h
//  FWPersonalApp
//
//  Created by hzkmn on 16/2/18.
//  Copyright © 2016年 ForrstWoo. All rights reserved.
//

#import "LXReorderableCollectionViewFlowLayout.h"

extern NSString * const FWBookshelfCollectionViewLayoutDecorationViewKind;

@interface FWBookshelfCollectionViewLayout : LXReorderableCollectionViewFlowLayout

@end
FWBookshelfCollectionViewLayout.h
//
//  FWBookshelfCollectionViewLayout.m
//  FWPersonalApp
//
//  Created by hzkmn on 16/2/18.
//  Copyright © 2016年 ForrstWoo. All rights reserved.
//

#import "FWBookshelfCollectionViewLayout.h"

#import "FWBookShelfDecarationView.h"

NSString * const FWBookshelfCollectionViewLayoutDecorationViewKind = @"FWBookshelfCollectionViewLayoutDecorationViewKind";

@interface FWBookshelfCollectionViewLayout ()

@property (nonatomic, strong) NSDictionary *bookShelfRectanges;
@property NSInteger countOfRow;

@end

@implementation FWBookshelfCollectionViewLayout

- (void)prepareLayout
{
    [super prepareLayout];
    
    [self registerClass:[FWBookShelfDecarationView class] forDecorationViewOfKind:FWBookshelfCollectionViewLayoutDecorationViewKind];
    
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    
    NSInteger itemCount = [self.collectionView numberOfItemsInSection:0];
    self.countOfRow = ceilf(itemCount / 3.0);
    for (int row = 0; row < self.countOfRow; row++)
    {
        dictionary[[NSIndexPath indexPathForItem:row inSection:0]] = [NSValue valueWithCGRect:CGRectMake(0, kDecorationViewHeight * row, screenSize.width, kDecorationViewHeight)];
    }
    
    self.bookShelfRectanges = [NSDictionary dictionaryWithDictionary:dictionary];
}

#pragma mark Runtime Layout Calculations
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // call super so flow layout can return default attributes for all cells, headers, and footers
    // NOTE: Flow layout has already taken care of the Cell view layout attributes! :)
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
    // create a mutable copy so we can add layout attributes for any shelfs that
    // have frames that intersect the rect the CollectionView is interested in
    NSMutableArray *newArray = [array mutableCopy];
    //    NSLog(@"in rect:%@",NSStringFromCGRect(rect));
    // Add any decoration views (shelves) who's rect intersects with the
    // CGRect passed to the layout by the CollectionView
    [self.bookShelfRectanges enumerateKeysAndObjectsUsingBlock:^(id key, id shelfRect, BOOL *stop) {
        //        NSLog(@"[shelfRect CGRectValue]:%@",NSStringFromCGRect([shelfRect CGRectValue]));
        
        if (CGRectIntersectsRect([shelfRect CGRectValue], rect))
        {
            UICollectionViewLayoutAttributes *shelfAttributes =
            [self layoutAttributesForDecorationViewOfKind:FWBookshelfCollectionViewLayoutDecorationViewKind
                                              atIndexPath:key];
            [newArray addObject:shelfAttributes];
        }
    }];
    
    for (int i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        
        [newArray addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
    }
    
    return [newArray copy];
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //    NSLog(@"%@", NSStringFromCGSize([self screenSize]));375 667
    UICollectionViewLayoutAttributes *attris = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    NSInteger currentRow = indexPath.item / 3;
    CGRect frame = CGRectMake(20 + (indexPath.item % 3) * (kCellWidth + 17.5), 35+ currentRow * (kCellHeight + 65), kCellWidth, kCellHeight);
    attris.frame = frame;
    attris.zIndex = 1;
    
    return attris;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath
{
    
    id shelfRect = self.bookShelfRectanges[indexPath];
    
    // this should never happen, but just in case...
    if (!shelfRect)
        return nil;
    
    UICollectionViewLayoutAttributes *attributes =
    [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind
                                                                withIndexPath:indexPath];
    attributes.frame = [shelfRect CGRectValue];
    //    NSLog(@"UICollectionViewLayoutAttributes :.%@", NSStringFromCGRect([shelfRect CGRectValue]));
    
    attributes.zIndex = -1; // shelves go behind other views
    
    return attributes;
}

- (CGSize)collectionViewContentSize
{
    CGSize contentSize = CGSizeMake(self.collectionView.bounds.size.width, self.countOfRow * kDecorationViewHeight + 20);
    
    return contentSize;
}

@end
FWBookshelfCollectionViewLayout.m

四、应用

//
//  FWAncientPoetryCollectionViewController.m
//  FWPersonalApp
//
//  Created by hzkmn on 16/2/17.
//  Copyright © 2016年 ForrstWoo. All rights reserved.
//



#import "FWAncientPoetryCollectionViewController.h"

#import "FWBookShelfDecarationView.h"
#import "FWBookshelfCollectionViewLayout.h"
#import "FWBookCategoryViewController.h"

@interface FWAncientPoetryCollectionViewController () <LXReorderableCollectionViewDataSource, LXReorderableCollectionViewDelegateFlowLayout>

@property (nonatomic, strong) NSMutableArray *books;

@end

@implementation FWAncientPoetryCollectionViewController

static NSString * const cellReuseIdentifier = @"Cell";
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"古籍";
    self.collectionView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bookShelfBackground.png"]];
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellReuseIdentifier];
    self.books = [[NSMutableArray alloc] initWithArray:[self bookNameOfAllBooks]];
}

- (NSArray *)bookNameOfAllBooks
{
  return [[FWDataManager getDataForPoetry] allKeys];
}

#pragma mark <UICollectionViewDataSource>

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [self.books count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellReuseIdentifier forIndexPath:indexPath];
    UIImage *image = [UIImage imageNamed:self.books[indexPath.item]];
    cell.backgroundColor = [UIColor colorWithPatternImage:image];

    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath willMoveToIndexPath:(NSIndexPath *)toIndexPath
{
    NSString *theBookName = self.books[fromIndexPath.item];
    [self.books removeObjectAtIndex:fromIndexPath.item];
    [self.books insertObject:theBookName atIndex:toIndexPath.item];
}

#pragma mark - UICollectionViewDelegateFlowLayout

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return CGSizeMake(kCellWidth, kCellHeight);
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    FWBookCategoryViewController *vc = [[FWBookCategoryViewController alloc] initWithUrlString:[[FWDataManager getDataForPoetry] objectForKey:self.books[indexPath.item]]];
    [self.navigationController pushViewController:vc animated:YES];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

    [self.books removeAllObjects];
    self.books = nil;
}

@end
FWAncientPoetryCollectionViewController.m
原文地址:https://www.cnblogs.com/salam/p/5249131.html