tvOS:焦点移动不正确

3

我有一个UIView,上面有两个按钮。在MyView类中,我有以下代码:

-(BOOL) canBecomeFocused {
    return YES;
}

-(NSArray<id<UIFocusEnvironment>> *)preferredFocusEnvironments {
    return @[_editButton, _addButton];
}

-(IBAction) editTapped:(id) sender {
    BOOL editing = !tableViewController.editing;
    [_editButton setTitle:editing ? @"Done" : @"Edit" forState:UIControlStateNormal];
    _addButton.hidden = !editing;
    [tableViewController setEditing:editing animated:YES];

基本思路是用户可以将焦点移动到编辑按钮,然后可以使添加按钮出现。

问题的起因是每次我点击编辑按钮时,焦点会转移到表格视图。实际上,我希望它移动到添加按钮。我还希望在编辑被禁用时,编辑按钮保持焦点。但是,它又向下移动到了表格视图。

所以我尝试了上面的代码。这个方法有效,因为焦点可以移动到视图上并移动到按钮上。但一旦到达那里,我就无法让它移动到其他地方。

我读过的所有内容都说只需覆盖preferredFocusEnvironments即可,但迄今为止我还没有能够让它起作用。焦点始终会转移到一个按钮,然后拒绝移动到其他任何地方。

有什么想法吗?


这证明真的很困难。我现在正在尝试使用 UIFocusGuide,但似乎从按钮到表视图的焦点转移是系统生成的移动,并忽略了我的焦点指南。即使我把它放在它们之间。 Grrr. - drekka
2个回答

4
如果有人遇到这个问题,请检查控制台是否打印以下调试信息。
警告:在进行焦点更新时调用updateFocusIfNeeded。此调用将被忽略。
我有以下代码:
// MARK: - Focus Environment

var viewToBeFocused: UIView?

func updateFocus() {
    setNeedsFocusUpdate()
    updateFocusIfNeeded()
}

override var preferredFocusEnvironments: [UIFocusEnvironment] {
    if let viewToBeFocused = self.viewToBeFocused {
        self.viewToBeFocused = nil
        return [viewToBeFocused]
    }
    return super.preferredFocusEnvironments
}

我在viewToBeFocused为空或者有其他视图时,多次调用了updateFocus()方法。在转场之间调试焦点问题非常困难,需要耐心。需要注意的是:这取决于您的使用情况,但如果您想在视图控制器转换(向后导航)后立即更新焦点,则可能需要在viewDidLoad中设置以下内容。
restoresFocusAfterTransition = false // default is true

如果这是真的,那么即使我们通过调用 updateFocusIfNeeded() 强制进行焦点更新,视图控制器也会倾向于聚焦最后一个聚焦的视图。在这种情况下,由于焦点更新已经在进行中,您将在此答案顶部之前提到的地方收到警告。

调试焦点问题

使用以下链接来调试焦点问题: https://developer.apple.com/documentation/uikit/focus_interactions/debugging_focus_issues_in_your_app

首先在“编辑 scheme > 在启动时传递的参数”下启用焦点调试器:

-UIFocusLoggingEnabled YES

enter image description here

这将记录焦点引擎尝试更新焦点的所有尝试。这非常有帮助。

1
对我来说,重要的是确保我不在“viewDidAppear()”中调用“updateFocusIfNeeded()”,可能是因为,正如答案中所述,此时应用程序已经处于焦点更改的中间阶段。 - Ken Roy

1
你可以使用以下逻辑来覆盖preferredFocusEnviromnets:
-(NSArray<id<UIFocusEnvironment>> *)preferredFocusEnvironments {
    if (condition) {
        return @[_editButton];
    }
    else {
        return @[_addButton];
    }
}

设置完成后,您可以调用


[_myView setNeedsFocusUpdate];
[_myView updateFocusIfNeeded];

条件可以是 BOOL condition = tableViewController.editing; 或类似的内容。
如果现在能够正常工作,您可以延迟调用它(约0.1秒)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接