美文网首页collectionView
UICollectionView靠左显示的Layout代码(sw

UICollectionView靠左显示的Layout代码(sw

作者: l富文本l | 来源:发表于2019-07-09 18:15 被阅读0次
    屏幕快照 2019-07-09 下午6.15.57.png

    实现如上效果

    layout

    import UIKit
    
    protocol UICollectionViewDelegateLeftAlignedLayout: UICollectionViewDelegateFlowLayout {
        
    }
    
    extension UICollectionViewLayoutAttributes {
        func leftAlignFrame(with sectionInset: UIEdgeInsets) {
            var frame = self.frame
            frame.origin.x = sectionInset.left
            self.frame = frame
        }
    }
    
    class LCYSearchFlowLayout: UICollectionViewFlowLayout {
    
        //layoutAttributesForElementsInRect方法 ---------------
        /*
         rect初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定。
         返回在collectionView的可见范围内(bounds)所有item对应的layoutAttrure对象装成的数组。collectionView的每个item都对应一个专门的UICollectionViewLayoutAttributes类型的对象来表示该item的一些属性,比如bounds,size,transform,alpha等。
         */
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            guard let originalAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
            let updatedAttributes = NSMutableArray.init(array: originalAttributes)
            
            for attribute in originalAttributes {
                /*
                 @property(nonatomic, readonly) UICollectionElementCategory representedElementCategory;
                 Item的类型。
                 你可以使用这个属性的值来区分这个布局属性是用于一个Cell还是Supplementary View还是Decoration View。
                 
                 
                 @property(nonatomic, readonly) NSString *representedElementKind;
                 目标视图的布局指定标识符。
                 你可以使用这个属性的值来标识Supplementary View或者Decoration View相关联的属性给定的目的。如果representedElementCategory属性为UICollectionElementCategoryCell,那么这个属性为nil。
                 */
                if (attribute.representedElementKind == nil) {
                    let index = updatedAttributes.index(of: attribute)
                    //layoutAttributesForItemAtIndexPath:返回对应于indexPath的位置的cell的布局属性,这个方法被重写了
                    updatedAttributes[index] = self.layoutAttributesForItem(at: attribute.indexPath) as Any
                }
            }
            
            return (updatedAttributes as! [UICollectionViewLayoutAttributes])
        }
        
        //重写了
        override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
            
            //当前的UICollectionViewLayoutAttributes
            let currentItemAttributes = super.layoutAttributesForItem(at: indexPath)?.copy() as! UICollectionViewLayoutAttributes
    
            let sectionInset = self.evaluatedSectionInsetForItem(at: indexPath.section)
            
            let isFirstItemInSection: Bool = indexPath.item == 0
            //如果是第一个那就直接返回就行
            if isFirstItemInSection {
                currentItemAttributes.leftAlignFrame(with:sectionInset)
                return currentItemAttributes
            }
            
            let layoutWidth: CGFloat = (self.collectionView?.frame.size.width)! - sectionInset.left - sectionInset.right
            
            let previousIndexPath = NSIndexPath.init(item: indexPath.item - 1, section: indexPath.section)
            
            let previousFrame = self.layoutAttributesForItem(at: previousIndexPath as IndexPath)?.frame
            
            let previousFrameRightPoint = (previousFrame?.origin.x)! + previousFrame!.size.width
            
            let currentFrame = currentItemAttributes.frame
            
            let strecthedCurrentFrame = CGRect(x: sectionInset.left, y: currentFrame.origin.y, width: layoutWidth, height: currentFrame.size.height)
            
            //如果不想交说明是这一行的第一个
            let isFirstItemInRow = !previousFrame!.intersects(strecthedCurrentFrame)
            
            if isFirstItemInRow {
                currentItemAttributes.leftAlignFrame(with: sectionInset)
                return currentItemAttributes
            }
            
            //放到之前的item的右侧
            
            var frame = currentItemAttributes.frame
            frame.origin.x = previousFrameRightPoint + self.evaluatedMinimumInteritemSpacingForSection(at: indexPath.section)
            
            currentItemAttributes.frame = frame
            
            return currentItemAttributes
            
        }
        
        // 计算section的inset
        func evaluatedSectionInsetForItem(at index: NSInteger) -> UIEdgeInsets {
    
            if (self.collectionView?.delegate?.responds(to: #selector(UICollectionViewDelegateFlowLayout.collectionView(_:layout:insetForSectionAt:))))! {
                
                let delegate = self.collectionView?.delegate as! UICollectionViewDelegateLeftAlignedLayout
                
                return (delegate.collectionView?(self.collectionView!, layout: self, insetForSectionAt: index))!
                
            } else {
                return sectionInset
            }
            
        }
        
        func evaluatedMinimumInteritemSpacingForSection(at index: NSInteger) -> CGFloat {
            if (self.collectionView?.delegate?.responds(to: #selector(UICollectionViewDelegateFlowLayout.collectionView(_:layout:minimumInteritemSpacingForSectionAt:))))! {
                let delegate = self.collectionView?.delegate as! UICollectionViewDelegateFlowLayout
                return (delegate.collectionView?(self.collectionView!, layout: self, minimumInteritemSpacingForSectionAt: index))!
            } else {
                return self.minimumInteritemSpacing
            }
        }
        
    }
    
    

    根据文字计算宽高

        func settingCollectionViewItemWidthBounding(with text: String) -> CGSize {
            let sizeWidth = CGSize(width: CGFloat(MAXFLOAT), height: 20)
            let sizeHeight = CGSize(width: screenWidth - 40, height: CGFloat(MAXFLOAT))
            
            let attributeDic = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14)]
            let frameWidth = text.boundingRect(with: sizeWidth, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributeDic, context: nil)
            
            let frameHeight = text.boundingRect(with: sizeHeight, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributeDic, context: nil)
            
            var finalSize = CGSize(width: frameWidth.size.width + 21, height: 30)
            
            if frameWidth.size.width > screenWidth - 40 {
                finalSize = CGSize(width: screenWidth - 40, height: frameHeight.size.height + 10)
            }
            
            return finalSize
            
        }
    

    相关文章

      网友评论

        本文标题:UICollectionView靠左显示的Layout代码(sw

        本文链接:https://www.haomeiwen.com/subject/mwyfkctx.html