ã¿ãªãããããã«ã¡ã¯ïŒ
ã€ã³ãã
ç§ã¯ãïŒãã·ã¢ã«ïŒæãè¿ãå€åœã®å°æ¹ã®åœã®å°æ¹éœåžã§ioséçºè
ãšããŠåããŠããŸãã çŽ1幎ååãåœã¯ç§ã«åœŒå¥³ã«äœããè² ãããããšã決ããŸãããç¹ã«ãç§ã¯èªåã®äººçã«1幎ãæè¡ã®
äœãä»äºã«1幎ãåž°åœã®å€¢ã家æãšä»äºã«1幎ã®ãããã§ãã...-èŠããã«ãç§ã¯è»éã«åŸŽå
µãããŸããã ãããŠããã®ã±ãŒã¹ã®èåŸã§ãç§ã¯ã©ãããããããé·ãéåŸ
ã¡æãŸããŠããUICollectionViewãå«ããã¹ãŠã®æ©èœãåããiOS 6ã®ãªãªãŒã¹ãéããŸããã
è¡£è£
ããã¬ãŒãã³ã°å Žããã£ãŒã¿ãŒãªã©ã®é
åçãªãã®ãæ±ã£ãåŸãç§ã¯å®¶ã«æ»ããåã³åãå§ããŸããããã¡ããã顧客ããã¶ã€ããŒããpinterest boardããã€ãŸãUICollectionViewèªäœãšåŒãã§ãã圢åŒã§ããŒã¿ã衚瀺ããå¿
èŠããããããžã§ã¯ãããªããåŸ
ãããŸããã§ããã
ãããžã§ã¯ã
ãã®ãããžã§ã¯ãã¯ã骚oneåéå®äŒç€Ÿã®iPadãªãŒã¯ã·ã§ã³ã«ã¿ãã°ã®ãããªãã®ã§ãã ããã§ã®åœŒãã®èšåã«å¯ŸããŠã圌ããã©ã®ããã«åå¿ãããããããªãã®ã§ããªã³ã¯ããã¶ã€ã³ã¬ã€ã¢ãŠãããŸãã¯å®éã®ã¹ã¯ãªãŒã³ã·ã§ããã¯æäŸããŸããã
ã¢ããªã±ãŒã·ã§ã³ã¯ãååãšããŠè€éã§ã¯ãããŸããããã¶ã€ã³ã®åã³ãããç§ãå°ãã ãå®ã£ãã®ã¯ãã¡ã€ã³ç»é¢ã®å€èŠ³ã§ãã ããã¯ãæ°Žå¹³ã¹ã¯ããŒã«ã䌎ã3ã€ã®æ°Žå¹³åã«é
眮ããããããã®ç»åã®ã³ã¬ã¯ã·ã§ã³ã§ãããšæ³å®ãããŠããŸããã èŠçŽ ã®é«ããšå¹
ãåºå®ãããäžå€®ã®è¡ïŒç»åã®æ¯çã«å¿ããŠïŒã 1è¡ç®ãš3è¡ç®ã®èŠçŽ ã®é«ãã¯ãå°ããæ¹åã«ãããã«ç°ãªããç Žãããšããžã®ããã«ãªããŸãã ç§ã®ãã©ã€ãªèª¬æãæåã§ååã«ç解ããŠããªãå Žåã¯ãèšäºã®æåŸã«ããã¹ã¯ãªãŒã³ã·ã§ããïŒæçµçµæã®ãµã³ãã«ïŒãèŠãŠãã ããã
ãŸãã¯ãããUICollectionViewFlowLayout
ããã¯æå°éã®åŽåãè²»ãããæåã®è©Šã¿ã§ããã ãããã®èŠçŽ ã«ééããããšã¯äžåºŠããªãã®ã§ãAppleã®ã¯ã©ã¹ã«å¯Ÿããç§ã®åžæã¯éåžžã«åŒ·ãã£ãã ãŸããç§ã¯éåžžãæ°Žå¹³æ¹åã®ãã€ã³ã¿ã¬ã¹ãããŒããã®åºåã«åçŽã«çŠç¹ãåœãŠãŠãç Žãããšããžã§ã¹ã³ã¢ãªã³ã°ããŸããã æ®å¿µãªãããããŒã«ãæ»ãããããšã¯ã§ããŸããã§ããã
ããåçïŒå³ïŒ0-éçºè
ã¯æ³å®ããUICollectionViewFlowLayoutã¯

