How to overwrite the accent color (within the code) in a macOS SwiftUI application? - swift

I'm writing an application where I want there to be a default color and the user can then overwritten it with their own choice. This works in iOS but I realized the macOS version won't let me overwrite the accent color.
To demo this I created a mini project and set the asset to pink so it would be obvious what the accent color is (noticed if I don't do this it just stays default blue)
I then added a simple list to the main ContentView so I could see the accent color. My code is:
struct ContentView: View {
let myListitems = [
"one", "two", "another", "and more"
]
#State var selectedItem:String?
var body: some View {
VStack {
Text("Hello, world!")
.padding()
List(myListitems, id: \.self, selection: $selectedItem) { item in
Text(item)
}
}
}
}
I then tried to set the accent color to blue on the main WindowGroup part AND (separately) on the ContentView page. Neither affect the pink accent.
Images to show the code changes:
Is there any way that you know of to overwrite this accent color (whether blue or user-defined in assets)? I would love the user to be able to change the color for the entire app but right now can't see how to even affect a view.
Thanks for any help

Users can do that in system preferences by changing accent color and highlight color, multicolor means use the color defined by the apps, other colors mean use that in every app. You don't need to do anything, it works out of the box.
You can reference those colors by NSColor.controlAccentColor and NSColor.selectedContentBackgroundColor if you need them for custom UI elements. As far as I know, SwiftUI only has Color.accentColor out of the box but you can instantiate Color with an NSColor object.

Related

How to control accessibility voiceover text for the SwiftUI Image

For the SwiftUI Image element, the voiceover template is seems "accessibility label - image - image name", e.g. for
var body: some View {
Image(systemName: "equal")
.accessibilityLabel("my label")
}
I am getting voiceover response "my label image equal".
Is it possible for voiceover to only say "my label", and not pronounce the "image equal" part?
Once the element gets the focus, the default trait(link, button, label, etc) will be played after accessibilityLabel text. That's the reason it reads out as "my label -> image"
To add or remove the default trait following methods can be used :
.accessibilityAddTraits
.accessibilityRemoveTraits
Example
To recognize an image as a button:
Add .isButton trait and remove the .isImage trait, now VoiceOver can read the description of Image as "my label -> button"
struct ContentView: View {
var body: some View {
Image(systemName: "equal")
.accessibilityLabel("my label")
.accessibilityAddTraits(.isButton)
.accessibilityRemoveTraits(.isImage)
}
}
As an element can have multiple traits, remove the ones you don't want the voiceover to read.

How to resize List items with a sidebar style

I want to reduce the size of the items in a List view, more precisely the height, the list being styled like a sidebar (.listStyle(.sidebar)). I tried changing the size with .controlSize(.mini) but it didn't work. It worked for other list styles (plain, bordered, etc.).
What strikes me is that Xcode sidebar does have list items that are smaller than the regular size, so it should be possible !
Side by side comparison between Xcode sidebar and my app sidebar
Is there a simple and idiomatic way to do this ?
Apologies if I am not correctly understanding the question but can't you just set the frame of the items? For example:
struct SwiftUIView: View {
var body: some View {
List {
ForEach((1...10), id: \.self) {_ in
Text("hello")
.frame(height: 50) // <- Right here!
}
}
.listStyle(.sidebar)
}
}
Where 50 would be the height you want.

How do I change text color when navigation link is selected? SwiftUI Mac Catalyst

I have used a List of NavigationLink to generate my sidebar but when running as a Mac Catalyst app all selections use the system accent color as their background. This is fine but where the colour is dark I want the text to invert to white like it does in most Mac apps.
Can anyone help? Here's my code:
List {
ForEach(topics, id: \.self) { topic in
NavigationLink(
destination: DetailView(selectedDate: self.titles[topic])
) {
HStack {
Image(topic)
Text(self.titles[topic]!)
}
}
}
}
Btw topic is an array of strings which are the keys for the dictionary titles. Thanks in advance.
Have you tried using the new Label(_:) element, instead of a custom HStack with image + text? Swift "2" now has Label which when coupled with the SidebarListStyle should do what you want to. Text goes to highlighted color when selected. Since you're using custom images, I'm not sure what happens there, but give it a try.
Instead of:
HStack {
Image(...)
Text(...)
}
Just use:
Label("Formalism", image: "formalism.png")

SwiftUI TextField keyboard flashes and breaks typing in other languages

https://youtu.be/ngExUJ7gyb8
Please observe the different behavior between system keyboard and the one using SwiftUI.
The first 5 seconds using spotlight search, you'll notice the typing is complete and the word picker does not flash for every character input.
In the last 5 second, you'll notice using SwiftUI's keyboard, the typing will be break every couple characters, and the word picker flashes for every new character input.
The same behavior can be observed using the simplest code
struct ContentView: View {
#State private var inputText = ""
var body: some View {
VStack(spacing: 10.0) {
TextField("Tap here", text: $inputText)
}
}
}
Is that a bug of SwiftUI? Or did I miss something?

SwiftUI TextField wobble on text change. Doesn't reproduce on all machine

So I made a simple app with simple text field instance bound to a local variable in SwiftUI
TextField("Main task", text: $store.mainTask)
.textFieldStyle(RoundedBorderTextFieldStyle())
.font(Font.custom("SF Pro Display", size: 14))
The text field is wrapped inside a view with transition and animation.
// text field is inside custom View
// conditional rendering—if that matters
if (true) {
CustomView()
.transition(.asymmetric(insertion: AnyTransition.opacity.animation(Animation.easeInOut(duration: 1).delay(0.5)), removal: AnyTransition.opacity.animation(Animation.easeInOut(duration: 0.1))))
}
I distributed the beta. Some people say they experienced the text wobbling as they typed. Some didn't. Does anyone know what's the reason?
I think it might be related with the animation, but I'm not so sure.