适用于 iPad 的可滚动 GridView
Posted
技术标签:
【中文标题】适用于 iPad 的可滚动 GridView【英文标题】:Scrollable GridView for iPad 【发布时间】:2013-01-12 13:18:44 【问题描述】:我正在为 iPad 实现一个表格并面临一些重大问题。
对于 GridView,我实现了自己的 UITableViewCell 子类,效果很好。
数据显示正确,但是当我想访问单个单元格以转到一些新的详细信息视图时出现问题。由于一行只包含一个单元格,所以 didSelectRowAtIndexPath 只能让我访问完整的单元格,但我不知道单个单元格在哪一列。
然后我实现了一个 TapGestureRecognizer。这向我显示了行和列并且有效,但直到我开始滚动......列部分仍然有效,但行显示不正确,因为 TapRecognizer 与 didSelectRowAtIndexPath 重叠(不好但不是那么重要的副作用.. 没有选定行的蓝色突出显示)。
有没有办法找出我滚动了多少像素?还是有更好的解决方案?
【问题讨论】:
是的,有一个更好的解决方案——它叫做UICollectionView
如果您计划以 ios 5.x 为目标,那么您可能需要查看 PSTCollectionView (github.com/steipete/PSTCollectionView)。它是 UICollectionView 的 100% API 兼容替代品。事实上,在 iOS 6 上,它将透明地使用 UICollectionView,而在 iOS 5.x 及更早版本上回退到 PSTCollectionView。
【参考方案1】:
我强烈建议在第 3 方课程中使用 UICollectionView
。访问所有委托协议有很多好处(例如,在没有UIGestureRecognizer
的情况下长按显示剪切复制粘贴UIMenuController
)我自己使用一个作为网格。
为了实现网格布局,我执行了以下操作...
1) 我在 .h 文件中设置了以下委托:
@interface YourViewControllerWithCollectionView : UIViewController <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, retain) IBOutlet UICollectionView *myCollectionView;
@end
注意,我没有设置UICollectionViewDelegate
,因为UICollectionViewDelegateFlowLayout
实际上是UICollectionViewDelegate
的子协议,所以不需要同时设置。
2) 在.m文件中,合成collection view,并在viewDidLoad中声明datasource和delegate:(别忘了连接outlet,可能要放背景单元格上的颜色,以便您可以看到它)
@synthesize myCollectionView;
viewdidLoad:
- (void)viewDidLoad
self.myCollectionView.delegate = self;
self.myCollectionView.dataSource = self;
//...
3) 实现数据源
#pragma mark - UICollectionView Datasource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
return 1;
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
//the number of cells you want per row
return 4;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
//load sublassed UICollectionViewCell called MyCollectionViewCell
static NSString *cellIdentifier = @"cell";
MyCustomCollectionViewCell *cell = (MyCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.title.text = @"Title"
// customize the cell...
return cell;
5) 实现UICollectionViewDelegateFlowLayout
#pragma mark – UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
//this is what forces the collectionview to only display 4 cells for both orientations. Changing the "-80" will adjust the horizontal space between the cells.
CGSize retval = CGSizeMake((myCollectionView.frame.size.width - 80) / 4, 78);
return retval;
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
// for the entire section, which we have set to 1, adjust the space at
// (top, left, bottom, right)
// keep in mind if you change this, you will need to adjust the retVal
// in the method above
return UIEdgeInsetsMake(5, 20, 10, 20);
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
CGFloat interimSpacing = 0.0f;
return interimSpacing;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
CGFloat lineSpacing = 0.0f;
return lineSpacing;
6) 最后但同样重要的是,在方向更改时使布局无效以重绘单元格:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
[self.myCollectionView.collectionViewLayout invalidateLayout];
因为您实现了UICollectionViewDelegateFlowLayout
,所以您已经可以访问UICollectionViewDelegate
来处理选择等,例如:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
MyCollectionViewCell *cell = (MyCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
//do something when a cell is tapped...
更多信息可以在这里找到:http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12
【讨论】:
我没有使用所有这些,但还是感谢您的努力。【参考方案2】:查看AQGridView 或其他controls at CocoaControls.com。
【讨论】:
【参考方案3】:我建议反对 UICollectionView。 UICollectionView 易于使用,但目前还不够稳定。我正在为我的应用程序使用GMGridView。经过几个月的运行,我可以说它对于生产版本来说已经足够稳定了。另一种选择是 PSTCollectionView,它是 UICollectionView 的 100% API 兼容替代品。但是,它还没有完成,甚至包含more bugs 而不是 UICollectionView。
我在使用 PSTCollectionView 时遇到的令人不安的问题是:
-
poor performance 如果你想在屏幕上显示 > 80 个单元格
重新加载部分是not implemented
装修意见是not implemented
UICollectionView 令人不安的问题是:
-
第一列的项目可能是disappear
插入第一个单元格将crash
重新加载带有标题视图的部分将crash
blurry text 在单元格中
检查打开的雷达 https://openradar.appspot.com/search?query=UICollectionView UICollectionView 的所有当前问题。
我相信 UICollectionView 和 PSTCollectionView 在稳定时会是不错的选择。但此时,GMGridView 是更好的选择。
【讨论】:
GMGridView:100 个未解决的问题。 PSTCollectionView:19 个未解决的问题。你的论点似乎无效。 GMGridView 不再维护,因此所有问题都没有解决。但是在作者停止维护之前它是非常稳定的。另一方面,PSTCollectionView 是新的和未完成的。以上是关于适用于 iPad 的可滚动 GridView的主要内容,如果未能解决你的问题,请参考以下文章
适用于 iPad 的 PDF 页面大小 (dpi) 是多少?