Sar*_*dag 12 objective-c ios6 uicollectionview
我正在摆弄新的UICollectionView和UICollectionViewLayout类.我创建了一个自定义布局,子类化UICollectionViewFlowLayout.
我的单元格大小正在动态变化,我使用下面的委托方法设置项目大小
- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout*)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
      NSLog(@"SETTING SIZE FOR ITEM AT INDEX %d", indexPath.row);
      return CGSizeMake(80, 80);
}
现在,在我的自定义UICollectionViewFlowLayout类的prepareLayout方法下,我需要访问这些大小变量,以便我可以计算如何放置它们并为layoutAttributesForItemAtIndexPath缓存它们.
但是,我似乎无法在UICollectionView或UICollectionViewFlowLayout下找到任何属性来达到我在委托方法中设置的自定义项目大小.
Sar*_*dag 13
自己找到了.
实现自定义类,而不是省略 UICollectionViewDelegateFlowLayout 
@interface SECollectionViewCustomLayout : UICollectionViewFlowLayout 
                                          <UICollectionViewDelegateFlowLayout>
然后你可以打电话
CGSize size = [self collectionView:self.collectionView 
                            layout:self 
            sizeForItemAtIndexPath:indexPath];
查看各种UICollectionView...头文件,并观看WWDC 2012 Session 219  - 高级集合视图和构建自定义布局视频(从大约6:50开始),似乎可扩展委托模式利用动态类型来确保布局可以正确访问它的扩展委托方法.
UI(Collection)ViewController是管理集合视图的对象)应声明自己支持此自定义协议.
UICollectionViewFlowLayout或子类,这只是意味着声明符合UICollectionViewDelegateFlowLayout..m如果您不想#import将布局标题放入委托的界面,请随意在文件的类扩展中执行此操作.collectionView属性,并将委托转换为符合所需协议的对象以说服编译器.respondsToSelector:在调用可选的委托方法之前,不要忘记像往常一样检查委托.实际上,如果您愿意,对所有方法执行此操作没有任何害处,因为类型转换意味着没有运行时保证委托甚至可以实现所需的方法.因此,如果您实现一个需要委托来获取其某些信息的自定义布局,那么您的标题可能如下所示:
@protocol CollectionViewDelegateCustomLayout <UICollectionViewDelegate>
- (BOOL)collectionView:(UICollectionView *)collectionView
                layout:(UICollectionViewLayout *)layout
shouldDoSomethingMindblowingAtIndexPath:(NSIndexPath *)indexPath;
@end
@interface CustomLayout : UICollectionViewLayout
// ...
@end
你的代表声明了一致性(我在这里的实现文件中已经这样做了):
#import "CustomLayout.h"
@interface MyCollectionViewController () <CollectionViewDelegateCustomLayout>
@end
@implementation
// ...
- (BOOL)collectionView:(UICollectionView *)collectionView
                layout:(UICollectionViewLayout *)layout
shouldDoSomethingMindblowingAtIndexPath:(NSIndexPath *)indexPath
{
    return [self canDoSomethingMindblowing];
}
// ...
@end
在您的布局实现中,您可以访问以下方法:
BOOL blowMind;
if ([self.collectionView.delegate respondsToSelector:@selecor(collectionView:layout:shouldDoSomethingMindblowingAtIndexPath:)]) {
    blowMind = [(id<CollectionViewDelegateCustomLayout>)self.collectionView.delegate collectionView:self.collectionView
                                                                                             layout:self
                                                            shouldDoSomethingMindblowingAtIndexPath:indexPath];
} else {
    // Perhaps the layout also has a property for this, if the delegate
    // doesn't support dynamic layout properties...?
    // blowMind = self.blowMind;
}
请注意,在这里进行类型转换是安全的,因为我们正在检查委托事先是否事先响应了该方法.
这只是猜测,但我怀疑Apple是如何管理UICollectionViewDelegateFlowLayout协议的.
delegate流布局中没有属性,因此调用必须通过集合视图的委托进行.UICollectionViewController 不公开符合扩展流布局委托(我怀疑它在另一个私有标头中这样做).UICollectionView该delegate属性仅声明符合"基础" UICollectionViewDelegate协议.同样,我怀疑UICollectionView流布局正在使用私有子类/类别以防止需要进行类型转换.为了进一步增加这一点,苹果公司不鼓励UICollectionView在文档中进行子类化(适用于iOS的集合视图编程指南:创建自定义布局):避免继承UICollectionView.集合视图很少或没有自己的外观.相反,它从数据源对象中提取其所有视图,并从布局对象中提取所有与布局相关的信息.
我们去了.并不复杂,但值得知道如何做到范式友好的方式.
有一个快速版本:
self.collectionView(self.collectionView, layout: self.collectionView.collectionViewLayout, sizeForItemAtIndexPath: indexPath)
| 归档时间: | 
 | 
| 查看次数: | 41573 次 | 
| 最近记录: |