You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SwiftUI App窗口UI分为两色区域并固定拆分效果

解决方案:固定文本框周边透明区域,窗口resize时保持不变

核心问题分析

原方案依赖窗口高度的比例值设置颜色区域和透明区域的高度,导致窗口调整大小时,透明区域高度会随窗口比例同步变化,完全违背了“透明区域固定”的需求。

优化方案

将底部透明区域设置为固定高度,上方颜色区域自动填充剩余窗口空间;同时调整布局层级,让文本框始终锚定在固定高度的透明区域内,确保窗口resize时透明区域尺寸完全不变。

优化后的完整代码

import SwiftUI

struct ContentView: View {
    @State private var textFieldContent = ""
    // 自定义固定透明区域高度,可按需调整
    private let transparentAreaHeight: CGFloat = 120
    
    var body: some View {
        ZStack {
            VisualEffectView()
            
            // 背景区域拆分:上方颜色区 + 底部固定高度透明区
            VStack(spacing: 0) {
                // 上方颜色区:自动填充除底部透明区外的所有空间
                Color(red: 0.1, green: 0.1, blue: 0.1)
                    .frame(maxHeight: .infinity)
                // 底部固定高度的透明区域
                Color.clear
                    .frame(height: transparentAreaHeight)
            }
            
            // 文本框与发送按钮:固定在底部透明区域内
            HStack {
                TextField("Send a message", text: $textFieldContent)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .padding()
                    .background(Color.clear)
                    .cornerRadius(25)
                    .focusable(false)
                    .padding(.leading, 20)
                
                Spacer()
                
                Button(action: {
                    // 按钮执行逻辑
                }) {
                    Text("Send")
                        .foregroundColor(.blue)
                }
                .buttonStyle(PlainButtonStyle())
                .padding(.trailing, 20)
            }
            .frame(maxWidth: .infinity, alignment: .bottom)
            .padding(.bottom, 20) // 调整文本框在透明区域内的垂直位置
            
            // 设置按钮:固定在右上角
            VStack {
                HStack {
                    Spacer()
                    Button(action: {
                        // 设置按钮执行逻辑
                    }) {
                        Image(systemName: "gearshape")
                            .foregroundColor(.blue)
                            .padding()
                    }
                    .buttonStyle(PlainButtonStyle())
                }
                Spacer()
            }
            .padding(.top, 20)
            .padding(.trailing, 20)
        }
        .edgesIgnoringSafeArea(.all)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct VisualEffectView: NSViewRepresentable {
    func makeNSView(context: Context) -> NSVisualEffectView {
        let view = NSVisualEffectView()
        view.blendingMode = .behindWindow
        view.state = .active
        view.material = .underWindowBackground
        return view
    }
    
    func updateNSView(_ nsView: NSVisualEffectView, context: Context) {}
}

关键修改说明

  1. 移除了原代码中依赖窗口比例的GeometryReader逻辑,改用固定高度定义透明区域
  2. 上方颜色区域通过frame(maxHeight: .infinity)自动填充剩余空间,无需手动计算比例
  3. 文本框通过.frame(maxWidth: .infinity, alignment: .bottom)和固定padding,确保始终位于底部透明区域内
  4. 简化布局层级,去掉冗余嵌套,提升代码可读性与运行性能

补充拓展技巧

如果需要让透明区域的宽度也固定(仅文本框周围保留透明),可将底部区域改为左右颜色区+中间固定宽度透明区,示例如下:

// 底部区域改为左右颜色填充+中间固定宽高透明区
HStack(spacing: 0) {
    Color(red: 0.1, green: 0.1, blue: 0.1)
        .frame(maxWidth: .infinity)
    Color.clear
        .frame(width: 400, height: transparentAreaHeight) // 固定宽度和高度
    Color(red: 0.1, green: 0.1, blue: 0.1)
        .frame(maxWidth: .infinity)
}

内容的提问来源于stack exchange,提问作者P_n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 19:27:41