简体   繁体   中英

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

So I have some buttons that I've added to a view through the Interface Builder and rather than using the system buttons I made them custom. I'm trying to figure out how to change characteristics, such as the text color and background color during different states (highlighted, focused, etc).

It doesn't seem like I can do it through the IB so I'll probably make a subclass of UIButton and change them there, but I'm having trouble finding what properties to change. I don't see them explicitly mentioned in the documentation

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!

In addition to @Yoseob Lee 's answer, you aren't required to create a UIButton subclass to achieve this. Just make sure you select custom in Interface Builder for the UIButton Type and then override the didUpdateFocusInContext method in the class where you want to change the button's attributes:

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

    if context.nextFocusedView == myButton {
        myButton = UIColor.redColor()
    } else {
        myButton = UIColor.blueColor()
    }
}

@Yoseob Lee is correct, but his answer is missing a few details. Here's a slightly better (subjective) answer.

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    if context.nextFocusedView === self {
        coordinator.addCoordinatedAnimations({ 
            // change the appearance as desired
            }, completion: nil)
    } else if context.previouslyFocusedView === self {
        coordinator.addCoordinatedAnimations({ 
            // revert back to default appearance
            }, completion: nil)
    }
}

Note the === instead of == for comparison. Comparing reference is faster in most cases. Also, adding any changes to appearance into animation coordinator groups changes into default animation (and time) so that change in appearance looks more part of the tvOS default behavior. Also, making sure just the previouslyFocusedView is reverted back to default state reduces unnecessary operations.

Both answers above work, but for such simple changes it's easier to use IB to set the attributes for each state. Although the setting is slightly hidden you can indeed change text color and background color.

弹出以更改状态配置

You can do the same in code with the following methods:

[aButton setTitleColor:UIColor.greenColor forState:UIControlStateFocused];

Swift 3

An implementation in swift 3.0:

override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {

    coordinator.addCoordinatedAnimations({
        if self.isFocused {
            self.button.alpha = 1.0 // in focus 
        }
        else {
            self.button.alpha = 0.0 // leaving focus
        }
        }, completion: nil)

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM