tvOS - preferredFocusEnvironments 不工作
tvOS - preferredFocusEnvironments not working
因为我在另一个 UINavigationController 中需要一个 UINavigationController(默认情况下这是不可能的),所以我创建了一个 UIViewController 作为 UINavigationController,但它不是 UINavigationController 的子类。
第二个 NavigationController(对 UINavigationController 进行子类化的那个)提供(取决于 ViewModel 的状态)一个控制器。
这是自定义 NavigationController:
class OnboardingViewController: UIViewController {
// MARK: - Outlets
@IBOutlet weak var containerView: UIView!
// MARK: - Internal
private var viewModel: OnboardingViewModel = OnboardingViewModel()
// MARK: - View flow
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
navigateToNextFlow()
}
override var preferredFocusEnvironments: [UIFocusEnvironment] {
switch viewModel.state {
case .recommendations: return recommendationsController.preferredFocusEnvironments
default: return super.preferredFocusEnvironments
}
}
// MARK: - Handlers
var navigateToNextHandler: (() -> Void)?
// MARK: - Controllers
private var recommendationsController: OnboardingRecommendationsViewController {
let controller = UIViewController.instantiate(from: "Onboarding Recommendations") as OnboardingRecommendationsViewController
controller.navigateToNextHandler = { [unowned self] in
self.viewModel.state = .done
self.navigateToNextFlow(animated: true)
}
return controller
}
// MARK: - Navigation
private func navigateToNextFlow(animated: Bool = false) {
switch viewModel.state {
case .recommendations:
add(child: recommendationsController, to: containerView)
case .done:
viewModel.finish()
navigateToNextHandler?()
}
updateFocusIfNeeded()
setNeedsFocusUpdate()
}
}
这是子视图控制器:
class OnboardingRecommendationsViewController: UIViewController {
// MARK: - Outlets
@IBOutlet weak var onOffButton: UIButton!
@IBOutlet weak var finishButton: UIButton!
// MARK: - Internal
fileprivate let viewModel: OnboardingRecommendationsViewModel = OnboardingRecommendationsViewModel()
// MARK: - View flow
override func viewDidLoad() {
super.viewDidLoad()
setupLabels()
setupOnOffButton()
}
// MARK: - Handlers
var navigateToNextHandler: (() -> Void)?
// MARK: - Focus
override var preferredFocusEnvironments: [UIFocusEnvironment] {
return [finishButton, onOffButton]
}
}
finishButton 在情节提要中的 onOffButton 下方。我正在尝试将初始焦点设置在 finishButton 而不是 onOffButton 上。但是用户可以根据需要关注 onOffButton。
无论我尝试什么,都行不通。 preferredFocusEnvironments 被调用,但按钮的焦点保持在错误的顺序。
我做错了什么?
你试过吗?
override var preferredFocusEnvironments: [UIFocusEnvironment] {
return [finishButton]
}
或者您可以禁用 onOffButton 的 userInteraction,直到 finishButton 获得焦点。 (虽然不是一个好的解决方案)
您应该设置 restoresFocusAfterTransition = false 以避免默认行为。然后,在 preferredFocusEnvironments return 您想要聚焦的视图中
抱歉回答晚了。原来我推送的 viewController 定义为 let
,所以我自己推送了几个实例,这就是为什么 preferredFocusEnvironments
似乎不起作用的原因。我实际上看到了 ViewController 的一个新实例,它具有另一个初始焦点顺序。将 viewController 的变量声明从 let
更改为 lazy var
就可以了。所以,最后,它真的与 preferredFocusEnvironments
不工作无关。但感谢您的输入!
因为我在另一个 UINavigationController 中需要一个 UINavigationController(默认情况下这是不可能的),所以我创建了一个 UIViewController 作为 UINavigationController,但它不是 UINavigationController 的子类。
第二个 NavigationController(对 UINavigationController 进行子类化的那个)提供(取决于 ViewModel 的状态)一个控制器。
这是自定义 NavigationController:
class OnboardingViewController: UIViewController {
// MARK: - Outlets
@IBOutlet weak var containerView: UIView!
// MARK: - Internal
private var viewModel: OnboardingViewModel = OnboardingViewModel()
// MARK: - View flow
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
navigateToNextFlow()
}
override var preferredFocusEnvironments: [UIFocusEnvironment] {
switch viewModel.state {
case .recommendations: return recommendationsController.preferredFocusEnvironments
default: return super.preferredFocusEnvironments
}
}
// MARK: - Handlers
var navigateToNextHandler: (() -> Void)?
// MARK: - Controllers
private var recommendationsController: OnboardingRecommendationsViewController {
let controller = UIViewController.instantiate(from: "Onboarding Recommendations") as OnboardingRecommendationsViewController
controller.navigateToNextHandler = { [unowned self] in
self.viewModel.state = .done
self.navigateToNextFlow(animated: true)
}
return controller
}
// MARK: - Navigation
private func navigateToNextFlow(animated: Bool = false) {
switch viewModel.state {
case .recommendations:
add(child: recommendationsController, to: containerView)
case .done:
viewModel.finish()
navigateToNextHandler?()
}
updateFocusIfNeeded()
setNeedsFocusUpdate()
}
}
这是子视图控制器:
class OnboardingRecommendationsViewController: UIViewController {
// MARK: - Outlets
@IBOutlet weak var onOffButton: UIButton!
@IBOutlet weak var finishButton: UIButton!
// MARK: - Internal
fileprivate let viewModel: OnboardingRecommendationsViewModel = OnboardingRecommendationsViewModel()
// MARK: - View flow
override func viewDidLoad() {
super.viewDidLoad()
setupLabels()
setupOnOffButton()
}
// MARK: - Handlers
var navigateToNextHandler: (() -> Void)?
// MARK: - Focus
override var preferredFocusEnvironments: [UIFocusEnvironment] {
return [finishButton, onOffButton]
}
}
finishButton 在情节提要中的 onOffButton 下方。我正在尝试将初始焦点设置在 finishButton 而不是 onOffButton 上。但是用户可以根据需要关注 onOffButton。
无论我尝试什么,都行不通。 preferredFocusEnvironments 被调用,但按钮的焦点保持在错误的顺序。
我做错了什么?
你试过吗?
override var preferredFocusEnvironments: [UIFocusEnvironment] {
return [finishButton]
}
或者您可以禁用 onOffButton 的 userInteraction,直到 finishButton 获得焦点。 (虽然不是一个好的解决方案)
您应该设置 restoresFocusAfterTransition = false 以避免默认行为。然后,在 preferredFocusEnvironments return 您想要聚焦的视图中
抱歉回答晚了。原来我推送的 viewController 定义为 let
,所以我自己推送了几个实例,这就是为什么 preferredFocusEnvironments
似乎不起作用的原因。我实际上看到了 ViewController 的一个新实例,它具有另一个初始焦点顺序。将 viewController 的变量声明从 let
更改为 lazy var
就可以了。所以,最后,它真的与 preferredFocusEnvironments
不工作无关。但感谢您的输入!