I am implementing custom code to handle a click on the Menu button on the Siri Remote. How can I force focus to change to my custom menu when pressing the menu button?
-
This question addresses a common tvOS focus issue [just go through]: https://stackoverflow.com/questions/40837449/tvos-focus-not-moving-correctly/52251007#52251007 – abhimuralidharan Sep 10 '18 at 10:43
6 Answers
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()
}

- 12,630
- 8
- 75
- 122

- 1,868
- 2
- 18
- 26
-
3This should be the accepted answer now since `preferredFocusedView` is being depreciated. – Reza Shirazian Apr 11 '17 at 03:30
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.

- 7,706
- 4
- 17
- 13

- 1,172
- 1
- 13
- 26
-
Thank you. I was considering doing it like this, but it seems soooooo messy to put all these "someConditions" all over the place. Would be so much easier if you could just setPreferredFocusedView... – Simen Øian Gjermundsen Sep 24 '15 at 21:14
-
But, wait. How does this work when I want to change the focus to another viewcontroller? – Simen Øian Gjermundsen Sep 24 '15 at 21:16
-
2I agree. Hopefully they'll add it. Also to avoid all the `someCondition`s, I added a `viewToFocus` `UIView` property to my viewController. Then in the getter, I check if that view is not nil and return it. Otherwise return the default view. – Slayter Sep 24 '15 at 22:27
-
1In regards to your viewController question, if the viewControllers view is apart of the parent viewController's hierarchy (I assume this is what you mean) then return the view of the viewController in your parent viewController's `preferredFocusedView` getter. – Slayter Sep 24 '15 at 22:28
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;

- 161
- 1
- 4
-
1this was deprecated in iOS 10. the suggest using preferredFocusEnvironments – nyxee Aug 02 '17 at 08:36
here is the objective C
- (UIView *)preferredFocusedView
{
if (someCondition) {
// this is if your menu is a tableview
NSIndexPath *ip = [NSIndexPath indexPathForRow:2 inSection:0];
UITableViewCell * cell = [self.categoryTableView cellForRowAtIndexPath:ip];
return cell;
}
return self.view.preferredFocusedView;
}
in your viewDidLoad or view did appear do something like this:
UIFocusGuide *focusGuide = [[UIFocusGuide alloc]init];
focusGuide.preferredFocusedView = [self preferredFocusedView];
[self.view addLayoutGuide:focusGuide];
if you want to do it when it first launches

- 2,553
- 2
- 16
- 24
-
I am getting nill for the cell and i am using collectionview instead of tableview! Any idea why it is nil? – IamDev Nov 25 '16 at 08:50
Here's a nice little Swift 2 copy / paste snippet:
var myPreferredFocusedView: UIView?
override var preferredFocusedView: UIView? {
return myPreferredFocusedView
}
func updateFocus(to view: UIView) {
myPreferredFocusedView = napDoneView
setNeedsFocusUpdate()
updateFocusIfNeeded()
}
Use it like this:
updateFocus(to: someAwesomeView)

- 4,150
- 4
- 35
- 67
@elu5ion 's answer, but in objective-c first declare:
@property (nonatomic) UIView *preferredView;
Set these methods:
-(void)setPreferredView:(UIView *)preferredView{
if (preferredView != nil) {
_preferredView = nil;
UIFocusGuide *focusGuide = [[UIFocusGuide alloc]init];
[self.view addLayoutGuide:focusGuide];
focusGuide.preferredFocusedView = [self preferredFocusedView];
[self setNeedsFocusUpdate];
[self updateFocusIfNeeded];
}
_preferredView = preferredView;
}
- (UIView *)preferredFocusedView {
if (_preferredView) {
return _preferredView;
}
return self.view.preferredFocusedView;
}

- 2,553
- 2
- 16
- 24