【问题标题】:How to set ScrollView's background color in NavigationView in SwiftUI如何在 SwiftUI 的 NavigationView 中设置 ScrollView 的背景颜色
【发布时间】:2020-02-19 11:23:20
【问题描述】:

我无法在 SwiftUI 中的 ScrollView 下设置背景颜色。当我使用.background(Color.red) 时,背景会被切断,因此它不会进入导航栏并且滚动似乎被破坏了。 我尝试了几个解决方案,但每个都不起作用。 我有一个简单的视图层次结构

NavigationView {
    ScrollView([.vertical], showsIndicators: true) {
        VStack {
            ForEach(0...50, id: \.self) { _ in
                Text("Text text")
            }
        }
    }
    .navigationBarTitle("Title", displayMode: .large)
}
.navigationViewStyle(StackNavigationViewStyle())

它按预期工作

现在,我想添加背景颜色,我尝试了以下解决方案

1

NavigationView {
    ScrollView([.vertical], showsIndicators: true) {
        VStack {
            ForEach(0...50, id: \.self) { _ in
                Text("Text text")
            }
        }
    }
    .background(Color.red)
    .navigationBarTitle("Title", displayMode: .large)
}
.navigationViewStyle(StackNavigationViewStyle())

结果

2

NavigationView {
    ZStack {
        Color.red
        ScrollView([.vertical], showsIndicators: true) {
            VStack {
                ForEach(0...50, id: \.self) { _ in
                    Text("Text text")
                }
            }
        }
        .navigationBarTitle("Title", displayMode: .large)
    }
}
.navigationViewStyle(StackNavigationViewStyle())

结果

3

NavigationView {
    ZStack {
        Color.red.edgesIgnoringSafeArea([.all])
        ScrollView([.vertical], showsIndicators: true) {
            VStack {
                ForEach(0...50, id: \.self) { _ in
                    Text("Text text")
                }
            }
        }
        .navigationBarTitle("Title", displayMode: .large)
    }
}
.navigationViewStyle(StackNavigationViewStyle())

结果

如何在ScrollView下设置背景色包装在NavigationView中?

// 编辑:

下面的动画呈现了一个理想的效果(它是用 UIKit 制作的)。

【问题讨论】:

  • 我也有同样的问题。似乎是另一个 SwiftUI 错误。
  • 即使我将 scrollView 放入 ZStack { Color.red, ScrollView } 我也有同样的问题。
  • 你找到解决办法了吗?
  • 不幸的是,没有。我放弃了 SwiftUI 并切换到了 UIKit。 SwiftUI 不完整,无法在生产中使用...
  • 还是不行

标签: ios swift swiftui


【解决方案1】:

你可以这样:

struct ContentView: View {
    init() {
        //Use this if NavigationBarTitle is with Large Font
        UINavigationBar.appearance().backgroundColor = .red
    }
    var body: some View {
        NavigationView {
            ScrollView([.vertical], showsIndicators: true) {
                VStack {
                    ForEach(0...70, id: \.self) { _ in
                        Text("Text text")
                    }
                }.frame(minWidth: 0, maxWidth: .infinity)
                    .background(Color(UIColor.red))
            }
            .navigationBarTitle("Title", displayMode: .large)
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

它会产生一个看起来像这样的视图:

我知道这不是完整的解决方案,因为它具有最高的安全边缘,但希望它可以帮助您更接近一点。

PS 我试过忽略顶部安全边缘,但它会导致导航栏间距出现问题

【讨论】:

  • 这是一种 hack,它不能按应有的方式工作。我不想更改导航栏的颜色,如果我的背景是图像或渐变怎么办?我觉得 SwiftUI 不好闻。
  • 哈哈,SwiftUI 还没开发完。
【解决方案2】:

您可以使用下面使用列表视图的代码实现几乎相同的行为。

struct DemoView: View {
    init(){
        let navigationBarAppearance = UINavigationBarAppearance()
        navigationBarAppearance.backgroundColor = UIColor.red
        UITableView.appearance().separatorStyle = .none
        UITableView.appearance().backgroundColor = UIColor.red
    }
    
    var body: some View {

        NavigationView{
 
                List{

                    ForEach(0..<30, id: \.self){ _ in
                        
                        Text("Text Text")
                        
                    }.listRowBackground(Color(UIColor.red))
            }
            }.navigationBarTitle("Title")
        }
        
    }
}

代码生成这些视图:1 2

【讨论】:

    【解决方案3】:

    在用尽所有可能性之后,我找到了以下解决方案,它非常适合您想要实现的目标。

    struct DemoView: View {
        
        init(){
            let navigationBarAppearance = UINavigationBarAppearance()
            navigationBarAppearance.backgroundColor = UIColor.red
            UIScrollView.appearance().backgroundColor = UIColor.red
        }
        
        var body: some View {
    
            NavigationView{
                    ScrollView{
                        VStack{   
                            ForEach(0..<30, id: \.self){ _ in
                                    Text("Text Text").foregroundColor(Color.black)
                            }
                        }.frame(maxWidth: .infinity)
                         .background(Color(UIColor.red))
                
                }.navigationBarTitle("Title")
            }  
        }
    }
    
    

    希望这会有所帮助;)

    【讨论】:

    • 但是如果我也想实现一个深色主题呢?
    • @leonboe 如果您向视图添加背景颜色,那么您的深色主题将带有您设置的与背景颜色相同的颜色(而不是深色)。如果您设置了深色主题,则只有默认颜色会带有深色。
    • 如果检测到从暗模式 -> 亮模式切换,则无法更改背景颜色,反之亦然?
    • 背景颜色设置好后,明暗模式没有区别。它将完全具有您设置的相同颜色。
    • 警告任何使用 Xcode 12 / SwiftUI 2 的人......将 .padding() 添加到 ScrollView 之外的任何内容都会破坏我项目的上述修复。必须将填充添加到 ScrollView 中的元素,然后这才起作用。这显然是一个成熟的框架的一个方便的特性。
    【解决方案4】:

    这是一个 hacky 的 SwiftUI 解决方案:

    iOS 13 和 iOS 14

    NavigationView {
        ScrollView {
            VStack {
                // ...
            }
            .background(Color.red.frame(height: 99999999))
        }
    }
    

    【讨论】:

    • 似乎对我不起作用。红色背景正确延伸到顶部和底部,但宽度不足以填满整个屏幕。
    猜你喜欢
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    相关资源
    最近更新 更多