💈MonthView

這個例子用到 PreferenceKey (Frames) 來記錄所有 MonthView 的 frames,然後利用這些 frames 與 currentIndex 來動態決定「圓角框線」(roundedBorder) 的位置。

程式碼

使用 Veiw Preference

  • 利用自製的 View extension .registerFrame(to: key, in: space) 來收集所有 MonthView 的 frame,然後再由 parent view 的 .onPreferenceChange() 來更新 YearView 的 @State 變數 frames

import SwiftUI
import PlaygroundSupport

// 月份名稱
let monthNames = [
    "ㄧ月", "二月", "三月","四月", "五月", "六月", 
    "七月", "八月", "九月","十月", "十一月", "十二月"
]

// ⭐️ 收集與處理所有的 MonthView's frame
typealias Frames = AllValues<CGRect>    // 📦 AllValues<T>

// live view
struct ContentView: View {
    let r: CGFloat = 1
    // view body
    var body: some View {
        YearView()   // 🌅 YearView
            .shadow(color: .black, radius: r, x: r, y: r)
    }
}

PlaygroundPage.current.setLiveView(ContentView())

使用 Anchor

  • 省掉用 geo.frame(in: space) 換算座標。

  • 省掉用 .coordinateSpace(name:) 定義座標系統。

  • 省掉用 @State 變數來管理畫面更新。

import SwiftUI
import PlaygroundSupport

// ⭐️ 收集與處理所有的 MonthView's frame
typealias FrameAnchors = AllValues<Anchor<CGRect>>

// live view
struct ContentView: View {
    let r: CGFloat = 1
    // view body
    var body: some View {
        YearView()   // 🌅 YearView
            .shadow(color: .black, radius: r, x: r, y: r)
    }
}

PlaygroundPage.current.setLiveView(ContentView())

使用 Anchor + View extension

import SwiftUI
import PlaygroundSupport

// ⭐️ 收集與處理所有的 MonthView's frame
typealias FrameAnchors = AllValues<Anchor<CGRect>>

// live view
struct ContentView: View {
    let r: CGFloat = 1
    // view body
    var body: some View {
        YearView()   // 🌅 YearView
            .shadow(color: .black, radius: r, x: r, y: r)
    }
}

PlaygroundPage.current.setLiveView(ContentView())

Last updated