iOS Swift Assortment View Customized Format

Spread the love


I’m making an attempt to realize the next outcome.
Authentic Format

My Code Consequence:
Customized Format

My Customized Movement Format Code:

public class LGHorizontalLinearFlowLayout: UICollectionViewFlowLayout {
    
    personal var lastCollectionViewSize: CGSize = CGSize.zero
    public var scalingOffset: CGFloat = 110
    public var minimumScaleFactor: CGFloat = 0.9
    public var scaleItems: Bool = true
    
    static func configureLayout(collectionView: UICollectionView, itemSize: CGSize, minimumLineSpacing: CGFloat, scaleItems: Bool) -> LGHorizontalLinearFlowLayout {
        
        let format = LGHorizontalLinearFlowLayout()
        format.scrollDirection = .horizontal
        format.minimumLineSpacing = minimumLineSpacing
        format.itemSize = itemSize
        format.scaleItems = scaleItems
        
        collectionView.decelerationRate = UIScrollView.DecelerationRate.quick
        collectionView.collectionViewLayout = format
        
        return format
    }
    
    override public func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {
        tremendous.invalidateLayout(with: context)
        
        if self.collectionView == nil {
            return
        }
        
        let currentCollectionViewSize = self.collectionView!.bounds.dimension
        
        if !currentCollectionViewSize.equalTo(self.lastCollectionViewSize) {
            self.configureInset()
            self.lastCollectionViewSize = currentCollectionViewSize
        }
    }
    
    personal func configureInset() -> Void {
        if self.collectionView == nil {
            return
        }
        let inset = self.collectionView!.bounds.dimension.width / 2 - self.itemSize.width / 2
        self.collectionView!.contentInset = UIEdgeInsets.init(high: 0, left: inset, backside: 0, proper: inset)
        self.collectionView!.contentOffset = CGPoint(x:-inset, y:0)
    }
    
    public override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        if self.collectionView == nil {
            return proposedContentOffset
        }
        
        let collectionViewSize = self.collectionView!.bounds.dimension
        let proposedRect = CGRect(x:proposedContentOffset.x, y:0, width:collectionViewSize.width, top:collectionViewSize.top)
        
        let layoutAttributes = self.layoutAttributesForElements(in: proposedRect)
        
        if layoutAttributes == nil {
            return proposedContentOffset
        }
        
        var candidateAttributes: UICollectionViewLayoutAttributes?
        let proposedContentOffsetCenterX = proposedContentOffset.x + collectionViewSize.width / 2
        
        for attributes: UICollectionViewLayoutAttributes in layoutAttributes! {
            if attributes.representedElementCategory != .cell {
                proceed
            }
            
            if candidateAttributes == nil {
                candidateAttributes = attributes
                proceed
            }
            
            if abs(attributes.middle.x - proposedContentOffsetCenterX) < abs(candidateAttributes!.middle.x - proposedContentOffsetCenterX) {
                candidateAttributes = attributes
            }
        }
        
        if candidateAttributes == nil {
            return proposedContentOffset
        }
        
        var newOffsetX = candidateAttributes!.middle.x - self.collectionView!.bounds.dimension.width / 2
        
        let offset = newOffsetX - self.collectionView!.contentOffset.x
        
        if (velocity.x < 0 && offset > 0) || (velocity.x > 0 && offset < 0) {
            let pageWidth = self.itemSize.width + self.minimumLineSpacing
            newOffsetX += velocity.x > 0 ? pageWidth : -pageWidth
        }
        
        return CGPoint(x:newOffsetX, y:proposedContentOffset.y)
    }
    
    public override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }
    
    public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        if !self.scaleItems || self.collectionView == nil {
            return tremendous.layoutAttributesForElements(in: rect)
        }
        
        let superAttributes = tremendous.layoutAttributesForElements(in: rect)
        
        if superAttributes == nil {
            return nil
        }
        
        let contentOffset = self.collectionView!.contentOffset
        let dimension = self.collectionView!.bounds.dimension
        
        let visibleRect = CGRect(x:contentOffset.x, y:contentOffset.y, width:dimension.width, top:dimension.top)
        let visibleCenterX = visibleRect.midX
        
        var newAttributesArray = Array<UICollectionViewLayoutAttributes>()
        for (_, attributes) in superAttributes!.enumerated() {
            let newAttributes = attributes.copy() as! UICollectionViewLayoutAttributes
            newAttributesArray.append(newAttributes)
            
            let distanceFromCenter = visibleCenterX - newAttributes.middle.x
            var defaultCenter = newAttributes.middle
            if distanceFromCenter == 0 {
                proceed
            }
            else if distanceFromCenter > 0 {
                defaultCenter.x -= min(distanceFromCenter,20)
            } else if distanceFromCenter < 0 {
                defaultCenter.x += min(abs(distanceFromCenter),20)
            }
            newAttributes.middle = defaultCenter
        }
        
        return newAttributesArray;
    }
    
}

The cells are usually not being centered accurately.
I’ve tried taking part in with cell sizes however quickly realized i’m losing my time and may give attention to its positions as an alternative.
Any assist could be a lot appreciated. Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *