你的位置:首页 > 操作系统

[操作系统]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 FWAncientPoetryCollectionViewControllerstatic 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