tvOS UITabBarController开始没有重点

时间:2015-10-18 13:24:02

标签: focus uitabbarcontroller uitabbar tvos

我有一个以UITabBarController开头的简单tvOS应用程序,我希望主视图在应用程序启动时具有焦点,而不是标签栏。

我尝试过玩self.tabBarController.tabBar.userInteractionEnabled暂时删除焦点,但徒劳无功。 (除此之外我不喜欢那种解决方法)

有任何线索吗?

提前致谢。

6 个答案:

答案 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
    }