UICollectionViewCell to UIButton Focus in tvOS

最后都变了- 提交于 2019-11-28 23:35:30

You should use a UIFocusGuide that encompasses the UIButton you want to focus. Make the UIFocusGuide as wide as the collectionView and tall enough to cover the button. Make the preferredFocusView the button.

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

  [self.view addConstraints:@[
    [topButtonFocusGuide.topAnchor constraintEqualToAnchor:myButton.topAnchor],
    [topButtonFocusGuide.bottomAnchor constraintEqualToAnchor:myCollectionView.topAnchor],
    [topButtonFocusGuide.leadingAnchor constraintEqualToAnchor:myCollectionView.leadingAnchor],
    [topButtonFocusGuide.widthAnchor constraintEqualToAnchor:myCollectionView.widthAnchor],
  ]];

Jess Bowers solution is almost there but Xcode says UIButtons doesn't have topAnchor property and the solution given by Jess doesn't work for me.

For me, the solution was to create a huge view with the same width as the UICollectionView on top of it. See picture.

The code will be this:

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

  [self.view addConstraints:@[
    [topButtonFocusGuide.topAnchor constraintEqualToAnchor:transparentView.topAnchor],
    [topButtonFocusGuide.bottomAnchor constraintEqualToAnchor:transparentView.bottomAnchor],
    [topButtonFocusGuide.leadingAnchor constraintEqualToAnchor:transparentView.leadingAnchor],
    [topButtonFocusGuide.widthAnchor constraintEqualToAnchor:transparentView.widthAnchor],
  ]];

Use :

override weak var preferredFocusedView: UIView? { get { return segmentedControl } }

One of the issues I was facing involved using a UINavigationController for the landing pages to push detail ViewControllers onto the stack when an item is selected.

I put a breakpoint inside the UIButton's canBecomeFocused override, and using this quick little extension asked the button why it is not focusable.

extension UIView {
    func whyNotFucusable () {
        print(self.perform(Selector(("_whyIsThisViewNotFocusable"))).takeUnretainedValue())
    }
}

I kept receiving the following error trying to debug....

ISSUE: This view may not be focusable because other views or focus guides are occluding it.

First of all I looked up in the dictionary what the heck occluding meant....

verb, formal, technical 
     - stop, close up, or obstruct (an opening, orifice, or passage).

The question now was what view is obstructing my UIButton???

I quickly unwrapped the UI in the visual debugger, and there was a clear view on top of my UIButtons. Inspecting the view I found out that Unlike iOS, where the nagivationBar has a default system background color, tvOS's implementation has a clear default color. I realized that I didn't hide the nav bar, and in return it was obstructing my buttons.

I did the following, and it fixed all my issues :)

navController.setNavigationBarHidden(true, animated: false)

Hope this helps!!!

Swift 3.0

Jess Bower's answer was huge help to me & saved a lot of time.

Here's what worked with Swift 3 & tvOS 10. One now has to use preferredFocusEnvironments. In ViewDidLoad()

        self.view.addLayoutGuide(focusGuide)
        self.focusGuide.topAnchor.constraint(equalTo: self.buttonAbove.topAnchor).isActive = true
        self.focusGuide.bottomAnchor.constraint(equalTo: self.CollectionView.topAnchor).isActive = true
        self.focusGuide.leadingAnchor.constraint(equalTo: self.CollectionView.leadingAnchor).isActive = true
        self.focusGuide.widthAnchor.constraint(equalTo: self.CollectionView.widthAnchor).isActive = true
        self.focusGuide.preferredFocusEnvironments = [self.buttonAbove]
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!