ã¹ã¯ãªãŒã³ã·ã§ããã§2ã€ã®ããšãããããŸãã
- æåïŒUICollectionViewFlowLayoutã¯ãæäžè¡ã®èŠçŽ ã®äžå¿ãäžã®èŠçŽ ã®äžå¿ããäžã«ãªãããã«èŠçŽ ãé
眮ããŸãã äžèšã§èšãã°ãããã«ã¯è»¢ãããŸããã
- 2çªç®ïŒäŸãšããŠãç§ã¯ãã·ã¥ãã¬ããã£ãºã ã®åµå§è
ã®åäœãèæ¯ã«ãåè¡èžè¡å®¶ã«ãããŸã æžãããŠããªãçµµç»ãæçš¿ããããšã«ããŸãã
RFQuiltLayout
ç§ã®ã°ãŒã°ã«ã¹ãã«ãéåžžã«åŒ±ããã
RFQuiltLayoutãç§ã®å Žåã¯å¯äžã®ã¿ãŒã³ããŒãœãªã¥ãŒã·ã§ã³ã§ãã
ãã®ã¯ã©ã¹ã¯ãããã©ã«ãã®ã»ã«ãµã€ãºCGSizeãæ ŒçŽããå€æ°blockPixelsã䜿çšããŸãã ããªã²ãŒãã¡ãœãã
- (CGSize) blockSizeForItemAtIndexPath:(NSIndexPath *)indexPath;
åã»ã«ã®blockPixelsã®ä¹æ°ãè¿ããŸãã ã€ãŸããblockPixels = {100ã100}ãblockSizeForItemAtIndexPath = {2.2ã0.8}ã®å Žåãã»ã«ã®ãµã€ãºã¯{220ã80}ã«ãªããŸãã
ç§ã®æèŠã§ã¯ãããã¯å°ãå¥åŠãªã·ã¹ãã ã§ããblockPixelsã{1ã1}ã«èšå®ããããªã²ãŒãã¡ãœããã§èŠçŽ ã«å¿
èŠãªãµã€ãºãè¿ããŸããããã®å Žåã®é
眮ã¢ã«ãŽãªãºã ã¯15èŠçŽ ã§ãéåžžã«æéãããããé
眮ããã®ã«100èŠçŽ ãå¿
èŠã§ãèšç®èœåã¯iPadãããæ¥æ¿ã§ãã å¿èã®ã¢ã«ãŽãªãºã ãå解ããã®ã«ååãªæéããªãã£ãã®ã§ãéžææ¹æ³ã«ãã£ãŠblockPixelsã®å€{20ã20}ãéžæããŸãããããã«ããã15åã®ã»ã«ã§éåžžã®ããã©ãŒãã³ã¹ãšè¯å¥œãªé
眮粟床ãåŸãããŸããã
åŒãè£ããããšããžãäœæããã«ã¯ãå°ãããªãã¯ã䜿çšããå¿
èŠããããŸãã-å®éãã»ã«ã®ãµã€ãºèªäœã«ã¯è§ŠããŸããã§ãããé
眮ã®æ®µéã§ã»ã«ãã©ã®è¡ã«ããããèŠã€ããããšãã§ããŸããã§ããããåçãã€ã³ã¹ããŒã«ãããšãã«è¡ããã§ãã¯ããæåãšæåŸã®è¡ã®è¡ã®é«ããæžãããŸããåçã ç»åã¯äžäžãããããã«ããªãã³ã°ãããŸããã åçãããªãã³ã°ã®äžã«ããããããããŒãã¬ãŒãã§ãã£ãå Žåã人ã
ã¯èžã®å ãšåºã倱ããããããäžåœã®çœ®ç©ã§ãã£ãå Žåããã©ãŽã³ã¯çŽç« ãªãã§è¡šç€ºããããã«ã·ã£çµšæ¯¯ã§ç§ã®æ±ãããã¯ã¯å±±ãåããŸããã ããããã¯ã©ã€ã¢ã³ãã¯æºè¶³ããŸãããã€ãŸããæè¡ä»æ§ããããã«ä¿®æ£ããããŸã§ãç§ãåãã§ããŸããã ã¡ã€ã³ç»é¢ã®åããªèŠçŽ ã®ä»£ããã«ããã¹ãŠã®ãããã衚瀺ãããŠããã¯ãã§ãã ãã¹ãŠ1500ã
ããå€ãã®èžè¡ïŒ
çµµç»ãè±ç¶ããã¹ã€ã®çœ®ç©ããã®ä»ãã¹ãŠã®1500ã®ç»åããå£ããçŸããã§ãã å³ããçå®ã¯ããµãŒãããŒãã£ã®ãœãªã¥ãŒã·ã§ã³ãç§ãæã£ããšããããšã§ã¯ãããŸããã§ããã ããã§ã¯ããã¬ãŒã¹ã¡ã³ããããŒãžã£ãŒãäœæããŸãããã
äºæ³ãããããã«ããã·ã¢èªã§æ
å ±ãèŠã€ããããšã¯ã§ããŸããã§ããïŒããŸãæåŸ
ããŠããŸããã§ããïŒããäžå¿
èŠã§å°ãªããšãå°ã圹ã«ç«ã€è±èªã®æåž«ã¯ãäœãšãããŠåŸç¹ããŸããã§ããæ€çŽ¢çµæã®æåã®10ããŒãžã çµæãšããŠãç§ã®ããã¥ã¢ã«ã¯ãå®éã«ã¯ã
Appleã®ããã¥ã¡ã³ããšäžèšã®RFQuiltLayoutã³ãŒãã§ããïŒãšããã§ãèè
ã®Bryce Reddã«æè¬ã®æãè¡šãããïŒã
SKRaggyCollectionViewLayout
ããã«ã¯ã©ã¹ã®æããªååããaã³ããŸãã
æåã«ãããªã²ãŒãã®ãããã³ã«ãå®çŸ©ããŸããã
@protocol SKRaggyCollectionViewLayoutDelegate <UICollectionViewDelegate> - (float)collectionLayout:(SKRaggyCollectionViewLayout*)layout preferredWidthForItemAtIndexPath:(NSIndexPath *)indexPath; @optional - (UIEdgeInsets)collectionLayout:(SKRaggyCollectionViewLayout*)layout edgeInsetsForItemAtIndexPath:(NSIndexPath *)indexPath; @end
ããªã²ãŒãã¯ã»ã«ã®é«ãã«åœ±é¿ãäžããããšãã§ããªããããç¹å®ã®ã»ã«ã§èŠããå¹
ã ãããããŒãžã£ãŒã«æž¡ããŸãã ããŠãUIEdgeInsetsïŒã»ã«ã®å
éšããã£ã³ã°ïŒãè¿ãã¡ãœããã¯ããããªãã§ã
ãããŠãã¡ãããè¡æ°ãæ ŒçŽããããããã£ã¯ã3è¡ã ãã§ãªããæ£æ©ã®ããã«æ©ãããšã§ãããã¯ã©ã¹ããŠãããŒãµã«ã«ããããšã§ãïŒ
@property (nonatomic, assign) NSUInteger numberOfRows;
ä»å®è£
ã
Appleã¯ãè£è¶³ãã¥ãŒãè£
食ãã¥ãŒãªã©ãUICollectionViewã®è¿œå èŠçŽ ã«ç
©ããããããªãå Žåã¯ãå°ãªããšã次ã®ã¡ãœããããªãŒããŒã©ã€ãããå¿
èŠããããšèšã£ãŠããŸãã
- (CGSize)collectionViewContentSize; - (NSArray*)layoutAttributesForElementsInRect:(CGRect)bounds; - (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath; - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;
åŸè
ã§ã¯ããã¹ãŠãæ確ã§ã-newBoundsãã³ã¬ã¯ã·ã§ã³ã®çŸåšã®å¢çã«äžèŽããªãå Žåã¯YESãè¿ããŸãã
æåã®ã¡ãœããã¯åŸã§å®è£
ããããããã«æ®ããlayoutAttributesForItemAtIndexPathã¡ãœããã«é²ã¿ãŸãããã ãã®ååããæãããªããã«ãåèŠçŽ ã®
UICollectionViewLayoutAttributesãèšç®ããå¿
èŠããããŸãã UICollectionViewLayoutAttributesã¯ã©ã¹ã®ãªããžã§ã¯ãã«ã¯ãã»ã«ã®ããããçš®é¡ã®ãããããããäœæã§ããtransform3Dãå«ãããªããžã§ã¯ãã®å Žæã«é¢ããå€ãã®æ
å ±ãå«ãŸããŠããŸããããã®å Žåã¯ãã£ã1ã€ã®ãã¬ãŒã ãå®è¡ã§ããŸãã
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UIEdgeInsets insets = UIEdgeInsetsZero; if ([self.delegate respondsToSelector:@selector(collectionLayout:edgeInsetsForItemAtIndexPath:)]) { insets = [self.delegate collectionLayout:self edgeInsetsForItemAtIndexPath:indexPath]; }
å®éãèå³æ·±ãããšã¯ãããŸãã-ããªã²ãŒãããUIEdgeInsetsãååŸããŸããããªã²ãŒããæäŸããå ŽåãframeForIndexPathã¡ãœããã䜿çšããŠãã¬ãŒã ãååŸããåä¿¡ããUIEdgeInsetsããã³CGRectã§å±æ§ãäœæããŠè¿ããŸãã ããããframeForIndexPathã¡ãœããã§ã¯ãã·ã£ãŒãããºã ã®äž»èŠéšåã¯ç§ããé ãããŠããŸãã
- (CGRect)frameForIndexPath:(NSIndexPath*)path {
ç§ã®ãã¹ã¿ã³ãŒããšåè±èªã®ã³ã¡ã³ããããŸãæ確ã§ãªãå Žåã¯ãç䌌ã³ãŒããããæ確ã«
æ··ä¹±ãããããšããŸãã
ããã«ãã[以åã«èšç®ãããã¬ãŒã ãindexPathããŒã䜿çšããŠä¿åããNSMutableDictionaryãåç
§ããŸããåå©ã§ããããšãããã£ãå Žåããã以äžã®ããšã¯ãããŸãã]
[èšç®ãé¿ããããªãå ŽåãæåŸã®ãã¬ãŒã ã®å³å¢çãããŒãã«ã®å
é ã«æãè¿ãè¡ãèŠã€ããŸã-ããã§ãçŸåšã®èŠçŽ ãé
眮ããå¿
èŠããããŸãïŒåè¡ã®x座æšã¯NSMutableArray edgeXPositionsã«æ ŒçŽãããŸãïŒ]
[ããã§ãX軞ã®è¡ãšäœçœ®ãããã³èŠçŽ ã®ããªã²ãŒããå¿
èŠãšããå¹
ãç¥ã£ãŠããã®ã§ãå·Šäžé
ã®äœçœ®ãèšç®ã§ããŸãã ã³ã¬ã¯ã·ã§ã³ã®é«ããšè¡æ°ãããã£ãŠããã®ã§ãåæã«èŠçŽ ã®é«ããèšç®ããŸã]
[æªåé«ããåŒãè£ããããšããžããå¿
èŠã§ãè¡ãæåãŸãã¯æåŸã®å Žåãèšç®ãããé«ãããããã«æžãããŸã]
[é«ãã1æªæºã®å Žåã¯å®å
šã«åçããé«ãã®æžå°ã«æ¯äŸããŠå¹
ãçž®å°ããŸã]
[å°æ¥ã®è¿
éãªã¢ã¯ã»ã¹ãšã¡ãœããããã®æ»ãã®ããã«ãååŸããå€ãindexPathsByFrameããã³framesByIndexPathãã£ã¯ã·ã§ããªã«ä¿åããŸã]
ãšããã§ãinvalidateLayoutã¡ãœããã§ãããã®indexPathsByFrameãframesByIndexPathãwhat-else-is-cachedããã¹ãŠã¯ãªã¢ããããšãå¿ããŠã¯ãªããŸããã åœç¶ã[super invalidateLayout]ãæ¬ èœããŠããŸããã
contentSizeã«æ»ããŸãã æããã«ãæ°Žå¹³ã¹ã¯ããŒã«ã®å Žåã次ã®ããã«ãªããŸãã
- (CGSize)collectionViewContentSize { return CGSizeMake(self.edgeX, self.collectionView.frame.size.height); }
ããã§ãedgeXã¯æãé ãã«ããã»ã«ã®X座æšã§ãã çµå±ã®ãšããããã¹ãŠã®ã»ã«ãã©ã®ããã«é
眮ãããŠãããã¯ãã§ã«ããã£ãŠããŸãã ãŸãã¯ããããªãã ãŸãã¯ããŸã ããã£ãŠããŸã...確ãã«ããã®äžã§[super prepareLayout]ãåŒã³åºãããšãå¿ããã«prepareLayoutã¡ãœãããåå®çŸ©ããåã»ã«ã®ãã¬ãŒã ãèšç®ããå¿
èŠããããŸã
- (void)prepareLayout { [super prepareLayout];
ã¯ããæ°åäžåã®ã»ã«ãããå Žåãã³ã¬ã¯ã·ã§ã³ãæ¥ãã§ããŒãããããšã¯ãããŸããããä»ã«äºçŽ°ãªæ¹æ³ã¯ãããŸããã
æåŸã«ãæåŸã®ã¡ãœããã§ããlayoutAttributesForElementsInRectããªãŒããŒã©ã€ãããŸãã ãã®äžã§ããã®é åã«è©²åœãããã¹ãŠã®èŠçŽ ã®å±æ§ãè¿ãå¿
èŠããããŸãã ã³ã¬ã¯ã·ã§ã³ããã®ãã¬ãŒã ã®ãµã€ãºã«ã¹ã¯ããŒã«ããããã³ã«åŒã³åºãããŸãã ãã®åŸãããã¯ãã¹ãŠãã£ãã·ã¥ãããŠããããã«èŠãããããã¡ãœããã¯contentSize.width / frame.size.widthåã ãåŒã³åºãããŸãã
ãé¡ããšåŒã°ãããã®ã®ç§ã®å®è£
ïŒåèŠçŽ ã®ãã¬ãŒã ã調ã¹ããããããã®é åãšäº€å·®ããå Žåãè¿ãããé
åã«è¿œå ããŸãã
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)bounds { if (CGRectEqualToRect(bounds, self.previousLayoutRect)) { return self.previousLayoutAttributes; } [self.previousLayoutAttributes removeAllObjects]; self.previousLayoutRect = bounds; NSArray *allFrames = self.framesByIndexPath.allValues; for (NSValue *frameValue in allFrames) { CGRect rect = [frameValue CGRectValue]; if (CGRectIntersectsRect(rect, bounds)) { [self.previousLayoutAttributes addObject:[self layoutAttributesForItemAtIndexPath:[self.indexPathsByFrame objectForKey:[NSValue valueWithCGRect:rect]]]]; } } return self.previousLayoutAttributes; }
çµµãããã¯ãã§ããããããã§ã¯ãããŸããç·šéãããæçš¿ã®å€æŽãä¿åããåŸãhabrãšã³ãžã³ãé©ãã»ã©æ¯åãããåé€ããããã§ã
ãã¹ãŠãæ£åžžã«æ©èœãããšããäºå®ã«å¯Ÿãã幞çŠæãéãå»ã£ãçŽåŸã«ãç§ã®å
éšã®ä»äºäžæ¯è
ã¯è©æ±ºãåºããŸããïŒæé©åããããã«ïŒ ããããã¯ãŒã«ããªãã¯ããã匷ãããšãå€æãããã®å
ãªãèªå·±ã¯ãèšæ¶ã®è
žãããææå°æ©ãªæé©åããšãããã¬ãŒãºãåŸãŠã1äžåã®èŠçŽ ããã£ãŠãiPad 2ã§ã®ãã¹ãã§ã¯é床äœäžãèŠãããªãã£ããšããäºå®ã®èåŸã«é ããŠããã°ããã®éæé©åã延æããããšã«ããŸããã
ããšãã
誰ããèå³ãæã¡ã誰ããæçšã§ãããæ®ãã¯ãã®æçš¿ãèªãã ãã®å¿èãæã£ãŠãããšæããŸãã ãæž
èŽããããšãããããŸããã
æåŸã«ãããã€ãã®ãªã³ã¯ïŒ
PS圌ãã¯ãã§ã«æåŸã®ãã¿ãã¬ã«ã¯çµµããªããšç§ã«æžããã åãæäœã3åè¡ããŸãããããã·ã³ã°ãªã³ã¯ãæ¿å
¥ããŠç·šéããä¿åããå€æŽãçºçããããšã確èªããããŒãžãéããå床éããŠåªãããããŸãã-ç»åãåã³æ¶ããŸããã ããã«ãåãç¶æ³ã«ã€ãªããã¯ãã®ãªã³ã¯
Or right here㯠ããã®æ©èœç矩åãæããã®ããããŸããã ãã©ãã«ã
念ã®ããããã®äžæ£ãªãªã³ã¯ãåã«ããã¹ãã§ããã«æ®ããŸã
habr.habrastorage.org/post_images/0e1/0c7/be4/0e10c7be44690901268d5dfa9e532d0e.png