🔰Slider label position
╱🚧 under construction
SwiftUI ⟩ controls ⟩ Slider ⟩ label position

Slider 1 程式碼重點解說:
.background負責將子視圖 (Text) 置中對齊 (Text的中心點放在背景正中央)。計算
Text的偏移量時,須以中央為基準。用
.offset()偏移Text。
// view properties
@State var t: CGFloat = 0.5
let sliderWidth: CGFloat = 300 // ⭐️ 滑桿寬度
// view body
// slider(fixed width) > background > text
Slider(value: $t)
// ⭐️ 1. `.background` 負責將子視圖「置中對齊」
.background {
let knobWidth: CGFloat = 28 // 滑桿調鈕寬度
let knobRange = sliderWidth - knobWidth // 調鈕活動範圍寬度
// ⭐️ 2. 因為 Text 會被 .background 置中對齊
// 所以計算偏移量時,須以中央為基準。
let xOffset = (t-0.5) * knobRange // 數值標籤偏移量
// ⭐️ 3. 用 .offset() 偏移 Text。
Text("\(t, specifier: "%.2f")")
.offset(x: xOffset, y: -30)
}// background
.frame(width: sliderWidth) // ⭐️ 寬度固定方法2-1:用 .background + GeometryReader + Slider 尺寸
優點:可適應母視圖的環境、大小可自動調整。
缺點:容易忽略
GeometryReader以左上角為對齊方式,導致定位錯誤。
Slider 2-1 程式碼重點解說:
雖然
.background負責將子視圖置中對齊,但GeometryReader是它唯一的子視圖,而且GeometryReader會用掉母視圖的所有空間,因此.background的對齊等於沒有效用❗️(對齊主要是由GeometryReader來接手掌控)注意:
GeometryReader的對齊方式與.background不同,它負責將子視圖對齊「左上角」,因此在GeometryReader內部放置子視圖的邏輯與在.background內不同❗️計算標籤偏移量時,要以
GeometryReader左上角考量,同時還要考量到調鈕本身有一定寬度 (28),因此調鈕的中心點無法接觸到滑桿最左側,而是調鈕的左側接觸到滑桿的最左側,所以計算標籤偏移量時,還要先加上調鈕寬度的一半。用
.position()直接設定 Text 中心點位置。 優點:不會因為字體寬度變化而導致標籤位置與調鈕無法對齊。
方法2-2:用 .background + GeometryReader + ZStack 幫忙置中
優點:
可適應母視圖、大小可自動調整。
ZStack可幫忙置中子視圖。
缺點:
容易忘記將
ZStack的尺寸放到與GeometryReader一樣大,導致GeometryReader依然先將整個ZStack放到左上角,然後ZStack才在它的內部做置中對齊,這時的置中對齊就是無效的,因為整個ZStack都在左上角❗️ (看上圖 slider 2-2)
Slider 2-2 程式碼重點解說:
忘記將
ZStack的尺寸放到與GeometryReader一樣大❗️GeometryReader依然先將整個ZStack放到左上角,然後ZStack才在它的內部做置中對齊❗️計算偏移量時,仍以「中心點」為考量,導致標籤位置錯誤❗️
方法2-3:同方法2-2,但修正了忘記將 ZStack 的尺寸放到與 GeometryReader 一樣大的問題,如此 ZStack 才能真正接手幫忙置中對齊子視圖。
Slider 2-3 程式碼重點解說:
使用
.overlay+GeometryReader取得Slider尺寸 (geo.size)先扣除
GeometryReader左右各一半滑桿調鈕的寬度。
註:當一個 view 用到 view modifier 時,母子視圖關係要倒過來看,例如:child.parent().grandParent(),前面的是子視圖、後面的是母視圖❗️
利用
.frame(maxWidth: .infinity, maxHeight: .infinity)將ZStack的尺寸放到最大 (GeometryReader扣掉調鈕寬度)此時
ZStack就能正常幫忙置中對齊Text。利用
GeometryReader的資訊 (geo.size) 計算ZStack的尺寸。 (註:這裡有用到 GeometryKit 這個 custom package)用
.position()直接設定標籤中心點位置 (此時標籤會疊在調鈕正上方)。用
.offset()將標籤往上調。
方法2-4:同方法2-3。眼尖的人應該會察覺到,雖然方法2-3中我們有用 ZStack 來幫忙置中子視圖,它唯一的子視圖 Text 卻選擇了 .position() 來直接設定自己的中心點位置。換句話說,ZStack 根本沒起任何作用,因此可以直接移除 ZStack❗️
🚧
GeometryReader:用於取得 Slider 的寬度。
GeometryKit:custom package
Last updated
Was this helpful?