💈example ⟩ SubButtons

Button 可以改變 @State 變數,觸發 view 的更新。

import SwiftUI
import PlaygroundSupport

let r: CGFloat = 4  // shadow radius
let bg1 = Circle().outlined(fill: .green ).shadow(radius: r, x: r/2, y: r/2)
let bg2 = Circle().outlined(fill: .purple).shadow(radius: r, x: r/2, y: r/2)

// live view
struct ContentView: View {
    
    // ⭐️ view state
    @State private var change = false
    
    // animation params
    var d: CGFloat { change ? 100 : 0 }  // offset
    var clockwise: Angle  { .degrees(change ? 135 : 0) }
    var reverse  : Angle  { .degrees(change ? 0 : 135) }
    var opacity  : Double { change ? 1 : 0 }
    
    let p: CGFloat = 24  // padding
    
    // view body
    var body: some View {
        ZStack(alignment: .bottomTrailing) {
            Group {
                // sub buttons
                Button(action: { self.change.toggle() }, label: {
                    Image(systemName: "bag.badge.plus")
                        // 🌀view.padding(_, _, _, _)
                        // ⭐️ 微調 padding,讓圖示居中。
                        .padding(p, p-2, p, p+2).background(bg2)
                        .rotationEffect(reverse)
                }).offset(y: -d).opacity(opacity)
                
                Button(action: { self.change.toggle() }, label: {
                    Image(systemName: "gauge.badge.plus")
                        .padding(p+1, p-2, p-1, p+2).background(bg2)
                        .rotationEffect(reverse)
                }).offset(-d * 0.71, -d * 0.71).opacity(opacity)
                
                Button(action: { self.change.toggle() }, label: {
                    Image(systemName: "calendar.badge.plus")
                        .padding(p+2, p+2, p-2, p-2).background(bg2)
                        .rotationEffect(reverse)
                }).offset(x: -d).opacity(opacity)
                    
                // main button
                Button(action: { self.change.toggle() }, label: {
                    Image(systemName: "plus")
                        .padding(24).background(bg1)
                        .rotationEffect(clockwise)
                })
            }// Group
                .accentColor(.white).imageScale(.large)
                .animation(.default)
            
        }// container: VStack
            .compositingGroup()
            .frame(width: 300, height: 300, alignment: .bottomTrailing)
            .shadow(radius: 8)
            .padding()
            .background(Color.gray)
            .cornerRadius(10)
    }
}

PlaygroundPage.current.setLiveView(ContentView())

Last updated