Search code examples
iosswiftuiuikit

How to set a UISegmentedControl and SwiftUI shape to the same color?


I have created a RoundedRectangle and set its foregroundColor to blue

RoundedRectangle(cornerRadius: 10).foregroundColor(.blue)

I have created a custom SegmentedControl struct and set its color to blue

UISegmentedControl.appearance().selectedSegmentTintColor = .blue

However, the objects render as totally different shades of blue. How can I set them to the same blue color?

Full code:

import SwiftUI

struct ContentView: View {
  @State var choice = Choice.a

  var body: some View {
    VStack {
      Menu { } label: {
        Text("Menu")
          .foregroundColor(.white)
          .padding(5)
          .background(
            RoundedRectangle(cornerRadius: 10)
              .foregroundColor(.blue)
          )
      }
      SegmentedControl(choice: $choice)
        .padding(.horizontal, 50)
    }
  }
}

struct SegmentedControl: View {
  @Binding var choice: Choice
  var choices = [Choice.a, Choice.b]
  
  init(choice: Binding<Choice>) {
    UISegmentedControl.appearance().selectedSegmentTintColor = .blue
    UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
    UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .normal)
    self._choice = choice
  }
  
  var body: some View {
    Picker("Which tab?",
           selection: $choice,
           content: {
      ForEach(choices, id: \.self) {
        Text($0.description())
      }
    })
      .pickerStyle(.segmented)
  }
}

enum Choice {
  case a
  case b
  
  func description() -> String {
    var str = ""
    switch self {
    case .a:
      str = "Choice A"
    case .b:
      str = "Choice B"
    }
    return str
  }
}

Solution

  • The difference is that Color.blue uses UIColor.systemBlue

    So you can approach it two ways

    First, you can change the rectangle

    RoundedRectangle(cornerRadius: 10)
        .foregroundColor(Color(UIColor.blue))
    

    Or second change the control

    UISegmentedControl.appearance().selectedSegmentTintColor = .systemBlue
    

    Either of these changes will match the other. It depends which you prefer.