iOS UICollectionView – 默认stream程,从右到左填充行
我正在使用我的一个应用程序UICollectionView,自定义单元格,但默认stream量。 目前这个视图在一行中显示3个单元格(全部大小相同)。 单元格从左到右填充行,但我需要从右到左。
可能吗? 我是否需要创build自定义stream布局? 如果是这样,任何人都可以举个简单的例子吗
任何帮助将不胜感激。
假设您只需要三个单元格,并使用此集合视图的标题视图,则需要执行以下步骤:
重写UICollectionViewFlowLayout
@interface GSRightToLeftCollectionViewFlowLayout : UICollectionViewFlowLayout
(GS是Groboot SmarTech :))
.m应该看起来像这样:
#import "GSRightToLeftCollectionViewFlowLayout.h" typedef enum { // enum for comfortibility. CellXPositionLeft = 1, CellXpositionRight = 2, CellXpositionCenter = 3, CellXPositionNone = 4 } CellXPosition; @interface GSRightToLeftCollectionViewFlowLayout () @property (nonatomic) BOOL cellFlag; @property (nonatomic) float cellLeftX; @property (nonatomic) float cellMiddleX; @property (nonatomic) float cellRightX; @end @implementation GSRightToLeftCollectionViewFlowLayout // when ever the bounds change, call layoutAttributesForElementsInRect: - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *allItems = [[super layoutAttributesForElementsInRect:rect] mutableCopy]; for (UICollectionViewLayoutAttributes *attribute in allItems) { // when we get an item, calculate it's English writing position, // so that we can convert it to the Hebrew - Arabic position. if (!self.cellFlag) { [self calculateLocationsForCellsWithAttribute:attribute]; self.cellFlag = YES; } // if it's a header, do not change it's place. if (attribute.representedElementKind == UICollectionElementKindSectionHeader) { continue; } // check where the item should be placed. CellXPosition position = [self attributeForPosition:attribute]; switch (position) { case CellXPositionLeft: attribute.frame = CGRectMake(self.cellLeftX, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height); break; case CellXpositionRight: attribute.frame = CGRectMake(self.cellRightX, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height); break; case CellXpositionCenter: attribute.frame = CGRectMake(self.cellMiddleX, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height); break; case CellXPositionNone: NSLog(@"warning"); break; } } return allItems; } - (CellXPosition)attributeForPosition:(UICollectionViewLayoutAttributes *)attribute { CellXPosition cellXposition = CellXPositionNone; // we will return an opposite answer if (attribute.indexPath.row % 3 == 0) { // if it's in the left side, move it to the right cellXposition = CellXpositionRight; } else if (attribute.indexPath.row % 3 == 1) { cellXposition = CellXpositionCenter; } else if (attribute.indexPath.row % 3) { // if it's in the right side, move it to the left cellXposition = CellXPositionLeft; } return cellXposition; } - (void)calculateLocationsForCellsWithAttribute:(UICollectionViewLayoutAttributes *)attribute { float cellWidth = self.itemSize.width; float minimumX = self.sectionInset.left; float maximumX = self.sectionInset.right; float displayWidth = self.collectionView.contentSize.width - minimumX - maximumX; // on iOS6, displayWidth will be 0 (don't know why), so insert an if (displayWidth == 0) and set manually the size. self.cellLeftX = minimumX; float space = (displayWidth - cellWidth * 3) / 2; self.cellMiddleX = self.cellRightX + cellWidth + space; self.cellRightX = self.cellMiddleX + cellWidth + space; } @end
在你显示CollectionView的类中,你需要这样做:
如果您正在使用故事板:1.将collectionView布局更改为自定义(在属性检查器中)2.将其类设置为GSRightToLeftCollectionViewFlowLayout。 3.在ViewDidLoad中(或者每当你执行初始化)
- (void)viewDidLoad { [super viewDidLoad]; GSRightToLeftCollectionViewFlowLayout *layout = [[GSRightToLeftCollectionViewFlowLayout alloc] init]; layout.itemSize = CGSizeMake(98, 138); // set the item size. layout.minimumLineSpacing = 1; // other layout properties. layout.minimumInteritemSpacing = 1; // other layout properties. layout.headerReferenceSize = CGSizeMake(50, 18); layout.sectionInset = UIEdgeInsetsMake(1.0f, 0.0f, 1.0f, 0.0f); layout.scrollDirection = UICollectionViewScrollDirectionVertical; // in case you use headers / footers. this is also where you would register a Cell if you don't use storyboards. [self.collectionView registerClass:[GSReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView"]; self.collectionView.collectionViewLayout = layout; }
由于阿拉伯语翻译,我有同样的问题。
这里是我的解决scheme:创build一个UICollectionViewFlowLayout的子类和覆盖
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect:
我使用NSLocales字符方向作为RTL翻译的触发器。 如果是LTR语言,它只是返回默认的属性。
希望这是有帮助的。
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *supersAttributes = [super layoutAttributesForElementsInRect:rect]; NSLocale *currentLocale = ((NSLocale *) [NSLocale currentLocale]); NSLocaleLanguageDirection direction = [NSLocale characterDirectionForLanguage:currentLocale.localeIdentifier]; // if it's an RTL language: change the frame if (direction == NSLocaleLanguageDirectionRightToLeft) { for (UICollectionViewLayoutAttributes *attributes in supersAttributes) { CGRect frame = attributes.frame; frame.origin.x = rect.size.width - attributes.frame.size.width - attributes.frame.origin.x; attributes.frame = frame; } } return supersAttributes; }
@implementation CollectionReversedLayout - (void)reverseLayoutAttributes:(UICollectionViewLayoutAttributes *)attributes { CGPoint newCenter = attributes.center; newCenter.x = self.collectionViewContentSize.width - newCenter.x; attributes.center = newCenter; return attributes; } - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *s = [super layoutAttributesForElementsInRect:rect]; for (UICollectionViewLayoutAttributes *attributes in s) { [self reverseLayoutAttributes:attributes]; } return s; } - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes *s = [super layoutAttributesForItemAtIndexPath:indexPath]; [self reverseLayoutAttributes:s]; return s; }