Alignment
Last updated
Last updated
SwiftUI โฉ View โฉ Layout โฉ
Aligning Views Across Stacks - align views across multiple stacks
SwiftUI Lab โฉ Alignment Guides in SwiftUI
Swift with Majid โฉ Alignment guides in SwiftUI
default alignment
built-in alignments
adjust alignment guide of indivisual views
ZStack {
/// โญ๏ธ 1. default alignment: `.center`
HStack {
Image(systemName: "mic")
Text("Connecting").font(.caption)
Text("Bryan").font(.title)
}
.padding()
.border(Color.blue, width: 1)
.overlay(HLine(color: .orange))
}
ๆณจๆ๏ผไธ่ฌ็ Image ไธๆฏๆด .firstTextBaseline๏ผไฝ SF Symbols ๆฏๆดใ
ZStack {
/// โญ๏ธ 2. built-in alignment:
HStack(alignment: .firstTextBaseline) {
Image(systemName: "mic")
Text("Connecting").font(.caption)
Text("Bryan").font(.title)
}
.padding()
.border(Color.blue, width: 1)
.overlay(HLine(color: .orange), alignment: Alignment(
horizontal: .center,
vertical: .firstTextBaseline
))
}
ZStack {
/// โญ๏ธ 3. adjust alignment guide of indivisual views
HStack(alignment: .firstTextBaseline) {
Image(systemName: "mic")
/// โญ๏ธ 3.1
/// When using `.alignmentGuide()`, make sure to specify an
/// **active alignment** of the **stack** (`.firstTextBaseline`
/// in this case). Otherwise, SwiftUI doesnโt invoke the closure
/// to offset the view.
.alignmentGuide(.firstTextBaseline) { dim in
/// โญ๏ธ 3.2 ๅฐๅฐ้ฝ็ท(alignment guide)่ชฟๅฐ image ๆญฃไธญๅคฎ
dim[VerticalAlignment.center] // = dim[.bottom] - 0.5 * dim.height
}
Text("Connecting").font(.caption)
Text("Bryan").font(.title)
}
.padding()
.border(Color.blue, width: 1)
.overlay(HLine(color: .orange), alignment: Alignment(
horizontal: .center,
vertical: .firstTextBaseline
))
}
By default, the alignment you specify for a stack applies only to that stackโs child views.
use custom alignment
use built-in alignment
/// โญ๏ธ 1. Define a Custom Alignment
extension VerticalAlignment {
/// โญ๏ธ 1.1 define custom alignment for image titles.
private struct ImageTitleAlignment: AlignmentID {
static func defaultValue(in context: ViewDimensions) -> CGFloat {
// default to bottom alignment if no guides are set.
context[VerticalAlignment.bottom]
}
}
/// โญ๏ธ 1.2 define a convenience alignment guide name
static let imageTitle = VerticalAlignment(
ImageTitleAlignment.self
)
}
struct AcrossStacks: View {
var body: some View {
/// โญ๏ธ 2. Assign custom alignment to parent view
/// When you assign an alignment on a stack,
/// it projects through enclosed child views.
HStack(alignment: .imageTitle, spacing: 32) {
VStack {
Image(systemName: "bell")
.resizable().scaledToFit().padding().foregroundColor(.red)
Text("Bell Peppers").font(.title)
/// โญ๏ธ 3. Within each nested stack, apply `.alignmentGuide()`
/// to the view you want to align with.
.alignmentGuide(.imageTitle) { dim in
dim[.firstTextBaseline]
}
}
VStack {
Image(systemName: "memorychip")
.resizable().scaledToFit().padding().foregroundColor(.green)
Text("Chili Peppers").font(.title)
/// โญ๏ธ 3.
.alignmentGuide(.imageTitle) { dim in
dim[.firstTextBaseline]
}
Text("Higher levels of capsicum").font(.caption)
}
}.overlay(HLine(), alignment: Alignment(horizontal: .center, vertical: .imageTitle))
}
}
/// โญ๏ธ parent stack
HStack(alignment: .firstTextBaseline) {
// nested stack
HStack(alignment: .firstTextBaseline) {
image
text
}
// nested stack
HStack(alignment: .firstTextBaseline) {
image
// โญ๏ธ ๅฐ้ฝ็ท (alignment guide) ๅพไธ (+) ๆ่ฎ image ๅพไธ้ฃ
.alignmentGuide(.firstTextBaseline) { d in
d[.bottom] + d.height
}
text
}
// nested stack
HStack(alignment: .firstTextBaseline) {
image
// โญ๏ธ ๅฐ้ฝ็ท (alignment guide) ๅพไธ (-) ๆ่ฎ image ๅพไธๆฒ
.alignmentGuide(.firstTextBaseline) { d in
d[.bottom] - d.height
}
text
}
}.baseLine()
import SwiftUI
extension View {
/// โญ๏ธ left border
func borderLeft(color: Color = .red, width: CGFloat = 1) -> some View {
overlay(VLine(color: color, width: width), alignment: .leading)
}
/// โญ๏ธ bottom border
func borderBottom(color: Color = .red, width: CGFloat = 1) -> some View {
overlay(HLine(color: color, width: width), alignment: .bottom)
}
/// โญ๏ธ base line
func baseLine() -> some View {
overlay(HLine(), alignment: Alignment(
horizontal: .center,
vertical: .firstTextBaseline
))
}
}
/// โญ๏ธ horizontal line
struct HLine: View {
var color: Color = .red
var width: CGFloat = 1
var body: some View {
Rectangle().fill(color).frame(height: width)
}
}
/// โญ๏ธ vertical line
struct VLine: View {
var color: Color = .red
var width: CGFloat = 1
var body: some View {
Rectangle().fill(color).frame(width: width)
}
}