使用UICollectionView做tag显示的时候的对齐方式
程序员文章站
2022-04-26 17:37:54
...
import UIKit
enum AlignType : NSInteger {
case left = 0
case center = 1
case right = 2
}
class EqualCellSpaceFlowLayout: UICollectionViewFlowLayout {
//两个Cell之间的距离
private var horizontalSpace : CGFloat{
didSet{
self.minimumInteritemSpacing = horizontalSpace
}
}
//cell对齐方式
private var alignType : AlignType = AlignType.center
//在居中对齐的时候需要知道这行所有cell的宽度总和
var cellWidthInLine : CGFloat = 0.0
override init() {
horizontalSpace = 5.0
super.init()
scrollDirection = UICollectionView.ScrollDirection.vertical
minimumLineSpacing = 5
sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
}
convenience init(_ cellType:AlignType){
self.init()
self.alignType = cellType
}
convenience init(_ cellType: AlignType, _ horizontalSpace: CGFloat){
self.init()
self.alignType = cellType
self.horizontalSpace = horizontalSpace
}
required init?(coder aDecoder: NSCoder) {
horizontalSpace = 5.0
super.init(coder: aDecoder)
scrollDirection = UICollectionView.ScrollDirection.vertical
minimumLineSpacing = 5
sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let layoutAttributes_super : [UICollectionViewLayoutAttributes] = super.layoutAttributesForElements(in: rect) ?? [UICollectionViewLayoutAttributes]()
let layoutAttributes:[UICollectionViewLayoutAttributes] = NSArray(array: layoutAttributes_super, copyItems:true)as! [UICollectionViewLayoutAttributes]
var layoutAttributes_t : [UICollectionViewLayoutAttributes] = [UICollectionViewLayoutAttributes]()
for index in 0..<layoutAttributes.count{
print("index in 0..<layoutAttributes.count ==============")
let currentAttr = layoutAttributes[index]
let previousAttr = index == 0 ? nil : layoutAttributes[index-1]
let nextAttr = index + 1 == layoutAttributes.count ?
nil : layoutAttributes[index+1]
layoutAttributes_t.append(currentAttr)
cellWidthInLine += currentAttr.frame.size.width
let previousY :CGFloat = previousAttr == nil ? 0 : previousAttr!.frame.maxY
let currentY :CGFloat = currentAttr.frame.maxY
let nextY:CGFloat = nextAttr == nil ? 0 : nextAttr!.frame.maxY
if currentY != previousY && currentY != nextY{
if currentAttr.representedElementKind == UICollectionView.elementKindSectionHeader{
layoutAttributes_t.removeAll()
cellWidthInLine = 0.0
print("currentAttr.representedElementKind == UICollectionView.elementKindSectionHeader =========== Header")
}else if currentAttr.representedElementKind == UICollectionView.elementKindSectionFooter{
layoutAttributes_t.removeAll()
cellWidthInLine = 0.0
print("currentAttr.representedElementKind == UICollectionView.elementKindSectionFooter ============ Footer")
}else{
self.setCellFrame(with: layoutAttributes_t)
layoutAttributes_t.removeAll()
cellWidthInLine = 0.0
print("currentY != previousY && currentY != nextY ============== Item")
}
} else if currentY != nextY { //这里currentY == previousY 说明和上一个项目在同一行,currentY != nextY说明下一个项目要换行了,这种情况直接计算本行的对齐方式
self.setCellFrame(with: layoutAttributes_t)
layoutAttributes_t.removeAll()
cellWidthInLine = 0.0
print("currentY != nextY ======== Else")
}
}
return layoutAttributes
}
/// 调整Cell的Frame
///
/// - Parameter layoutAttributes: layoutAttribute 数组
func setCellFrame(with layoutAttributes : [UICollectionViewLayoutAttributes]){
var nowWidth : CGFloat = 0.0
switch alignType {
case AlignType.left:
nowWidth = self.sectionInset.left
for attributes in layoutAttributes {
var nowFrame = attributes.frame
nowFrame.origin.x = nowWidth
attributes.frame = nowFrame
nowWidth += nowFrame.size.width + self.horizontalSpace
}
break;
case AlignType.center:
nowWidth = (self.collectionView!.frame.size.width - cellWidthInLine - (CGFloat(layoutAttributes.count - 1) * horizontalSpace)) / 2
for attributes in layoutAttributes{
var nowFrame = attributes.frame
nowFrame.origin.x = nowWidth
attributes.frame = nowFrame
nowWidth += nowFrame.size.width + self.horizontalSpace
}
break;
case AlignType.right:
nowWidth = self.collectionView!.frame.size.width - self.sectionInset.right
for var index in 0 ..< layoutAttributes.count{
index = layoutAttributes.count - 1 - index
let attributes = layoutAttributes[index]
var nowFrame = attributes.frame
nowFrame.origin.x = nowWidth - nowFrame.size.width
attributes.frame = nowFrame
nowWidth = nowWidth - nowFrame.size.width - horizontalSpace
}
break;
}
}
}
做对齐方式的部分其实就是通过重新UICollectionViewFlowLayout来做的,主要是将每一行的元素按照设定的方向进行排列。
以下给出测试用的源码
import UIKit
class ViewController: UIViewController {
let list = ["全部","肺癌","甲状腺癌","食管癌","乳腺癌","抠鼻咽喉癌","淋巴瘤","肝胆胰癌","胃癌","结肠直癌","泌尿系统肿瘤","妇科肿瘤","骨肿瘤","一","二","三","四"]
@IBOutlet weak var mCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let layout = EqualCellSpaceFlowLayout(.left)
mCollectionView.collectionViewLayout = layout
}
}
extension ViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return list.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "tagCell", for: indexPath) as? TagCell
cell?.name.text = list[indexPath.row]
return cell!
}
func collectionView(_ collectionView: UICollectionView?, TextForItemAt indexPath: IndexPath) -> String {
return list[indexPath.row]
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let attr:[NSAttributedString.Key:Any] = [.font:UIFont.systemFont(ofSize: 12)]
let width = (list[indexPath.row] as NSString).boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: 30), options: .usesLineFragmentOrigin, attributes: attr, context: nil).width + 5.0
return CGSize(width: width, height: 30)
}
}
上一篇: [原创] jQuery源码分析-15AJAX-类型转换器
下一篇: 继承方式六:寄生组合式继承