Changing The Color of a Button in Swiftui on Tvos

Changing the color of a Button in SwiftUI on tvOS

Again, I have only checked it on iOS, but this should help:

struct ContentView: View {

@State var selected = false

var body: some View {

Button(action: { self.selected.toggle() }) {
Text($selected.wrappedValue ? "On":"Off")
.foregroundColor(.white)
} .padding(.all)
.background(RoundedRectangle(cornerRadius: 5.0)
.fill(self.selected ? Color.green : Color.blue))

}
}

You can pass any view into .background() modifier, so you might also want to try placing an Image() in there.

How can I create a button with a background color for tvOS while still showing focus?

Override didUpdateFocusInContext method and check if next focus view is button, if yes then customize its UI, and to set it back to orignal state check context.previousFocusedView was that button, something like below

- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
{
if (context.nextFocusedView == _button)
{
// set background color
}
else if (context.previousFocusedView == _button)
{
// set background color to background
}
}

In Swift (tvOS) how do you change a UIButton's highlight and focus colors?

You're definitely on the right track!

Once you subclass UIButton, you can override the function didUpdateFocusInContext (from UIFocusEnvironment protocol, which UIButton on tvOS already implements)

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator)

if context.nextFocusedView == self {
// This is when the button will be focused
// You can change the backgroundColor and textColor here
} else {
// This is when the focus has left and goes back to default
// Don't forget to reset the values
}
}

You can also get fancy and transform the frame to imitate the default "focus" effect!

Custom Button style (SwiftUI) tvOS

Apple’s recommended solution is to use the new CardButtonStyle button style, which removes the usual padding but keeps the tvOS hover effects:

Button(action: {}, label: {
Text("B")
.padding()
.background(Color.red)
.clipShape(Circle())
})
.buttonStyle(CardButtonStyle())

However, this still applies a round-rect button background, which doesn’t look good with your Circle background.

I’d recommend updating your design so you can use CardButtonStyle. Button manages its own focus state, so you can’t override or wire-up anything to it. And on tvOS you can’t make your own button from scratch because there is no onTap/onClick event. Your only other real option is to build a custom button in UIKit so you can avoid the limits of SwiftUI on tvOS.

Is it possible to use different colors for focused and selected state on uitabbaritems at tvOS?

I fixed that by setting the the standardAppearance of the tab bar each time the focus changes in my UITabBarController. The relevant code looks like this (the initial setup of appearance is only posted for completeness):

    // setting up standard appearance for the first time
private func setupTabbarAppearance() {
let tabBarAppearance = UITabBarAppearance()
//...
tabBarAppearance.selectionIndicatorTintColor = .focusedBackgroundColor // focused items
//...
let itemAppearance = UITabBarItemAppearance()
//...
itemAppearance.normal.titleTextAttributes[.foregroundColor] = .normalTextColor // used for focused AND non-focused items,
// when the whole tabbar is focused
//...
itemAppearance.selected.titleTextAttributes[.foregroundColor] = .selectedTextColor // used for the selected item,
// wen tabbar is not focused
// ...
tabBarAppearance.inlineLayoutAppearance = itemAppearance
tabBar.standardAppearance = tabBarAppearance
tabBar.setNeedsLayout()
}

private func setTabBarIndicatorColor(tabBarFocused: Bool) {
let currentAppearance = tabBar.standardAppearance
// here is where the color is set
currentAppearance.selectionIndicatorTintColor = tabBarFocused ? .focusedBackgroundColor : .selectedBackgroundColor
tabBar.standardAppearance = currentAppearance
}

// change appearance each time, when focus changes in tabbar controller
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if isTabbarInHierarchy(view: context.nextFocusedView) {
setTabBarIndicatorColor(tabBarFocused: true)
} else {
setTabBarIndicatorColor(tabBarFocused: false)
}
super.didUpdateFocus(in: context, with: coordinator)
}

private func isTabbarInHierarchy(view: UIView?) -> Bool {
guard let view = view else {return false}
if view == tabBar {
return true
}
return isTabbarInHierarchy(view: view.superview)
}

How to create a UIButton for tvOS with a clear background color?

Since tvOS 11 there is a solution for that using the button type "plain" instead of "system" without loosing the effects for focusing and selection:

  1. Open the button properties in the Interface builder an select "Type"->"Plain"Button Properties

  2. Set the button background color to "clear color"

Thats it.

Watch Apples Video about "UIButtonTypePlain" here (starts at 13:44):
UIButtonTypePlain explained

How to set custom highlighted state of SwiftUI Button

Updated for SwiftUI beta 5

SwiftUI does actually expose an API for this: ButtonStyle.

struct MyButtonStyle: ButtonStyle {

func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.padding()
.foregroundColor(.white)
.background(configuration.isPressed ? Color.red : Color.blue)
.cornerRadius(8.0)
}

}

// To use it
Button(action: {}) {
Text("Hello World")
}
.buttonStyle(MyButtonStyle())



Related Topics



Leave a reply



Submit