0

I use UIScrollView.appearance().backgroundColor to change the background color of my ContentView. But unfortunately, that has the side effect that the colors of my ModalView() are not quite normal anymore.

To solve the problem, I see three possible solutions:

The first option is somehow to assign the UIScrollView.appearance().backgroundColor = UIColor.red only to the first ScrollView.

The second would be to find another way to change the background color of my ContentView().

And the third option would be to reset the UIScrollView.appearance().backgroundColor in ModalView()back to the default setting. (EDIT: I think now that the third option is not possible)

And thanks for every answer

import SwiftUI

struct ContentView: View {
    @State private var show_modal: Bool = false

    var body: some View {
        UIScrollView.appearance().backgroundColor = UIColor.red // This how I change the backgroundcolor of this View

        return NavigationView {
            ScrollView { // This ScrollView should be affected by the initializer
                VStack(spacing: 12) {
                    HStack {
                        Text("Only unimportant content")
                        Spacer()
                    }
                } .padding(.horizontal).padding(.bottom)
            }

            .navigationBarTitle(Text("Header"))
            .navigationBarItems(
                leading:
                Button(action: { self.show_modal = true }) {
                    Image(systemName: "plus")
                        .padding(.all, 10)
                } .sheet(isPresented: self.$show_modal) { ModalView() }.padding(.leading, -10)
            )
        }
    }
}

struct ModalView: View { // This should not be affected by the initializer
    @Environment(\.presentationMode) var presentationMode
    @State private var name: String = ""

    var body: some View {
        // UIScrollView.appearance().backgroundColor = UIColor.red // If anyone knows the default value, please enter this here

        return NavigationView {
            Form {
                List {
                    TextField("This is a TextField", text: $name)
                }
            }

            .navigationBarTitle(Text(""), displayMode: .inline)
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(
                leading:
                Button(action: { self.presentationMode.wrappedValue.dismiss() }) {
                    Text("Cancel")
                }.padding(.vertical, 5)
            )
        }
    }
}


This is my ModalView() with the "beautiful" side effects enter image description here

In this picture, you can see what makes me believe that the third option is not possible:
- The interior of the selected text field is discolored
- The auto-correction suggestions are also discolored
- With dark mode turned on it gets even worse
enter image description here

Mattis Schulte
  • 639
  • 1
  • 10
  • 18

3 Answers3

3

Just apply the background colour directly to the scroll view.

return VStack{
    ScrollView { // This ScrollView should be affected by the initializer
        Text("Text 1")
    }
        .background(Color.red)
    ScrollView { // This ScrollView should NOT be affected by the initializer
        Text("Text 2")
    }
}
Chris
  • 4,009
  • 3
  • 21
  • 52
  • No, that's not the solution to my problem. It may work in the example code above, but as I said before, this is a much-simplified version. And unfortunately, it does not work in my real project. But thanks for the answer anyway. And I have edited the example code a bit to make it more like my real project. – Mattis Schulte Nov 20 '19 at 12:23
  • @MattisSchulte Is there a reason you need to use the `appearance()` API then? You can still override it for individual views. – Chris Nov 20 '19 at 12:26
  • Yes, I need the ```appearance()``` API, as this is the easiest way to change the background color of the ContenView, including the navigation bar, when using ```ScrollView``` and ```NavigationView``` together. But you're right that I can still override it for individual views. So if I could find a way to set the Appearance API back to default, my problem would be solved. – Mattis Schulte Nov 20 '19 at 12:42
  • only use appearance() if swiftUI cant achieve what you want. Changing the backgroundcolor of a ScrollView in swiftUI shouldn't be a problem, so there is absolutely no need for appearance() – KevinP Nov 20 '19 at 13:16
  • @Mamaessen Regrettably, changing the background color when using ```ScrollView``` and ```NavigationView``` is a very big problem. But if you want to know more about this topic, [here](https://stackoverflow.com/questions/56923397/how-change-background-color-if-using-navigationview-in-swiftui) is a good question. – Mattis Schulte Nov 20 '19 at 13:35
1

The default backgroundcolor for a sheet is secondarySystemBackground.

UIScrollView.appearance().backgroundColor = UIColor.secondarySystemBackground
KevinP
  • 2,562
  • 1
  • 14
  • 27
1

You can specify modal view as a specifical case like the following:

    UIScrollView.appearance().backgroundColor = UIColor.red //normal 
    UIScrollView.appearance(whenContainedInInstancesOf: [UIPresentationController.self]) .backgroundColor = UIColor.white //modal

If you want a better result, just specify subclass of UIScrollView.

    UIScrollView.appearance().backgroundColor = UIColor.red
    UIScrollView.appearance(whenContainedInInstancesOf: [UIPresentationController.self]).backgroundColor = UIColor.clear
    UITableView.appearance(whenContainedInInstancesOf: [UIPresentationController.self]).backgroundColor = UIColor.secondarySystemBackground
E.Coms
  • 11,065
  • 2
  • 23
  • 35