TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Why does my Linear Gradient have a solid (white/black) background behind it?

Forums > SwiftUI

LinearGradient(gradient: Gradient(colors: [
            Color(.sRGB, red: 0/255, green: 0/255, blue: 0/255, opacity: 0.2),
            Color(.sRGB, red: 0/255, green: 0/255, blue: 0/255, opacity: 0)]),
                       startPoint: .bottom, endPoint: .top)
            .frame(height: 20)
            .cornerRadius(5)
            .offset(x: 0, y: 5)
        ZStack {
            Rectangle()
                .fill(Color("Theme"))
                .frame(height: 60)
            HStack {

                Image("Home")
                    .renderingMode(.template)
                    .resizable()
                    .frame(width: 16, height: 18.59)
                    .padding(.leading, 40)
                    .foregroundColor(self.index != 0 ? Color(red: 70/255, green: 70/255, blue: 73/255) : Color("Accent"))
                    .onTapGesture {
                        self.index = 0
                    }

                Spacer()

                Image("Checklist")
                    .renderingMode(.template)
                    .resizable()
                    .frame(width: 20, height: 20)
                    .foregroundColor(self.index != 1 ? Color(red: 70/255, green: 70/255, blue: 73/255) : Color("Accent"))
                    .onTapGesture {
                        self.index = 1
                    }

                Spacer()

                Button(action: {
                    showAddSheet = true
                }, label: {
                    Circle()
                        .fill(Color("Accent"))
                        .frame(width: 48, height: 48)
                        .overlay(
                            ZStack {
                                Rectangle()
                                    .fill(.white)
                                    .frame(width: 3, height: 14)
                                Rectangle()
                                    .fill(.white)
                                    .frame(width: 14, height: 3)
                            }
                        )
                })

                Spacer()

                Image("Upgrades")
                    .renderingMode(.template)
                    .resizable()
                    .frame(width: 18, height: 18)
                    .foregroundColor(self.index != 2 ? Color(red: 70/255, green: 70/255, blue: 73/255) : Color("Accent"))
                    .onTapGesture {
                        self.index = 2
                    }

                Spacer()

                Image("Settings")
                    .renderingMode(.template)
                    .resizable()
                    .frame(width: 19.4, height: 20)
                    .padding(.trailing, 40)
                    .foregroundColor(self.index != 3 ? Color(red: 70/255, green: 70/255, blue: 73/255) : Color("Accent"))
                    .onTapGesture {
                        self.index = 3
                    }

            }
            .padding(.top, 8)
            .sheet(isPresented: $showAddSheet) {
                AddTaskView(negativeTasks: .constant(false), bonusTasks: .constant(false))
                    .environment(\.managedObjectContext, self.viewContext)
            }
        }

2      

Have you ever had a maths problem where the instructor poses a verbose word problem?

Thomas and Emily are approaching a switch. Thomas is carrying 100 Winterfest trees to the towne centre. Emily is in a rush and has two troublesome trucks with 2.7 tonnes of coal for Gordon who is down at the docks. The docks are 4.3 kilometers south of the towne centre. If Thomas is heading east at 40 kph, and Emily is heading west at 60 kph, what time will the Controller have his tea?

The important skill was tossing out misleading data points, and focusing on the problem's main point. This is what your code felt like when I tried to understand your question! Most of your code has nothing to do with the SwiftUI issue. (A-hem!) What I think you're attempting is a gradual blending from the top of your screen to the toolbar at the bottom. Hard to tell; this was my best guess.

Please watch this updated video (23 Oct 2021). What is behind the main SwiftUI view? In a nutshell, Paul answers your question.

You ask: Why does my Linear Gradient have a solid (white/black) background behind it? Paul's answer: It doesn't. (Watch the video for details.)

But your screenshot clearly shows, uh, white! You need to understand what's happening. I copied your code into Playground and tossed all the references to Winterfest trees, coal, and other unnecessary cruft.

So the biggest clue was your observation of the white/black background behind your linear gradient. Those are the defaults for light and dark mode. So the next question then might be WHY are you seeing these? And why behind your Linear Gradient?

Take a look at your gradient's modifiers. Hey! There's an offset there! You need to remember that SwiftUI draws the gradient in place, then PUSHES in the offset direction. In your code, it pushes it towards the top of the screen, but the gradient's frame remains in its original location. It leaves behind what? An empty space where the default background shines through. But as @twostraws warns in his video, do not try to muck with what's behind your views.

Instead, how do you adjust what you have on screen?

I played around with this for a bit and developed a solution for you to try in Playgrounds. Copy / Paste into Playgrounds. The TestPadding struct has a withPadding constant. Without padding, you'll see how the gradient is pushed up, and the background shows through revealing the cause of your frustration.

Change the withPadding constant to true, and see the results. Maybe this is what you're looking for?

// Solution to @Mast3rGenius's Post
// Why does my Linear Gradient have a solid (white/black) background behind it?
//
// 26 October 2021 by Obelix
//

import SwiftUI
import PlaygroundSupport

struct TestPadding: View {
    let paddingOffset = -40.0
    let withPadding   = false  // test this with true

    var body: some View {
        VStack(spacing: 0) {
            Color(.red).border(.red, width: 0)
            LinearGradient(gradient: Gradient(colors: [ .blue.opacity(1), .red.opacity(1) ]),
                           startPoint: .bottom, endPoint: .top)
                .frame(height: 40)  // gradient's frame
                .offset(y: paddingOffset)
                .padding(.bottom, withPadding ? paddingOffset : 0)  // possible solution?
            Color(.blue).border(.blue, width: 0)
        }
        .frame(width: 500, height: 400)
    }
}

let testView = TestPadding()
PlaygroundPage.current.setLiveView(testView)

Gradient Leak

3      

Not exactly what I was looking for, but I think you lead me to my desired solution? Will update. Also, I understand why this didn't make a whole lot of sense without more context.

2      

Hacking with Swift is sponsored by Blaze.

SPONSORED Still waiting on your CI build? Speed it up ~3x with Blaze - change one line, pay less, keep your existing GitHub workflows. First 25 HWS readers to use code HACKING at checkout get 50% off the first year. Try it now for free!

Reserve your spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.