iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Mobile Development

從概念發想上架一支SwiftUI app系列 第 7

基礎部分 - 調整PanelView排版

  • 分享至 

  • xImage
  •  

先看一下今日成果
Day7

試著把操作面板調整小一點

PanelView.swift

struct PanelView: View {
    
    @Binding var lightSettings: LightSettings
    
    var body: some View {
        HStack {
            RotationPanel(rotationOffset: $lightSettings.rotationOffset)
                .frame(width: 120, height: 120)
            VStack {
                Slider(value: $lightSettings.circleSize, in: 20...80)
                Text("光圈: \(Int(lightSettings.circleSize))")
                Slider(value: $lightSettings.brightness, in: 0.5...1)
                Text("亮度: \(Int(lightSettings.brightness*100))")
                ColorPicker("顏色", selection: $lightSettings.color)
            }
                
            VStack {
                PositionPanel(offset: $lightSettings.offset)
                    .frame(width: 120, height: 120)
                Button(action: {
                    lightSettings.offset = .zero
                }) {
                    Image(systemName: "camera.metering.center.weighted")
                }
                .padding()
            }
        }
        .padding()
    }
}

旋轉面板加一個state,在DragGesture()手勢放開後自動歸零。

struct RotationPanel: View {
    @Binding var rotationOffset: CGSize
    @State private var lastOffset: CGSize = .zero
    @State private var isLock: Bool = false

    var body: some View {
        VStack {
            GeometryReader { geometry in
                ZStack {
                    Circle()
                        .stroke(Color.gray, lineWidth: 2)
                        .frame(width: 120, height: 120)
                    Circle()
                        .fill(Color.blue)
                        .frame(width: 20, height: 20)
                        .offset(rotationOffset)
                        .gesture(
                            DragGesture()
                            .onChanged { value in
                                let radius = 60.0 // 圓形的半徑
                                var newX = value.translation.width + lastOffset.width
                                var newY = value.translation.height + lastOffset.height

                                let distance = sqrt(newX * newX + newY * newY)
                                if distance > radius {
                                    let angle = Double(atan2(newY, newX))
                                    newX = radius * cos(angle)
                                    newY = radius * sin(angle)
                                }

                                rotationOffset = CGSize(width: newX, height: newY)
                            }
                            .onEnded { _ in
                                if isLock {
                                    lastOffset = rotationOffset
                                } else {
                                    rotationOffset = .zero
                                }
                            }
                    )
                }
            }
            Button(action: {
                isLock.toggle()
            }) {
                Text(isLock ? "解鎖" : "鎖定")
            }.offset(x: 0, y: 40)
        }
    }
}

發現一個新問題,因為PositionPanel為正方形,雖然縮小PanelView讓LightZone空間變大,卻無法運用到所有空間。明天週末有多一點時間嘗試毛玻璃模糊效果與各種版型的Layout。


上一篇
基礎部分 - 重構程式碼, 實作光束效果
下一篇
聊聊APP下一步
系列文
從概念發想上架一支SwiftUI app30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言