UICollectionView基礎知識(基本使用三)
水平滾動列表
使用集合視圖可以創建出水平滾動的列表, 如果要實現水平滾動, 就要考慮在流式布局之下, 區段內的條目會默認換行;
解決方式是利用每個 section 中只有一個 Item, 當水平滾動時每個Section 豎直方向將其中的 Item 擺放, 排列完成后水平方向開始下一 Section, 所以當有多個 Section, 每個 Section 僅有一個 Item時,會一行顯示
#import "ViewController.h"
#import "ImageCollectionViewCell.h"
@interface ViewController ()<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
@property (nonatomic, copy) NSArray *wordArray;
@property (nonatomic, strong) NSMutableDictionary *artDictionary;
@end
@implementation ViewController
- (NSMutableDictionary *)artDictionary
{
if (!_artDictionary) {
_artDictionary = [NSMutableDictionary dictionary];
}
return _artDictionary;
}
// 根據 indexPath 獲得 String 數據
- (NSString *)itemAtIndexPath:(NSIndexPath *)indexPath
{
return [NSString stringWithFormat:@"%zd-%zd",indexPath.section, indexPath.item];
}
// 根據 String 創建圖片
- (UIImage *)imageForString:(NSString *)string
{
NSArray *fontFamilys = [UIFont familyNames];
NSString *fontName = fontFamilys[rand() % fontFamilys.count];
CGFloat fontSize = 12 + rand() % 20;
UIFont *font = [UIFont fontWithName:fontName size:fontSize];
UIImage *image = [self stringImageTinted:string font:font inset:10.f];
return image;
}
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flowLayout.sectionInset = UIEdgeInsetsMake(40, 10, 40, 10);
flowLayout.minimumLineSpacing = 10.f;
flowLayout.minimumInteritemSpacing = 10;
flowLayout.itemSize = CGSizeMake(100, 100);
[self.collectionView setCollectionViewLayout:flowLayout];
// 注冊 Cell
[self.collectionView registerClass:[ImageCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
// 注冊 Header
[self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
// 注冊 Footer
[self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer"];
self.collectionView.backgroundColor = [UIColor lightGrayColor];
// 允許用戶多選
self.collectionView.allowsMultipleSelection = YES;
}
#pragma mark - UICollectionViewDataSource
// 有100組, 每組只顯示1個元素
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 100;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 1;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
UIImage *image = self.artDictionary[indexPath];
if (!image)
{
NSString *item = [self itemAtIndexPath:indexPath];
image = [self imageForString:item];
self.artDictionary[indexPath] = image; // 緩存圖片
}
return image.size;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ImageCollectionViewCell *cell = (ImageCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
NSString *item = [self itemAtIndexPath:indexPath];
UIImage *image = self.artDictionary[indexPath];
if (!image)
{
image = [self imageForString:item];
self.artDictionary[indexPath] = image;
}
cell.image = image;
return cell;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if (kind == UICollectionElementKindSectionHeader) {
UICollectionReusableView *header = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
header.backgroundColor = [UIColor blackColor];
return header;
} else if (kind == UICollectionElementKindSectionFooter) {
UICollectionReusableView *footer = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer" forIndexPath:indexPath];
footer.backgroundColor = [UIColor darkGrayColor];
return footer;
}
return nil;
}
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Selected item at indexPath: %@", indexPath);
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Deselect item at indexPath: %@",indexPath);
}
#pragma mark - Other
// 根據文字, 字體, 內邊距生成圖片
- (UIImage *)stringImageTinted:(NSString *)string font:(UIFont *)font inset:(CGFloat)inset
{
CGSize baseSize = [string sizeWithAttributes:@{NSFontAttributeName: font}];
CGSize adjustSize = CGSizeMake(baseSize.width + inset * 2, baseSize.height + inset * 2);
// 開啟圖像上下文
UIGraphicsBeginImageContextWithOptions(adjustSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// 繪制白色背景
CGRect bounds = (CGRect){.size = adjustSize};
// 設置繪圖顏色
[[UIColor whiteColor] set];
CGContextAddRect(context, bounds);
CGContextFillPath(context);
// 繪制隨機色, 覆蓋白色背景
[[UIColor colorWithRed:((rand() % 255) / 255.0f)
green:((rand() % 255) / 255.0f)
blue:((rand() % 255) / 255.0f)
alpha:0.5f] set];
CGContextAddRect(context, bounds);
CGContextFillPath(context);
// 繪制黑色線框
[[UIColor blackColor] set];
CGContextAddRect(context, bounds);
CGContextSetLineWidth(context, inset);
CGContextStrokePath(context);
// 繪制文字
CGRect insetBounds = CGRectInset(bounds, inset, inset);
// 段落格式
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; // 斷行模式
paragraphStyle.alignment = NSTextAlignmentCenter; // 居中顯示
[string drawInRect:insetBounds withAttributes:@{
NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle,
NSForegroundColorAttributeName: [UIColor blackColor]
}];
// 從圖像上下文獲得圖片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 關閉圖像上下文
UIGraphicsEndImageContext();
return image;
}
@end