如何将按钮“固定”在 SwiftUI 中的特定位置

问题描述 投票:0回答:1

我有一个带有按钮的电视遥控器图像资源,我在其顶部放置了隐形按钮以使其发挥作用。问题是,由于隐形按钮需要位于相应的图形对应项(如暂停、播放等)上方,因此无论设备大小如何,按钮都应固定在某个位置。我尝试过 GeometryReader、RemoteGeo,甚至 ChatGPT 建议的一些 UIKit 修改都无济于事。有好心人可以帮助我吗?

示例按钮如下:

private func iphonePortraitButtons() -> some View {
        
        ZStack {
            VStack {
                
                // Design for Portrait Mode
                
                ////////////////DVD PAUSE BUTTON////////////////
                Button(action: { let generator = UIImpactFeedbackGenerator(style: .heavy)
                    generator.impactOccurred()
                    isDVDLogoPaused.toggle() }) {
                        Rectangle().opacity(1)
                            .foregroundColor(.green)
                    }
                    .frame(width: remoteGeo.size.width * 0.15,
                           height: remoteGeo.size.height * 0.08)
                    .position(x: remoteGeo.size.width * 0.158,
                              y: remoteGeo.size.height * 0.13)
                
                ////////////////INFO BUTTON////////////////
                Button(action: { let generator = UIImpactFeedbackGenerator(style: .heavy)
                    generator.impactOccurred()
                    showFloatingIsland.toggle() }) {
                        Rectangle().opacity(1)
                            .foregroundColor(.green)
                    }
                    .frame(width: remoteGeo.size.width * 0.16,
                           height: remoteGeo.size.height * 0.05)
                    .position(x: remoteGeo.size.width * 0.675,
                              y: remoteGeo.size.height * 0.077)
                
                //////////////////DIGITAL CLOCK BUTTON////////////////
                Button(action: { let generator = UIImpactFeedbackGenerator(style: .heavy)
                    generator.impactOccurred()
                    showDigitalClock.toggle() }) {
                        Rectangle().opacity(1)
                            .foregroundColor(.green)
                    }
                    .frame(width: remoteGeo.size.width * 0.16,
                           height: remoteGeo.size.height * 0.031)
                    .position(x: remoteGeo.size.width * 0.310,
                              y: remoteGeo.size.height * 0.095)
          
                }
               }
              }
swift swiftui uikit uibutton
1个回答
0
投票

主要问题可能是按钮包含在

VStack
中。尝试移除
VStack
,以便按钮由
ZStack
固定。然后在
GeometryReader
周围加上
ZStack
即可给出尺寸。然后可以将整个视图应用为电视图像的叠加层。

这是对您的示例的改编,以显示它的工作原理。您在某些按钮上设置的尺寸非常小,我增加了一些。

struct ContentView: View {
    
    private func buttonIcon(systemName: String) -> some View {
        Image(systemName: systemName)
            .resizable()
            .scaledToFit()
            .foregroundStyle(Color(white: 0.2, opacity: 0.2))
    }
    
    private func iphonePortraitButtons() -> some View {
        GeometryReader { proxy in
            let w = proxy.size.width
            let h = proxy.size.height
            ZStack {
                
                Button {
                    print("pause")
                } label: {
                    buttonIcon(systemName: "pause.rectangle.fill")
                        .frame(width: w * 0.16, height: h * 0.16)
                        .position(x: w * 0.158, y: h * 0.13)
                }
                
                Button {
                    print("info")
                } label: {
                    buttonIcon(systemName: "info.square.fill")
                        .frame(width: w * 0.16, height: h * 0.16)
                        .position(x: w * 0.675, y: h * 0.077)
                }
                
                Button {
                    print("clock")
                } label: {
                    buttonIcon(systemName: "clock.fill")
                        .frame(width: w * 0.16, height: h * 0.16)
                        .position(x: w * 0.310, y: h * 0.095)
                }
            }
        }
    }
    
    var body: some View {
        Image(systemName: "tortoise")
            .resizable()
            .scaledToFit()
            .foregroundStyle(.orange)
            .background(.blue.opacity(0.1))
            .overlay {
                iphonePortraitButtons()
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

Screenshot

© www.soinside.com 2019 - 2024. All rights reserved.