1

我目前正在關注本教程(https://www.raywenderlich.com/99087/swift-expanding-cells-ios-collection-views),它創建了一個自定義UICollectionViewLayout,問題在於本教程是用Swift編寫的,但我試圖將它轉換爲Objective- C爲我的項目。UICollectionViewLayout(從Swift轉換到Objective-C)

將教程複製到Objective-C中的第一部分很好,我已經到了這個階段。 enter image description here

雖然,在當我們想創建一個自定義UICollectionViewLayout第二部分,並在故事板的CollectionView的佈局,以定製和改變設置自定義類,出現空白屏幕。

下面是我想從教程轉載自斯威夫特的Objective-C代碼:

@implementation TimetableCustomLayout{ 
    NSMutableArray *cache; 
} 

-(NSInteger)featuredItemIndex{ 

CGFloat dragOffset = 180; 
    return MAX(0, self.collectionView.contentOffset.y - dragOffset); 
} 

-(CGFloat)nextItemPercentageOffset{ 
    CGFloat dragOffset = 180; 
    return (self.collectionView.contentOffset.y/dragOffset) - [self featuredItemIndex]; 
} 

-(CGFloat)width{ 
    return CGRectGetWidth(self.collectionView.bounds); 
} 

-(CGFloat)height{ 
    return CGRectGetHeight(self.collectionView.bounds); 
} 

-(NSInteger)numberOfItems{ 
    //Will be replaced with dynamic value later 
    return 5; 
} 


-(CGSize)collectionViewContentSize{ 

    CGFloat dragOffset = 180; 



    return CGSizeMake([self height], [self width]); 
} 


-(void)prepareLayout{ 

    [super prepareLayout]; 
    cache = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil]; 

    self.standardHeight = 100; 
    self.featuredHeight = 280; 

    CGRect frame = CGRectZero; 
    CGFloat y = 0; 

    for(int item = 0; item < 5; item ++){ 
     NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:0]; 
     UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 

     attributes.zIndex = item; 
     CGFloat height = self.standardHeight; 

     if(indexPath.item == [self featuredItemIndex]){ 
      CGFloat yOffset = self.standardHeight * [self nextItemPercentageOffset]; 
      y = self.collectionView.contentOffset.y - yOffset; 

      height = self.featuredHeight; 

    }else if(indexPath.item == ([self featuredItemIndex] + 1) && indexPath.item != [self numberOfItems]){ 
      CGFloat maxY = y + self.standardHeight; 
      height = self.standardHeight + MAX((self.featuredHeight - self.standardHeight) * [self nextItemPercentageOffset], 0); 
      y = maxY - height; 
    } 

     frame = CGRectMake(0, y, [self width], [self height]); 
    attributes.frame = frame; 
     [cache addObject:attributes]; 

     y = CGRectGetMaxY(frame); 

    } 

} 

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 
{ 
    [super layoutAttributesForElementsInRect:rect]; 



    NSMutableArray *layoutAttributes = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil]; 

    NSLog(@"%@", cache); 

    for(UICollectionViewLayoutAttributes *attributes in cache){ 
     if(CGRectIntersectsRect(attributes.frame, rect)){ 
      [layoutAttributes addObject:attributes]; 
     } 
    } 

    return layoutAttributes; 

} 


-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{ 
    return true; 
} 

@end 

我也越來越錯誤,終止應用程序由於未捕獲的異常「NSInvalidArgumentException」,原因:' + [UICollectionViewLayoutAttributes框架]:無法識別的選擇器。

我認爲錯誤可能是由於不正確的翻譯,從斯威夫特的Objective-C,特別是這條線,

斯威夫特:

var cache = [UICollectionViewLayoutAttributes]() 

的Objective-C:

NSMutableArray *layoutAttributes = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil]; 

這是我在StackOverflow上的第一個問題,任何反饋和幫助將不勝感激,在此先感謝。

回答

2

您正在初始化時將對UICollectionViewLayoutAttributes類的引用添加到cachelayoutAttributes數組中。然後,調用frame屬性給類引用(注意表示類方法的錯誤消息的+,其中實例方法使用-)。

替換此行:

NSMutableArray *layoutAttributes = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil]; 

有了這個:

NSMutableArray *layoutAttributes = [[NSMutableArray alloc] init]; 

這同樣適用於cache變量初始化。


您也可以使用泛型使用Objective-C的類型安全數組:

NSMutableArray<UICollectionViewLayoutAttributes*> *layoutAttributes = [[NSMutableArray alloc] init]; 

更多信息here