UICollectionView可以创建高度不一的瀑布流,但是没有办法处理宽度不一的标签流.现在我们就用代码来自己创建一个标签流,会分别使用frame硬编码布局和autolayout自动布局两种方式来实现
一. frame硬编码布局
最终完成效果如下
![](https://img.haomeiwen.com/i1312609/0618774592e9f76e.png)
- 新建一个Single View Application的iOS Project,我们就在初始创建的ViewController上面编写代码
- 我们创建数据源(TagLabel是一个自定义的UILabel,加入了文本和边框的padding,也可以直接使用UILabel,一样可以实现效果)
var dataSource = [String]()
var labels = [TagLabel]()
//mock 数据数量
let count = 20
- 在viewDidLoad中初始化数据
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for _ in 0..<count {
dataSource.append(RandomString.sharedInstance.getRandomStringOfLength(3 + Int(arc4random_uniform(7))))
}
for i in 0..<count {
labels.append(TagLabel())
labels[i].text = dataSource[i]
labels[i].padding = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
labels[i].layer.borderColor = UIColor.greenColor().CGColor
labels[i].layer.borderWidth = 1
labels[i].layer.cornerRadius = 8
self.view.addSubview(labels[i])
}
layoutLabels()
}
- 布局标签流
func layoutLabels() {
let width = UIScreen.mainScreen().bounds.width
//标签间水平间距
let horizontalSpace : CGFloat = 12
//标签行间距
let verticalSpace : CGFloat = 12
//左边已经填充长度
var left : CGFloat = 0
//顶部已经填充高度
var top : CGFloat = 0
var lineLabels = [[TagLabel]]()
var lineLabel = [TagLabel]()
var lineStartSpace = [CGFloat]()
for label in labels {
let labelWidth = label.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).width
if left + labelWidth + horizontalSpace > width {
lineLabels.append(lineLabel)
lineLabel = [TagLabel]()
lineStartSpace.append((width - left + horizontalSpace) / 2)
left = 0
}
left += labelWidth + horizontalSpace
lineLabel.append(label)
}
lineLabels.append(lineLabel)
lineStartSpace.append((width - left + horizontalSpace) / 2)
top = verticalSpace + 20
var size : CGSize = CGSize.zero
for (index, oneLine) in lineLabels.enumerate() {
left = lineStartSpace[index]
for label in oneLine {
size = label.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
label.frame = CGRect(x: left, y: top, width: size.width, height: size.height)
left += size.width + horizontalSpace
}
top += size.height + verticalSpace
}
}
- RandomString是我自己写的一个生成随机长度的字符串方法,代码如下:
///随机字符串生成
class RandomString {
let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
/**
生成随机字符串,
- parameter length: 生成的字符串的长度
- returns: 随机生成的字符串
*/
func getRandomStringOfLength(length: Int) -> String {
var ranStr = ""
for _ in 0..<length {
let index = Int(arc4random_uniform(UInt32(characters.characters.count)))
ranStr.append(characters[characters.startIndex.advancedBy(index)])
}
return ranStr
}
private init() {
}
static let sharedInstance = RandomString()
}
- 以上就是硬编码布局标签流的所有代码了,运行看看效果吧~
二. AutoLayout自动布局
待续...
完整代码见Github: https://github.com/growold/SwiftLearn 的Learn02TagFlow项目.
网友评论