Search code examples
objective-cswiftuicollectionviewlayout

How to transfer Object c to Swift aout collectionVIewLayout


I have took below website as reference, and tried to convert this to Swift code. Refer to “collectioViewLayout” part, I have difficulties to make things in order.

Appreciated that.UICollectionVIew circlesLayout

The original code is as below:-

- (CGSize)sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
if ([[self.collectionView.delegate class] conformsToProtocol:@protocol(UICollectionViewDelegateFlowLayout)]) {
    return [(id)self.collectionView.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
}
return CGSizeMake(0, 0);}

My revised swift code as follows:-

func sizeForItem(at indexPath: IndexPath?) -> CGSize {
    if type(of: collectionView.delegate) is UICollectionViewDelegateFlowLayout {
        if let indexPath = indexPath {
            return collectionView!.delegate?.collectionView!(collectionView!, layout: self, sizeForItemAt: indexPath) ?? CGSize.zero
        }
        return CGSize.zero
    }
    return CGSize(width: 0, height: 0)
}

However, some errors appeared. (see below)

Part 1) Cast from 'UICollectionViewDelegate?.Type' to unrelated type 'UICollectionViewDelegateFlowLayout' always fails

Part 2) Incorrect argument labels in call (have ':layout:sizeForItemAt:', expected':targetIndexPathForMoveFromItemAt:toProposedIndexPath:')

Is there anyone who can guide me how to fix those problem into correct swift code please?


Solution

  • The Objective-C code checks the type of collectionView.delegate, but in Swift you have to do a cast to tell the compiler that you are sure that it is indeed of type UICollectionViewDelegateFlowLayout{

    func sizeForItem(at indexPath: IndexPath?) -> CGSize {
        // "as?" does the cast, evaluating the expression to nil if it fails.
        if let delegate = collectionView!.delegate as? UICollectionViewDelegateFlowLayout,
            // you can combine these two checks into one if statement. Just separate them with ","
            let indexPath = indexPath {
            return delegate.collectionView?(collectionView, layout: self, sizeForItemAt: indexPath) ?? .zero
        }
        return .zero
    }