我有一个以UITabBarController
开头的简单tvOS应用程序,我希望主视图在应用程序启动时具有焦点,而不是标签栏。
我尝试过玩self.tabBarController.tabBar.userInteractionEnabled
暂时删除焦点,但徒劳无功。 (除此之外我不喜欢那种解决方法)
有任何线索吗?
提前致谢。
答案 0 :(得分:6)
我原来的解决方案不再适用于tvOS 9.3,所以我发现了一个带有子类UITabBarController
的新解决方案:
@interface TVTabBarController : UITabBarController
@property (nonatomic) BOOL useDefaultFocusBehavior;
@end
@implementation TVTabBarController
- (UIView *)preferredFocusedView {
return self.useDefaultFocusBehavior ? [super preferredFocusedView] : self.selectedViewController.preferredFocusedView;
}
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
[super didUpdateFocusInContext:context withAnimationCoordinator:coordinator];
self.useDefaultFocusBehavior = YES;
}
@end
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.tabBarController.tabBar.hidden = YES; // or do it in storyboard
}
如果您使用故事板进行初始UI设置,请不要忘记将自定义类TVTabBarController
设置为您的标签栏控制器。
继承自UITabBarController
的提议方法对我没有用,因为实际上-preferredFocusedView
在启动时被调用了两次,所以我必须添加一个计数器来返回self.selectedViewController.preferredFocusedView
前2个电话。但这是一个非常糟糕的解决方案,并且不能保证它在未来不会中断。
所以我找到了一个更好的解决方案:在第一次通话时强制重点更新appdelegate' -applicationDidBecomeActive:
。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.tabBarController.tabBar.hidden = YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
static BOOL forceFocusToFirstTab = YES;
if (forceFocusToFirstTab) {
forceFocusToFirstTab = NO;
[self.tabBarController.selectedViewController updateFocusIfNeeded];
}
}
答案 1 :(得分:3)
上述方法大部分都有效但不允许您选择带有click的标签栏项,因为它返回tabBar时应该返回selectedItem。这是一个改进版本,通过在正常情况下返回[super preferredViewController]而不是tabBar来解决这个问题。此版本还会在启动时隐藏带有alpha的标签栏,以便它不会闪烁。可能有更优雅的方法来隐藏。
@interface MWTabBarController ()
@property (nonatomic, assign) BOOL firstTime;
@end
@implementation MWTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
self.firstTime = YES;
self.tabBar.alpha = 0;
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(unAlphaTabBar) userInfo:nil repeats:NO];
}
- (void) unAlphaTabBar
{
self.tabBar.alpha = 1;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (UIView *)preferredFocusedView {
if (self.firstTime) {
self.firstTime = NO;
return self.selectedViewController.preferredFocusedView;
}
else {
return [super preferredFocusedView];
}
}
答案 2 :(得分:2)
我找到了解决方案,所以如果有人感兴趣,你只需要继承UITabBarController
并覆盖preferredFocusedView
:
@interface ZTWTabBarController ()
@property (nonatomic, assign) BOOL firstTime;
@end
@implementation ZTWTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
self.firstTime = YES;
}
- (UIView *)preferredFocusedView {
if (self.firstTime) {
self.firstTime = NO;
return self.selectedViewController.preferredFocusedView;
}
else {
return [super preferredFocusedView];
}
}
@end
答案 3 :(得分:0)
这是最简单的&我认为最干净的解决方案:
override var preferredFocusedView: UIView? {
if tabBar.hidden {
return selectedViewController?.preferredFocusedView
}
return super.preferredFocusedView
}
答案 4 :(得分:0)
我能够使用isHidden
的{{1}}属性非常简单地实现此效果。
UITabBar
当用户向上滚动以显示标签栏时,override func viewDidLoad() {
super.viewDidLoad()
self.tabBar.isHidden = true
}
将自动取消隐藏。
答案 5 :(得分:0)
由于tvOS中不推荐使用preferredFocusedView
,因此您应该覆盖preferredFocusEnvironments
属性
Swift 4.0
override var preferredFocusEnvironments: [UIFocusEnvironment] {
if firsTime, let enviroments = selectedViewController?.preferredFocusEnvironments {
firsTime = false
return enviroments
}
return super.preferredFocusEnvironments
}