我开始尝试SwiftUI,我很惊讶,它似乎不是简单的改变一个视图的背景颜色。你如何使用SwiftUI做到这一点?


当前回答

解决方案:

你可以创建一个彩色视图,并将其设置为VStack背景。

struct ColoredView: UIViewRepresentable {
    var color: Color
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        view.backgroundColor = UIColor(color)
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .clear
        }
        return view
    }
    func updateUIView(_ uiView: UIView, context: Context) {}
}

用法:

 VStack {
    Text("VStack with Red backgound")
    Text("VStack with Red backgound")
    Text("VStack with Red backgound")
    Text("VStack with Red backgound")
 }.background(ColoredView(color: .red))

结果:

其他回答

Xcode 11.5

简单地使用ZStack添加背景颜色或图像到你的SwiftUI的主视图

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.black
        }
        .edgesIgnoringSafeArea(.vertical)
    }
}

像这样

struct ContentView : View {
    @State var fullName: String = "yushuyi"
    var body: some View {        
        VStack
            {
                TextField($fullName).background(SwiftUI.Color.red)
                Spacer()
        }.background(SwiftUI.Color.yellow.edgesIgnoringSafeArea(.all))
    }
}

填充整个屏幕:

var body: some View {
    Color.green.edgesIgnoringSafeArea(.all)
}
Code Result

屏幕背景色

(从Xcode Version 13开始)

我不确定最初的海报是指整个屏幕的背景色还是单个视图的背景色。我将添加这个答案,即设置整个屏幕的背景色。

使用ZStack

var body: some View {
    ZStack {
            Color.purple
                .ignoresSafeArea()
            
            // Your other content here
            // Other layers will respect the safe area edges
    }
}

我添加了. ignoressafearea(),否则,它将停止在安全区域边缘。

使用叠加修饰符

var body: some View {
    Color.purple
        .ignoresSafeArea(.vertical) // Ignore just for the color
        .overlay(
            VStack(spacing: 20) {
                Text("Overlay").font(.largeTitle)
                Text("Example").font(.title).foregroundColor(.white)
        })
}

注意:重要的是保持. ignoressafearea为颜色,这样你的主要内容就不会忽略安全区域的边缘。

iOS 15

iOS 15/Xcode 13引入了一些改变样式在安全区域边缘的工作方式。

根据我的观察,规则是:如果样式触及安全区边缘,它就会渗入安全区。

这为设置背景颜色/样式提供了更多选项。

什么是风格?

样式可以是:

颜色 材质(模糊效果) 分层视图(。第二、第三、第四系) 梯度

使用背景

因为VStack的背景接触到安全区域的边缘,紫色会渗入安全区域。

var body: some View {
    VStack {
        Text("Hello, World!")
        Divider()
        Spacer()
    }
    .background(Color.purple)
}

TabView

在iOS 15中,TabView不再是半透明的。这意味着背景色会直接渗透进去。

如果你想为你的TabView提供一个自定义样式,你可以添加另一个触碰底部安全区域边缘的样式,这样它就会渗透到你的TabView中。例如:

var body: some View {
    TabView {
        VStack {
            Text("Hello, World!")
            Divider()
            Spacer()
            // Bleeds into TabView
            Rectangle()
                .frame(height: 0)
                .background(.thinMaterial)
        }
        .background(Color.purple)
        .tabItem {
            Text("Tab 1")
            Image(systemName: "wifi")
        }
    }
}

NavigationView

发生在TabView上的事情也会发生在NavigationView上。

要自定义NavigationView样式,添加一个触摸顶部安全区域边缘的样式,它将渗透到NavigationView:

var body: some View {
    NavigationView {
        VStack {
            // Bleeds into NavigationView
            Rectangle()
                .frame(height: 0)
                .background(.ultraThinMaterial)
            Text("Hello, World!")
            Divider()
            Spacer()
        }
        .background(Color.purple)
        .navigationTitle(Text("Style"))
    }
}

我完全愿意用其他方式来实现这个目标。如果你知道其他方法,请留下评论或编辑这个答案。

我不知道为什么没有人这么说,但是background()修饰符旨在设置背景颜色,并且支持ignoresSafeArea():

var body: some View {
    Text("Da ba dee")
        .background(Color.blue.ignoresSafeArea())
}