簡體   English   中英

有沒有辦法在 uicollctionview 的每個部分給出外邊框?

[英]Is there a way to give outer border in every section of uicollctionview?

嘗試在集合視圖中添加每個部分的外邊框。

如果我使用的是cell.layer.border ,它還會創建一個內邊框。 有沒有一種簡單的方法可以只為集合視圖中的每個部分創建外邊框?

嘗試創建如下圖所示的紅色邊框

在此處輸入圖像描述

正如 Matt 在評論和文章中指出的那樣,您需要使用 DecorationView。

你可以在這里閱讀

因此,要做到這一點,您必須執行以下步驟:

  1. 創建一個自定義的UICollectionReusableView作為裝飾視圖
  2. 子類UICollectionViewFlowLayout以創建自定義布局
  3. 重寫layoutAttributesForDecorationViewlayoutAttributesForElements弄清楚每個section的frame,將decoration view放在section frame中
  4. 使用自定義流布局作為集合視圖的布局

這是代碼

  1. 創建 Decoration 視圖,它只是一個帶有邊框的常規視圖
class SectionBackgroundView : UICollectionReusableView {
    
    static let DecorationViewKind = "SectionBackgroundIdentifier"
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        // Customize the settings to what you want
        backgroundColor = .clear
        layer.borderWidth = 5.0
        layer.borderColor = UIColor.blue.cgColor
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
  1. 創建自定義流程布局
class BorderedFlowLayout: UICollectionViewFlowLayout {
    
    override init() {
        super.init()
        
        // Register your decoration view for the layout
        register(SectionBackgroundView.self,
                 forDecorationViewOfKind: SectionBackgroundView.DecorationViewKind)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutAttributesForDecorationView(ofKind elementKind: String,
                                                    at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        if elementKind == SectionBackgroundView.DecorationViewKind {
            
            guard let collectionView = collectionView else { return nil }
            
            // Initialize a UICollectionViewLayoutAttributes for a DecorationView
            let decorationAttributes
                = UICollectionViewLayoutAttributes(forDecorationViewOfKind: SectionBackgroundView.DecorationViewKind,
                                                   with:indexPath)
            
            // Set it behind other views
            decorationAttributes.zIndex = 2
            
            let numberOfItemsInSection
                = collectionView.numberOfItems(inSection: indexPath.section)
            
            // Get the first and last item in the section
            let firstItem = layoutAttributesForItem(at: IndexPath(item: 0, section: indexPath.section))
            
            let lastItem = layoutAttributesForItem(at: IndexPath(item: (numberOfItemsInSection - 1),
                                                                 section: indexPath.section))
            
            // The difference between the maxY of the last item and
            // the the minY of the first item is the height of the section
            let height = lastItem!.frame.maxY - firstItem!.frame.minY
            
            // Set the frame of the decoration view for the section
            decorationAttributes.frame = CGRect(x: 0,
                                                y: firstItem!.frame.minY,
                                                width: collectionView.bounds.width,
                                                height: height)
            
            return decorationAttributes
        }
        
        return nil
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        
        // Get all the UICollectionViewLayoutAttributes for the current view port
        var attributes = super.layoutAttributesForElements(in: rect)
        
        // Filter to get all the different sections
        let sectionAttributes
            = attributes?.filter { $0.indexPath.item == 0 } ?? []
        
        // Loop through the different sections
        for sectionAttribute in sectionAttributes {
            
            // Create decoration attributes for the current section
            if let decorationAttributes
                = self.layoutAttributesForDecorationView(ofKind: SectionBackgroundView.DecorationViewKind,
                                                         at: sectionAttribute.indexPath) {
                
                // Add the decoration attributes for a section if it is in the current viewport
                if rect.intersects(decorationAttributes.frame) {
                    attributes?.append(decorationAttributes)
                }
            }
        }
        
        return attributes
    }
}
  1. 在您的視圖中使用自定義布局 controller
private func configureCollectionView() {
    
    collectionView = UICollectionView(frame: CGRect.zero,
                                      collectionViewLayout: createLayout())
    
    collectionView.backgroundColor = .white
    
    collectionView.register(UICollectionViewCell.self,
                            forCellWithReuseIdentifier: "cell")
    
    // You can ignore the header and footer views as you probably already did this
    collectionView.register(HeaderFooterView.self,
                            forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
                            withReuseIdentifier: HeaderFooterView.identifier)
    
    collectionView.register(HeaderFooterView.self,
                            forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter,
                            withReuseIdentifier: HeaderFooterView.identifier)
    
    collectionView.dataSource = self
    collectionView.delegate = self
    
    view.addSubview(collectionView)
}

private func createLayout() -> UICollectionViewFlowLayout {
    
    let flowLayout = BorderedFlowLayout()
    flowLayout.minimumLineSpacing = 10
    flowLayout.minimumInteritemSpacing = 10
    flowLayout.scrollDirection = .vertical
    flowLayout.sectionInset = UIEdgeInsets(top: 10,
                                           left: horizontalPadding,
                                           bottom: 10,
                                           right: horizontalPadding)
    
    return flowLayout
}

做所有這些應該會給你你想要的

自定義 UIViewCollectionView UICollectionViewFlowLayout 邊框圍繞每個部分裝飾視圖 iOS swift

我只發布了最重要的片段。 如果由於某種原因您無法繼續操作,這里是重新創建示例的完整代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM