在iOS 6 發布前,開發人員習慣使用UITableView來展示幾乎所有類型的數據集合。ios 6 為 IOS 引入了全新的控制器,用來顯示數據集合,集合視圖控制器是與表視圖控制器類似的全新UI框架。。
下面講解下一些重要的類與協議,它們是你在實現集合視圖時必須知道 的。
- UICollectionViewController
這個類的功能與UITableViewController類似。它負責管理集合視圖、存儲所需的數據,並且能處理數據源與委托協議。
1、UICollectionViewCell
它與UITableViewCell很像。你通常不需要創建UITableViewCell,可以調用 dequeueReusableCellWithReuseIdentifier:方法從集合視圖中獲取。
MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:
orientation == PhotoOrientationLandscape ? CellIdentifierLandscape:CellIdentifierPortrait
forIndexPath:indexPath];
2、UICollectionViewDataSource
猜到了吧,它與UITableViewDataSource方法類似。數據源協議擁有需要在UICollectionViewController的子類中實現的方法。
3、UICollectionViewDelegate
要在集合視圖中處理選中或高亮事件,就得實現委托協議中的方法。
下面能過具體的Demo向大家介紹下UICollectionViewController的用法:
首先在Xcode中創建一個單視圖應用。在第二個窗格中,選擇Use Storyboards、Use Automatic Reference Counting以及Choose iPad as the target device復選框並點擊Next按鈕,然后再選擇想要保存的位置。
1、編輯 storyboard
打開 MainStoryboard.storyboard文件並刪除其中唯一的視圖控制器。從對象庫中拖出一個UICollectionViewController類。確保這個控制器被設置為故事板的初始視圖控制器。
現在,在工程中打開唯一的視圖控制器的頭文件。將基類從UIViewController改成 UICollectionViewController,並實現UICollectionViewDataSource 與 UICollectionViewDelegate協議。回到故事板,將集合視圖控制器的類名改成MKViewController(或者使用任意其它的前綴)。構建並運行應用,ios模擬器中會出現一個黑色的屏幕。
2、添加集合視圖單元
看到這樣的結果並不能使你滿足,對吧?我們來給它加點料吧。首先,添加一個UICollectionViewCell的子類。我們取名為MKPhotoCell。打開你的故事板並在集合視圖控制器中選擇唯一的集合視圖單元。將它的類更改為MKPhotoCell.在Utilities(實用工具)窗格打開屬性檢查器並將標識符設置為 MKPhotoCell。這一步非常重要。在后面的代碼中,你將會使用這個標識符來(dequeue)出列單元.如圖所示:
添加一個空白的UIView作為你的集合視圖單元的子視圖,並把視圖背景色改為紅色。
3、實現數據源方法
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return100;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:@"MKPhotoCell"
forIndexPath:indexPath];
return cell;
}
現在構建並運行應用。你將會看到有100個單元的柵格,每一個單元都是紅色的。很神奇吧,當你旋轉iPad到橫向時會更驚奇:柵格會自動旋轉並對齊。
4、顯示圖片
現在可以用一些更加有趣的東西來替換這些紅色的子視圖。這里我們要顯示某個目錄中的圖片。把一些圖片大約50張復制到你的工程中去。移除在上一節中添加的紅色子視圖,並添加一個UIImageView和一個UILabel到UICollectionViewCell中。
5、准備數據源
實現方法是遍歷目錄中的文件。把它添加到集合視圖控制器子類的viewDidLoad方法中。
NSArray * photosArray = [[NSFileManagerdefaultManager] contentsOfDirectoryAtPath:[selfphotosDirectory] error:nil];
self.photosList = photosArray;
然后定義photosDirectory方法:
-(NSString*) photosDirectory
{
return [[[NSBundlemainBundle] resourcePath] stringByAppendingPathComponent:@"Photos"];
}
現在,更新數據源方法,使其返回這些信息數據。上節代碼返回的是一個區和100個項。將數值100改成self.photosList數組。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:@"MKPhotoCell"
forIndexPath:indexPath];
NSString *photoName = [self.photosList objectAtIndex:indexPath.row];
NSString *photoFilePath = [[self photosDirectory] stringByAppendingPathComponent:photoName];
cell.nameLabel.text =[photoName stringByDeletingPathExtension];
UIImage *image = [UIImage imageWithContentsOfFile:photoFilePath];
UIGraphicsBeginImageContext(CGSizeMake(128.0f, 128.0f));
[image drawInRect:CGRectMake(0, 0, 128.0f, 128.0f)];
cell.photoView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cell;
}
現在構建並運行應用,你將會看到圖片整齊地按照行列排列。
6、支持橫屏與豎屏圖片
在故事板中創建另一個UICollectionViewCell並將它的類更改為MKPhotoCell.改變圖片視圖的大小以適應豎屏,之前的舊的單元方向則是橫屏。你可以為橫屏使用180*120大小,為豎屏單元使用120*180大小。MKPhotoCell大小為200*250. 更改它們的cellIdentifier,比如改成MKPhotoCellLandscape 和 MKPhotoCellPortrait這樣的。完成之后,故事板應該是這樣的:
7、判定方向
現在你必須根據圖片的方向來決定使用哪個單元。可以通過創建UIImage然后讀取它的size屬性來獲取圖片的方向。如果圖片的寬度大於高度,則是橫向;否則就是豎向。如果你在collectionView cellForItemAtIndexPath:方法中進行計算的話,滾動速度肯定會受影響,我們在viewDidLoad方法中計算。代碼如下:
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray * photosArray = [[NSFileManagerdefaultManager] contentsOfDirectoryAtPath:[selfphotosDirectory] error:nil];
self.photosCache = [NSMutableDictionarydictionary];
self.photoOrientation = [NSMutableArrayarray];
self.photosList = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[photosArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *path = [[selfphotosDirectory] stringByAppendingPathComponent:obj];
CGSize size = [UIImage imageWithContentsOfFile:path].size;
if(size.width > size.height)
[self.photoOrientationaddObject:[NSNumbernumberWithInt:PhotoOrientationLandscape]];
else
[self.photoOrientationaddObject:[NSNumbernumberWithInt:PhotoOrientationPortrait]];
}];
dispatch_async(dispatch_get_main_queue(), ^{
self.photosList = photosArray;
[self.collectionViewreloadData];
});
});
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifierLandscape = @"MKPhotoCellLandscape";
static NSString *CellIdentifierPortrait = @"MKPhotoCellPortrait";
int orientation = [[self.photoOrientation objectAtIndex:indexPath.row] integerValue];
MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:
orientation == PhotoOrientationLandscape ? CellIdentifierLandscape:CellIdentifierPortrait
forIndexPath:indexPath];
NSString *photoName = [self.photosList objectAtIndex:indexPath.row];
NSString *photoFilePath = [[self photosDirectory] stringByAppendingPathComponent:photoName];
cell.nameLabel.text =[photoName stringByDeletingPathExtension];
__block UIImage* thumbImage = [self.photosCache objectForKey:photoName];
cell.photoView.image = thumbImage;
if(!thumbImage) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage *image = [UIImage imageWithContentsOfFile:photoFilePath];
if(orientation == PhotoOrientationPortrait) {
UIGraphicsBeginImageContext(CGSizeMake(180.0f, 120.0f));
[image drawInRect:CGRectMake(0, 0, 180.0f, 120.0f)];
thumbImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
} else {
UIGraphicsBeginImageContext(CGSizeMake(120.0f, 180.0f));
[image drawInRect:CGRectMake(0, 0, 120.0f, 180.0f)];
thumbImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.photosCache setObject:thumbImage forKey:photoName];
cell.photoView.image = thumbImage;
});
});
}
return cell;
}
構建並運行應用。應該可以橫豎屏切換了。因為篇幅問題,暫不處理點擊事件了。
原文:http://www.cnblogs.com/javawebsoa/archive/2013/05/24/3098089.html