Custom Alignment within ZStack
Last updated
Last updated
๐ก ้็ถไธ้ข็ไพๅญไฝฟ็จ่ช่ฃฝๅฐ้ฝ็ท๏ผไฝ่จ่ซๅ่ฃก็ๅๆณๅฏ่ฝๆฏ่ผๅฟซใ
/// โญ๏ธ 1. define custom vertical alignment (for cap height)
extension VerticalAlignment {
private struct CapHeightAlignment: AlignmentID {
static func defaultValue(in context: ViewDimensions) -> CGFloat {
context[VerticalAlignment.firstTextBaseline]
}
}
static let capHeight = VerticalAlignment(
CapHeightAlignment.self
)
}
/// โญ๏ธ 2. define custom horizontal alignment (for "second" leading)
extension HorizontalAlignment {
private struct SecondLeadingAlignment: AlignmentID {
static func defaultValue(in context: ViewDimensions) -> CGFloat {
context[.leading]
}
}
static let secondLeading = HorizontalAlignment(
SecondLeadingAlignment.self
)
}
struct View1: View {
/// โญ๏ธ Unfortunately, we still have to use `UIFont`
/// to access the `.capHeight` property.
let bigFont = UIFont.systemFont(ofSize: 70)
let smallFont = UIFont.systemFont(ofSize: 24)
var body: some View {
/// โญ๏ธ ZStack ๅ
ง้จไฝฟ็จ่ช่ฃฝ็ๅฐ้ฝ็ท
ZStack(alignment: Alignment(
horizontal: .secondLeading, vertical: .capHeight
)) {
/// HStack ๅ
ง้จไปฅ `.firstTextBaseline` ๆ็๏ผ
/// "7" ่ "kts" ๅบ็ทๅฐ้ฝใ
HStack(alignment: .firstTextBaseline, spacing: 3) {
Text("7")
.font(.system(size: 70))
.foregroundColor(Color.green)
/// โญ๏ธ "7" ่ ".0" ๅ็ดๆนๅไปฅ `.capHeight` ๅฐ้ฝ
.alignmentGuide(.capHeight) { dim in
// โญ๏ธ ไฝๅฟ
้ ๆๅ่ชฟๆด `.capHeight` ๅฐ้ฝ็ท็ไฝ็ฝฎใ
dim[.firstTextBaseline] - bigFont.capHeight
}
Text("kts")
.font(.system(size: 18))
/// โญ๏ธ "kts" ่ ".0" ๆฐดๅนณๆนๅไปฅ `.secondLeading` ๅฐ้ฝ
.alignmentGuide(.secondLeading) { $0[.leading] }
}.baseLine(color: .blue)
Text(".0")
.font(.system(size: 24))
.foregroundColor(Color.green)
/// โญ๏ธ "kts" ่ ".0" ๆฐดๅนณๆนๅไปฅ `.secondLeading` ๅฐ้ฝ
.alignmentGuide(.secondLeading){ $0[.leading] }
/// โญ๏ธ "7" ่ ".0" ๅ็ดๆนๅไปฅ `.capHeight` ๅฐ้ฝ
.alignmentGuide(.capHeight) { dim in
// โญ๏ธ ไฝๅฟ
้ ๆๅ่ชฟๆด `.capHeight` ๅฐ้ฝ็ท็ไฝ็ฝฎใ
dim[.firstTextBaseline] - smallFont.capHeight
}
}.overlay(HLine(), alignment: Alignment(
horizontal: .center, vertical: .capHeight
)).overlay(VLine(), alignment: Alignment(
horizontal: .secondLeading, vertical: .center
))
}
}