How can I force focus to change to a specific view in tvOS?

Finally figured it out myself. You have to override the preferredFocusedView property of your UIView or UIViewController.

In Swift it works like this:

func myClickHandler() {
    someCondition = true
    self.setNeedsFocusUpdate()
    self.updateFocusIfNeeded()
    someCondition = false
}

override weak var preferredFocusedView: UIView? {
    if someCondition {
        return theViewYouWant
    } else {
        return defaultView
    }
}

I can't quite remember how to override getters in Objective-C so if someone want to post that I'll edit the answer.


Here is another implementation based on Slayters answer above. Its slightly more elegant I think than using the conditional booleans.

Put this in your viewcontroller

var viewToFocus: UIView? = nil {
    didSet {
        if viewToFocus != nil {
            self.setNeedsFocusUpdate();
            self.updateFocusIfNeeded();
        }
    }
}

override weak var preferredFocusedView: UIView? {
    if viewToFocus != nil {
        return viewToFocus;
    } else {
        return super.preferredFocusedView;
    }
}

Then to use it in your code

viewToFocus = myUIView;

For ios 10 you should use preferredFocusEnvironments instead of preferredFocusedView .

In below example if you want to focus on button then see below code.

@IBOutlet weak var button: UIButton!

override var preferredFocusEnvironments: [UIFocusEnvironment] {
    return [button]
}

override func viewDidLoad() {
    super.viewDidLoad()

    setNeedsFocusUpdate()
    updateFocusIfNeeded()
}