8 Replies
      Latest reply: Oct 6, 2015 4:07 PM by gfiumara RSS
      gfiumara Level 1 Level 1 (0 points)

        I have a UICollectionView of custom UICollectionViewCell subclasses, each with a UILabel and a UIButton. I want to make use of the great default focus behavior of the UIButton (since UICollectionViewCells don't have any default focus behavior), so I override the preferredFocusedView property of the UICollectionViewCell subclass to return the UIButton:

         

        @IBOutlet weak var button:UIButton!
        @IBOutlet weak var textLabel:UILabel!
        
        override var preferredFocusedView:UIView?
        {
             get {
                  return self.button
             }
        }
        
        override func canBecomeFocused() -> Bool
        {
             return true
        }
        

         

        When I do this, I'm unable to move the selection to the next UICollectionViewCell. The context object of collectionView(_:didUpdateFocusInContext:withAnimationCoordinator:) reports that the previous and next NSIndexPaths are always (0,0).

         

        If I instead return self or self.textLabel from preferredFocusView and do custom focus appearance changes (like changing the backgroundColor of the UICollectionViewCell), I'm able to move focus around the UICollectionView without problem. collectionView(_:canFocusItemAtIndexPath:) has not been overridden. Is there some default behavior of focus in the UIButton that I'm overlooking?

        • Re: Cannot move focus off of UIButton in UICollectionViewCell
          mwhuss Apple Staff Apple Staff (625 points)

          This is because when you're trying to focus the next cell it's going Button A -> Cell A -> Button A.

           

          No need to return a preferred focus view for the cell, the focus engine will automatically find the focusable buttons.

            • Re: Cannot move focus off of UIButton in UICollectionViewCell
              gfiumara Level 1 Level 1 (0 points)

              If preferredFocusedView is not overridden to return the UIButton, the focus moves around the UICollectionView as expected, but the UIButton in the UICollectionViewCell does not receive focus (does not get the white background with shadow), as evidenced by firings of collectionView(_:didUpdateFocusInContext:withAnimationCoordinator:). The focused property of the UIButton when moving through the UICollectionView (from nextFocusedIndexPath) in that delegate method remains false.

                • Re: Cannot move focus off of UIButton in UICollectionViewCell
                  mwhuss Apple Staff Apple Staff (625 points)

                  Remove the -canBecomeFocused method from your collection view cell and then they won't even be considered for focus.

                    • Re: Cannot move focus off of UIButton in UICollectionViewCell
                      gfiumara Level 1 Level 1 (0 points)

                      The reason for overriding canBecomeFocused is because the docs say that the default value is false. Regardless, removing the overridden method doesn't change the behavior I'm seeing.

                       

                      Here's a minimum working example. Reproduce yourself by (project posted separately to avoid moderation):

                       

                      1. New Single View project (Obj-C this time).
                      2. Change ViewController to a UICollectionViewController.
                      3. Swap out Main.storyboard's ViewController for a UICollectionViewController, changing class to ViewController.
                      4. Add a new UICollectionViewController subclass.
                      5. Populate a single UIButton in the prototype cell in the storyboard, changing the class (to that from step 4) and reuse ID, and adding an outlet to the subclass created in step 4.
                      6. Populate required UICollectionViewDataSource methods in ViewController (numberOfItems..., and cellForItem...).
                      7. Populate collectionView:didUpdateFocus... to observe focus changes.
                      8. Run.

                       

                      Without overriding preferredFocusView in TestCollectionViewCell, you can move around the UICollectionView fine, but the UIButton (the only view in the cell) never gets focus. If you return the button from preferredFocusedView, the button gets focus, but only in (0,0).

                • Re: Cannot move focus off of UIButton in UICollectionViewCell
                  mbwksr234 Level 1 Level 1 (10 points)

                  try adding

                   

                  
                    override func collectionView(collectionView: UICollectionView, canFocusItemAtIndexPath indexPath: NSIndexPath) -> Bool {
                      return false
                    }
                  

                   

                  in addition to not overridding preferredFocusedView

                    • Re: Cannot move focus off of UIButton in UICollectionViewCell
                      gfiumara Level 1 Level 1 (0 points)

                      This works! This also makes no sense on immediate inspection: the cell cannot obtain focus, but one of its child views can? This lead me to discover something else. UICollectionView has a property, remembersLastFocusedIndexPath, that I set to true. If this is false, I do not need to implement canFocusItemAtIndexPath. Reading the documentation a little more thoroughly, I think I see what may have been happening. A reading of the documentation for this property along with mwhuss's initial reply may reveal that this isn't a bug, but perhaps really strange default behavior (in my opinion).