タグを自動的に改行させる
はじめに
SwiftUI でタグを配置する際に詰まったため備忘録。
実現したいこと
↑ こういうやつ
詰まった部分
import SwiftUI
struct ContentView: View {
@State var tagList = [
- tagATagATagATagATagATagA,
- tagBTagBTagBTagBTagBTagB,
- tagCTagCTagCTagCTagCTagC,
- tagDTagDTagDTagDTagDTagD]
var body: some View {
VStack {
Text(
- タグを横並びにしたいので HStack を使ってみると、各タグが全て改行されてしまい不自然)
.padding(.vertical, 10)
HStack {
ForEach(tagList, id: \.self) { tag in
Text(tag)
}
}
Spacer()
}
}
}
解決方法
こちらの StackOverflow の記事が参考になった。
import SwiftUI
struct ContentView: View {
@State var tagList = [
- tagATagATagATagA,
- tagBTagBTagBTagB,
- tagCTagCTagCTagC,
- tagDTagDTagDTagDTagDTagD]
var body: some View {
generateTags()
}
private func generateTags() -> some View {
var width = CGFloat.zero
var height = CGFloat.zero
return ZStack(alignment: .topLeading) {
ForEach(tagList, id: \.self) { tag in
item(for: tag)
.padding([.horizontal, .vertical], 4)
.alignmentGuide(.leading, computeValue: { d in
if abs(width - d.width) > 330 {
width = 0
height -= d.height
}
let result = width
if tag == tagList.last {
width = 0
} else {
width -= d.width
}
return result
})
.alignmentGuide(.top, computeValue: { _ in
let result = height
if tag == tagList.last {
height = 0
}
return result
})
}
}
}
func item(for text: String) -> some View {
Text(text)
.padding(.all, 5)
.font(.footnote)
.background(Color.blue)
.foregroundColor(Color.white)
.cornerRadius(30)
}
}
alignmentGuide
で横幅を指定することで、タグを自動的に改行する。
元記事では GeometryReader
を使って端末の画面サイズを指定していたが、他のコードに影響がありレイアウトが崩れたため、330 にサイズを限定した。
また、実際にはサーバーの API からタグの配列を取得して表示させる。