Cell spacing in UICollectionView

后端 未结 26 3272
旧巷少年郎
旧巷少年郎 2020-11-22 15:53

How do I set cell spacing in a section of UICollectionView? I know there is a property minimumInteritemSpacing I have set it to 5.0 still the spaci

相关标签:
26条回答
  • 2020-11-22 16:35

    I know that the topic is old, but in case anyone still needs correct answer here what you need:

    1. Override standard flow layout.
    2. Add implementation like that:

      - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
          NSArray *answer = [super layoutAttributesForElementsInRect:rect];
      
          for(int i = 1; i < [answer count]; ++i) {
              UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
              UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
              NSInteger maximumSpacing = 4;
              NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
      
              if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
                  CGRect frame = currentLayoutAttributes.frame;
                  frame.origin.x = origin + maximumSpacing;
                  currentLayoutAttributes.frame = frame;
              }
          }
          return answer;
      }
      

    where maximumSpacing could be set to any value you prefer. This trick guarantees that the space between cells would be EXACTLY equal to maximumSpacing!!

    0 讨论(0)
  • 2020-11-22 16:36

    I'm using monotouch, so the names and code will be a bit different, but you can do this by making sure that the width of the collectionview equals (x * cell width) + (x-1) * MinimumSpacing with x = amount of cells per row.

    Just do following steps based on your MinimumInteritemSpacing and the Width of the Cell

    1) We calculate amount of items per row based on cell size + current insets + minimum spacing

    float currentTotalWidth = CollectionView.Frame.Width - Layout.SectionInset.Left - Layout.SectionInset.Right (Layout = flowlayout)
    int amountOfCellsPerRow = (currentTotalWidth + MinimumSpacing) / (cell width + MinimumSpacing)
    

    2) Now you have all info to calculate the expected width for the collection view

    float totalWidth =(amountOfCellsPerRow * cell width) + (amountOfCellsPerRow-1) * MinimumSpacing
    

    3) So the difference between the current width and the expected width is

    float difference = currentTotalWidth - totalWidth;
    

    4) Now adjust the insets (in this example we add it to the right, so the left position of the collectionview stays the same

    Layout.SectionInset.Right = Layout.SectionInset.Right + difference;
    
    0 讨论(0)
  • 2020-11-22 16:38

    If u want to tweak the spacing without touching the actual cell size, this is the solution that worked best for me. #xcode 9 #tvOS11 #iOS11 #swift

    So in UICollectionViewDelegateFlowLayout, change implement the next methods, the trick is u have to use both of them, and the documentation was not really pointing me to think in that direction. :D

    open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return cellSpacing
    }
    
    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return cellSpacing
    }
    
    0 讨论(0)
  • 2020-11-22 16:38

    My solution in Swift 3 cell line spacing like in Instagram:

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = UIColor.rgb(red: 227, green: 227, blue: 227)
        cv.showsVerticalScrollIndicator = false
        layout.scrollDirection = .vertical
        layout.minimumLineSpacing = 1
        layout.minimumInteritemSpacing = 1
        return cv
    }()
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    
        switch UIDevice.current.modelName {
        case "iPhone 4":
            return CGSize(width: 106, height: 106)
        case "iPhone 5":
            return CGSize(width: 106, height: 106)
        case "iPhone 6,7":
            return CGSize(width: 124, height: 124)
        case "iPhone Plus":
            return CGSize(width: 137, height: 137)
        default:
            return CGSize(width: frame.width / 3, height: frame.width / 3)
        }
    }
    

    How to detect device programmaticlly: https://stackoverflow.com/a/26962452/6013170

    0 讨论(0)
  • 2020-11-22 16:38

    I had done every thing just fine except setting :

    layout.scrollDirection = .horizontal
    
    0 讨论(0)
  • 2020-11-22 16:39

    Define UICollectionViewDelegateFlowLayout protocol in your header file.

    Implement following method of UICollectionViewDelegateFlowLayout protocol like this:

    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
    {
        return UIEdgeInsetsMake(5, 5, 5, 5);
    }
    

    Click Here to see Apple Documentation of UIEdgeInsetMake method.

    0 讨论(0)
提交回复
热议问题