Triển khai giao diện thẻ bằng UICollectionView trong Swift

Cơ sở sử dụng UICollectionView để tạo giao diện thẻ.

Các phương thức delegate quan trọng cần phân biệt rõ:

protocol NguồnDữLiệuGiaoDiện {
    func sốPhần Tử(_ collectionView: UICollectionView) -> Int
    func kíchThướcPhầnTử(_ collectionView: UICollectionView, tại indexPath: IndexPath) -> CGSize
}
extension GiaoDiệnThẻ: NguồnDữLiệuGiaoDiện {
    func sốPhần Tử(_ collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func sốLượngPhầnTử(_ collectionView: UICollectionView, trong section: Int) -> Int {
        return danhSáchDữLiệu.count
    }
    
    func phầnTử(_ collectionView: UICollectionView, tại indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.tạoLại("CellThẻ", forIndexPath: indexPath) as! CellThẻTùyChỉnh
        cell.nộiDung.text = danhSáchDữLiệu[indexPath.row]
        return cell
    }
    
    func phầnBổSung(_ collectionView: UICollectionView, loại kind: String, tại indexPath: IndexPath) -> UICollectionReusableView {
        if kind == UICollectionView.elementKindSectionHeader {
            let header = collectionView.tạoLạiHeader("TiêuĐề", forIndexPath: indexPath)
            return header
        } else if kind == UICollectionView.elementKindSectionFooter {
            let footer = collectionView.tạoLạiFooter("ChânTrang", forIndexPath: indexPath)
            return footer
        }
        return UICollectionReusableView()
    }
}
protocol TươngTácGiaoDiện {
    func chọnPhầnTử(_ collectionView: UICollectionView, tại indexPath: IndexPath)
}
extension GiaoDiệnThẻ: TươngTácGiaoDiện {
    func chọnPhầnTử(_ collectionView: UICollectionView, tại indexPath: IndexPath) {
        let nhóm = indexPath.section
    }
}
protocol BốTríDòng {
    func kíchThướcPhầnTử(_ collectionView: UICollectionView, tại indexPath: IndexPath) -> CGSize
    func khoảngCáchGiữaDòng(_ collectionView: UICollectionView, tại section: Int) -> CGFloat
}
extension GiaoDiệnThẻ: BốTríDòng {
    func kíchThướcPhầnTử(_ collectionView: UICollectionView, tại indexPath: IndexPath) -> CGSize {
        let chuỗi = danhSáchDữLiệu[indexPath.row]
        let kíchThước = chuỗi.kíchThướcVớiChiềuRộng(chiềuRộngMànHình, font: UIFont.systemFont(ofSize: 14))
        return CGSize(width: kíchThước.width + 24.0, height: 30)
    }
    
    func khoảngCáchGiữaDòng(_ collectionView: UICollectionView, tại section: Int) -> CGFloat {
        return 12
    }
    
    func khoảngCáchGiữaPhầnTử(_ collectionView: UICollectionView, tại section: Int) -> CGFloat {
        return 12
    }
}

Để thực hiện căn lề trái cho các phần tử, tham khảo giải pháp sau:

class BốTríDòngCănTrái: UICollectionViewFlowLayout {
    enum HướngCăn {
        case trái, phải, giữa, tựĐộng
    }
    
    var hướngCăn: HướngCăn = .tựĐộng
    
    override func tínhKíchThướcNộiDung() {
        super.tínhKíchThướcNộiDung()
        
        if hướngCăn == .trái {
            let chiềuRộngTổng = tổngChiềuRộngPhầnTử()
            let khoảngCách = (chiềuRộngMànHình - chiềuRộngTổng) / 2
            for phầnTử in cácPhầnTử {
                phầnTử.vịTrí.x = khoảngCách
                phầnTử.vịTrí.y += khoảngCáchGiữaDòng
            }
        }
    }
    
    private func tổngChiềuRộngPhầnTử() -> CGFloat {
        var tổng = 0.0
        for phầnTử in cácPhầnTử {
            tổng += phầnTử.kíchThước.width
        }
        return tổng
    }
}

Mẫu phần tử hiển thị thẻ:

class CellThẻTùyChỉnh: UICollectionViewCell {
    let nộiDung = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        thiếtLậpGiaoDiện()
    }
    
    private func thiếtLậpGiaoDiện() {
        backgroundColor = UIColor(red: 0.96, green: 0.97, blue: 0.98, alpha: 1.0)
        layer.cornerRadius = 4
        layer.masksToBounds = true
        
        addSubview(nộiDung)
        nộiDung.textColor = UIColor.darkText
        nộiDung.font = UIFont.systemFont(ofSize: 13)
        nộiDung.textAlignment = .center
        nộiDung.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(12)
        }
    }
}

Kết hợp UICollectionView với giao diện tùy chỉnh:

class GiaoDiệnThẻ: UIView {
    lazy var collectionView: UICollectionView = {
        let bốTrí = BốTríDòngCănTrái()
        bốTrí.hướngCăn = .trái
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: bốTrí)
        collectionView.backgroundColor = .white
        collectionView.register(CellThẻTùyChỉnh.self, forCellWithReuseIdentifier: "CellThẻ")
        collectionView.delegate = self
        collectionView.dataSource = self
        return collectionView
    }()
    
    func cậpNhậtDữLiệu() {
        danhSáchDữLiệu = ["Thẻ 1", "Thẻ 2", "Thẻ dài dài dài", "Thẻ 4", "Thẻ 5"]
        collectionView.reloadData()
    }
}

Thẻ: UICollectionView Swift CustomFlowLayout AutoLayout

Đăng vào ngày 28 tháng 5 lúc 16:55