Swift 使用CollectionView实现不等宽标签布局
2020-06-11 本文已影响0人
GuiiLiin
实现CollectionView中不等宽标签布局
自定义cell
import UIKit
class XFTagCell: UICollectionViewCell {
lazy var bgView:UIView = {
let bgView:UIView = UIView()
bgView.backgroundColor = UIColor.red
return bgView
}()
lazy var tagLabel:UILabel = {
let tagLabel:UILabel = UILabel()
tagLabel.textAlignment = NSTextAlignment.center
tagLabel.font = UIFont.systemFont(ofSize: 13)
tagLabel.textColor = UIColor.purple
return tagLabel
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.contentView.addSubview(bgView)
bgView.addSubview(tagLabel)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
bgView.snp.makeConstraints { (make) in
make.left.right.top.bottom.equalTo(0)
}
tagLabel.snp.makeConstraints { (make) in
make.left.top.equalTo(2)
make.right.bottom.equalTo(-2)
}
}
}
自定义 UICollectionViewFlowLayout
最重要的就是自定义继承
UICollectionViewFlowLayout
的类 所有CollectionView的样式都在这里面实现
import UIKit
protocol GLCustomTagFlowLayoutDelegate : NSObjectProtocol {
func getCollectionVIewHeight(H:CGFloat)
}
class GLCustomTagFlowLayout: UICollectionViewFlowLayout {
var delegate:GLCustomTagFlowLayoutDelegate?
var maximumInteritemSpacing: CGFloat = 10
override func prepare() {
super.prepare()
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
super.layoutAttributesForElements(in: rect)
//使用系统帮我们计算好的结果
guard let attributes = super.layoutAttributesForElements(in: rect) else {
return nil
}
//第0个cell没有上一个cell,所以从1开始
for i in 1..<attributes.count {
let curAttr = attributes[i]
let preAttr = attributes[i-1]
let origin = preAttr.frame.maxX
//根据maximumInteritemSpacing计算出的新的x位置
let targetX = origin + maximumInteritemSpacing
//只有系统计算的间距大于maximumInteritemSpacing时才进行调整
if curAttr.frame.minX > targetX {
// 换行时不用调整
if targetX + curAttr.frame.width < collectionViewContentSize.width {
var frame = curAttr.frame
frame.origin.x = targetX
curAttr.frame = frame
}
}
if i == attributes.count-1 {
print(curAttr.frame.maxY)
self.delegate?.getCollectionVIewHeight(H: curAttr.frame.maxY)
}
}
return attributes
}
}
控制器
import UIKit
class XFShowTagColController: UIViewController {
lazy var titleArr:NSArray = {
let arr:NSArray = ["家打","2klajsdfklj","2343","付款拉屎都卡世纪东方","523","61","724","路上慢点了jjk","sdada424","冷空气将巧克力;人",",;;,';哈哈","12421412"]
return arr
}()
lazy var collectionView:UICollectionView = {
let layout:GLCustomTagFlowLayout = GLCustomTagFlowLayout()
layout.delegate = self
let collectionView:UICollectionView = UICollectionView(frame: CGRect(), collectionViewLayout: layout)
collectionView.register(XFTagCell.self, forCellWithReuseIdentifier: "tag")
collectionView.backgroundColor = UIColor.orange
collectionView.delegate = self
collectionView.dataSource = self
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "TAG"
self.view.addSubview(collectionView)
collectionView.snp.makeConstraints { (make) in
make.left.right.top.bottom.equalTo(0)
}
}
}
extension XFShowTagColController : UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: labelWidth((titleArr[indexPath.item]) as! String, 20), height: 20)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return titleArr.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell:XFTagCell = collectionView.dequeueReusableCell(withReuseIdentifier: "tag", for: indexPath) as! XFTagCell
cell.tagLabel.text = titleArr[indexPath.item] as? String
return cell
}
// 根据font和高度计算宽度
func labelWidth(_ text: String, _ height: CGFloat) -> CGFloat {
let size = CGSize(width: 2000, height: height)
let font = UIFont.systemFont(ofSize: 13)
let attributes = [NSAttributedString.Key.font: font]
let labelSize = NSString(string: text).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
return labelSize.width + 10
}
}
// 得到标签的高度 根据项目需求使用
extension XFShowTagColController : GLCustomTagFlowLayoutDelegate {
func getCollectionVIewHeight(H: CGFloat) {
// H为标签总高度
}
}