SWIFT: Force focus engine to go to button when quitting collection in TVOS

1.1k views Asked by At

I have implemented programmatically this:

  1. List of tableView cells.
  2. Each tableViewCell contains a collectionView and below it a Button.

enter image description here

What's happening now:

  1. Focus engine is on a collection View
  2. User scrolls down
  3. Focus engine goes to next collection view unless I'm on the last item of the focused collection view, then it goes to VoirTout button.

What I want is:

  1. Focus engine is on a collection View
  2. User scrolls down
  3. Focus engine goes to Voir Tout Button

I have seen a couple of answers that make use of preferredFocusEnvironments like this:

 // Trying to force focus on button
    var voirToutButton:  CustomButton? = CustomButton(color: .red, titleString: "");
    override var preferredFocusEnvironments : [UIFocusEnvironment] {
        return [voirToutButton!]
    }

And then calling these inside viewDidLoad:

 // TRYING TO FORCE FOCUS ON VOIR TOUT BUTTON
setNeedsFocusUpdate()
updateFocusIfNeeded()

But, in my case that had no effect.

1

There are 1 answers

0
AG_HIHI On

I solved it like this. I'm not sure this is the most optimal way but it works:

class TableViewCell: UITableViewCell {

    var voirToutButton:  CustomButton? = CustomButton(color: .red, titleString: "");
    var shouldRefocusToVoirToutButton:Bool = false
    override var preferredFocusEnvironments : [UIFocusEnvironment] {
            return [voirToutButton!]
    }
    override func shouldUpdateFocus(in context: UIFocusUpdateContext) -> Bool {
        if (self.shouldRefocusToVoirToutButton){
            // Resetting this to false in order to avoid the focus getting stuck on voirToutButton
            self.shouldRefocusToVoirToutButton = false
                    self.setNeedsFocusUpdate()
                   self.updateFocusIfNeeded()
        }
        return true
        
    }
}

extension TableViewCell: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, shouldUpdateFocusIn context: UICollectionViewFocusUpdateContext) -> Bool {
       
        if let previouslyFocusedItemParent =  context.previouslyFocusedItem?.parentFocusEnvironment as? UICollectionView, let nextFocusedItemParent = context.nextFocusedItem?.parentFocusEnvironment as? UICollectionView  {
          
 let isPreviousFocusInCurrentCollectionView = previouslyFocusedItemParent == self.moviesCollectionView
        let isNextFocusInCurrentCollectionView = nextFocusedItemParent == self.moviesCollectionView
        let isFocusLeavingCollectionView = !(isPreviousFocusInCurrentCollectionView == isNextFocusInCurrentCollectionView)
        let isFocusMovingDown:Bool =  !(context.focusHeading == .up)
        if (isFocusLeavingCollectionView && isFocusMovingDown) {
            self.shouldRefocusToVoirToutButton = true
        }
        return true
        }
            // I remove this else it says that I need to return a bool (!(
        else {
            print("If I remove this else it says that I need to return a bool (!(")
            return true
        }
    }
    
}