【发布时间】:2014-06-27 04:25:18
【问题描述】:
我正在开发一个具有UICollectionView 的应用程序 - 集合视图的工作是显示来自 Web 服务的数据。
我正在尝试实现的应用程序的一个功能是使用户能够将此UICollectionView 的布局从网格视图更改为表格视图。
我花了很多时间试图完善它,并设法让它发挥作用。不过也有一些问题。两种布局之间的过渡看起来不太好,有时它会在切换视图之间中断,我的应用程序的视图处于意外状态。只有当用户在网格和表格视图之间快速切换(按下changeLayoutButton)时才会发生这种情况。
所以,显然有一些问题,我觉得代码有点脆弱。我还需要解决上述问题。
我将从如何实现此视图开始。
实施
因为我需要两个不同的单元格(grideCell 和 tableViewCell)来显示不同的东西 - 我决定子类化 UICollectionViewFlowLayout 会更好,因为它可以满足我的所有需要 - 我需要做的就是更改细胞大小。
考虑到这一点,我创建了两个子类UICollectionViewFlowLayout
这就是这两个类的样子:
BBTradeFeedTableViewLayout.m
#import "BBTradeFeedTableViewLayout.h"
@implementation BBTradeFeedTableViewLayout
-(id)init
{
self = [super init];
if (self){
self.itemSize = CGSizeMake(320, 80);
self.minimumLineSpacing = 0.1f;
}
return self;
}
@end
BBTradeFeedGridViewLayout.m
#import "BBTradeFeedGridViewLayout.h"
@implementation BBTradeFeedGridViewLayout
-(id)init
{
self = [super init];
if (self){
self.itemSize = CGSizeMake(159, 200);
self.minimumInteritemSpacing = 2;
self.minimumLineSpacing = 3;
}
return self;
}
@end
如您所见,非常简单 - 只需更改单元格大小。
然后在我的viewControllerA 类中,我实现了UICollectionView,如下所示:
创建属性:
@property (strong, nonatomic) BBTradeFeedTableViewLayout *tableViewLayout;
@property (strong, nonatomic) BBTradeFeedGridViewLayout *grideLayout;
在viewDidLoad
/* Register the cells that need to be loaded for the layouts used */
[self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemTableViewCell" bundle:nil] forCellWithReuseIdentifier:@"TableItemCell"];
[self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemGridViewCell" bundle:nil] forCellWithReuseIdentifier:@"GridItemCell"];
用户点击一个按钮来改变布局:
-(void)changeViewLayoutButtonPressed
我使用 BOOL 来确定当前处于活动状态的布局,并基于此使用以下代码进行切换:
[self.collectionView performBatchUpdates:^{
[self.collectionView.collectionViewLayout invalidateLayout];
[self.collectionView setCollectionViewLayout:self.grideLayout animated:YES];
} completion:^(BOOL finished) {
}];
在cellForItemAtIndexPath
我确定应该使用哪些单元格(grid 或 tableView)并加载数据 - 代码如下所示:
if (self.gridLayoutActive == NO){
self.switchToTableLayout = NO;
BBItemTableViewCell *tableItemCell = [collectionView dequeueReusableCellWithReuseIdentifier:tableCellIdentifier forIndexPath:indexPath];
if ([self.searchArray count] > 0){
self.switchToTableLayout = NO;
tableItemCell.gridView = NO;
tableItemCell.backgroundColor = [UIColor whiteColor];
tableItemCell.item = self.searchArray[indexPath.row];
}
return tableItemCell;
}else
{
BBItemTableViewCell *gridItemCell= [collectionView dequeueReusableCellWithReuseIdentifier:gridCellIdentifier forIndexPath:indexPath];
if ([self.searchArray count] > 0){
self.switchToTableLayout = YES;
gridItemCell.gridView = YES;
gridItemCell.backgroundColor = [UIColor whiteColor];
gridItemCell.item = self.searchArray[indexPath.row];
}
return gridItemCell;
}
最后在两个单元格类中 - 我只是根据需要使用数据来设置图像/文本。
也在网格单元格中 - 图像更大,我删除了我不想要的文本 - 这是使用两个单元格的主要原因。
我很想知道如何让这个视图在 UI 中看起来更流畅、更少错误。我想要的外观就像 eBay 的 iOS 应用程序一样——它们在三种不同的视图之间切换。我只需要在两个不同的视图之间切换。
【问题讨论】:
-
您是否尝试过在过渡期间禁用更改布局按钮?
-
这可以工作 - 但我觉得它是一个黑客。我想让整个传统更加强大。
-
这根本不是 hack。如果您考虑一下 - 您不想在原始动画中间来回传输。
-
我想你是对的。我会在动画期间禁用它并在完成块中启用它吗?
-
@Tender:完全正确
标签: ios objective-c cocoa-touch uicollectionview