如何强制焦点更改为 tvOS 中的特定视图?

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

我正在实现自定义代码来处理对 Siri Remote 上“菜单”按钮的点击。 如何在按下菜单按钮时强制焦点更改到我的自定义菜单?

终于自己弄明白了。您必须覆盖 UIViewUIViewControllerpreferredFocusedView 属性。

在 Swift 中它是这样工作的:

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

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

我不太记得如何覆盖 Objective-C 中的吸气剂,所以如果有人想要 post 我会编辑答案。

这里是 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;

}

在您的 viewDidLoad 或视图中确实出现了这样的事情:

    UIFocusGuide *focusGuide = [[UIFocusGuide alloc]init];
    focusGuide.preferredFocusedView = [self preferredFocusedView];
    [self.view addLayoutGuide:focusGuide];

如果您想在首次启动时执行此操作

这是另一个基于上述 Slayter 回答的实现。我认为它比使用条件布尔值更优雅。

将此放入您的 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;
    }
}

然后在您的代码中使用它

viewToFocus = myUIView;

@elu5ion 的回答,但是在 objective-c 首先声明:

@property (nonatomic) UIView *preferredView;

设置这些方法:

-(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;
}

这是一个不错的小 Swift 2 复制/粘贴片段:

var myPreferredFocusedView: UIView?
override var preferredFocusedView: UIView? {
    return myPreferredFocusedView
}
func updateFocus(to view: UIView) {
    myPreferredFocusedView = napDoneView
    setNeedsFocusUpdate()
    updateFocusIfNeeded()
}

这样使用:

updateFocus(to: someAwesomeView)

对于 ios 10,您应该使用 preferredFocusEnvironments 而不是 preferredFocusedView 。

在下面的例子中,如果你想关注 button 然后看下面的代码。

@IBOutlet weak var button: UIButton!

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

override func viewDidLoad() {
    super.viewDidLoad()

    setNeedsFocusUpdate()
    updateFocusIfNeeded()
}