The collectionView is used to make a label style. The label needs to be wrapped according to the width of the collectionView. We usually use a custom set of flowLayout to meet such requirements.

Import SwiftUI /// Enumeration of alignment directions, enum AlignDirection: Int {case left = 0, // align rightFlow left, // align rightData left, Align right up the display center / / / / right alignment among} class CollectionViewAlignFlowLayout: UICollectionViewFlowLayout {/ / the default left alignment var alignDirection: alignDirection. = left / / all the layout of the cell properties var layoutAttributes: [UICollectionViewLayoutAttributes] = [] / / collectionViewContentSize collectionView the actual size of private var contentSize: CGSize = CGSize.zero override var collectionViewContentSize: CGSize { if self.scrollDirection == .vertical { return CGSize.init(width: self.collectionView! .frame.width, height: contentSize.height) } return CGSize.init(width: contentSize.width, height: self.collectionView! .frame.height) } override init() { super.init() } required init?(coder aDecoder: NSCoder) { super.init(coder: Override func prepare() {super.prepare() contentSize = cgsize.zero Int = self.collectionView! . NumberOfItems (inSection: 0) / / empty the old layout layoutAttributes removeAll () for I 0. In the. Let layoutAttr = layoutAttributesForItem(at: indepath.init (row: I, section: 0)) layoutAttributes.append(layoutAttr!) } } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {//size defaults to itemSize var size = self.itemSize // Get the size of the item from the proxy method if self.collectionView! .delegate ! = nil && self.collectionView! .delegate! .conforms(to: UICollectionViewDelegateFlowLayout.self) && self.collectionView! .delegate! .responds(to: # the selector (UICollectionViewDelegateFlowLayout. CollectionView (_ : layout: sizeForItemAt:))) {/ / convert objects let flowLayoutDelegate =  self.collectionView! .delegate as! UICollectionViewDelegateFlowLayout size = flowLayoutDelegate.collectionView! (self.collectionView! , layout: self, sizeForItemAt: indexPath)} // Initialize each item's frame. CGFloat = 0 var y: CGFloat = 0 // Get the last item from layoutAttributes. If not, set the current item to the first item Let collectionViewWidth: CGFloat = self. CollectionView! .bounds.width // Sets the initial value of the coordinates according to the alignment direction if alignDirection ==. Left {// Align left x = self.sectionInset.left y = self.sectionInset.top Count >0 {let lastLayoutAttr = layoutAttributes. Last! // Determine if the current line is wide enough to insert a new item if lastLayoutAttr.frame.maxX+self.minimumInteritemSpacing+size.width+self.sectionInset.right>collectionViewWidth { / / if the width is greater than the total width, change the y coordinates of the current item according to the next line y = lastLayoutAttr. Frame. MaxY + self. MinimumLineSpacing} else {/ / if the width can be inserted into the item and modify the coordinate points, The Y-axis is parallel to the previous item, X axis is an item on the far right of the combined with line spacing x = lastLayoutAttr. Frame. The maxX + self. MinimumInteritemSpacing y = lastLayoutAttr. Frame. MinY}}} } else {/ / horizontal sliding let layoutAttr = super. LayoutAttributesForItem (ats: indexPath)! x = layoutAttr.frame.origin.x y = layoutAttr.frame.origin.y } frame = CGRect(x: x, y: y, width: size.width, height: Size height) / / update the contentSize, assignment here sometimes is not the maximum, if need to use collectionViewContentSize this property, Width = frame.maxx +self.sectionInset.right contentsize.height = Frame.maxy +self.sectionInset.bottom // Create the layout property let layoutAttr = for each item UICollectionViewLayoutAttributes.init(forCellWith: IndexPath) layoutAttr. Frame = frame return layoutAttr} / / return all layout override func layoutAttributesForElements (in the rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return layoutAttributes } }Copy the code