Search code examples
swiftuiwatchos-6

Is it possible to have overlapping views that don't blend?


I'm trying to mimic the grouped Cancel / Set button pair that you see in places like the Stopwatch app. I've currently done this by using a ZStack with two overlapping RoundedRectangle with different cornerRadius and padding.

This seems to work well shape-wise but there's a subtle colour overlap that I haven't found a way to fix.

This is how it renders

I've tried playing with BlendMode and `opacity' with no luck.

Button(action: {}, label: { Text("Cancel").foregroundColor(Color.white) })
.background(VStack(spacing: 0) {
               ZStack {
                   RoundedRectangle(cornerRadius:20).foregroundColor(Color.gray)
                   RoundedRectangle(cornerRadius: 8).foregroundColor(Color.gray).padding(.leading, 20)
               }})

Does anyone have any ideas?


Solution

  • I've realised that this is actually the button's accent colour being applied. If I set the accentColour to Color.clear, this overlap disappears.

    I actually need this behaviour elsewhere so I've followed Alejandro Martinez's guide on creating reusable Button styles and created this:

    public struct AccentlessButtonStyle: ButtonStyle {
        public func body(configuration: Button<Self.Label>, isPressed: Bool) -> some View {
             configuration.accentColor(Color.clear)
        }
    }
    
    extension StaticMember where Base: ButtonStyle {
        public static var accentless: AccentlessButtonStyle.Member {
            StaticMember<AccentlessButtonStyle>(AccentlessButtonStyle())
        }
    }
    

    It seems to inherit the default button styling in all other ways.

    Using it requires this:

    Button(action: {}, label: { Text("Cancel") }).buttonStyle(.accentless)