2015-12-06 3 views
7

私はセクション付き標準UICollectionViewを使用します。私の細胞はグリッドのように配置されています。ユーザーがApple TVリモコンを使用してフォーカスを移動すると、選択した方向の次のセルが正しくフォーカスされます。しかし、グリッドに「ギャップ」がある場合、デフォルトフォーカスエンジンはセクションを飛び越えます。それは、いくつかのセクションになる可能性があるが同じ列にあるセルに焦点を当てるためにこれを行います。UICollectionViewのカスタムフォーカスエンジンの動作

簡易例: 3つのセクションがあります。最初のセクションには3つのセルがあります。 2番目のセルは2つのセルを持ち、最後のセルは3つのセルを持ちます。緑色セルがフォーカスされ、ユーザが下方向に触れ、黄色セルがフォーカス取得し、セクション2、フォーカスエンジンによってスキップされた場合

enter image description here

次の画像を参照してください。

セクションを飛び越さないように強制したいと思います。だから黄色のセルに焦点を当てるのではなく、青いセルに焦点を合わせたいと思います。

Apple TV Focusエンジンは、内部的にグリッドシステムのように動作し、記述された動作がデフォルトの動作であることを知りました。他の動き(例えば、対角線)を可能にするために、フォーカスエンジンをpreferredFocusedViewにリダイレクトすることができる不可視のUIFocusGuideを配置することによって、フォーカスエンジンを助ける必要があります。

次の画像では、UICollectionViewセクションの空きスペースに1つの目に見えない赤のフォーカスガイドが配置されています。このガイドは、下向きのフォーカスを目的の青色のセルにリダイレクトします。私はそれが理論の中で完璧な解決策になると思う。

enter image description here

しかし、どのように、私はUICollectionViewセクションのすべての空のスペースにUIFocusGuide秒を追加しますか?私はいくつかのことを試みたが、何も働かなかった。たぶんそれをデコレータビューとして追加するのは間違っているようです。または、追加のセルとして、しかしそれはデータレイヤーを壊し、制約アンカーは機能しません。

UICollectionViewUIFocusGuideを追加する方法はありますか?

+0

同じ問題を見つけることができます。 collectionView:canFocusItemAtIndexPathをオーバーライドして、黄色のセルにfalseを返しましたか? –

+0

いいえ私はしていません。しかし、私は少し混乱を引き起こす可能性がある、細胞が焦点を当てる必要があります原因だと思います。私はまだ 'UIFocusGuide'技術を好む。しかし、それを達成する方法はまだ分かりません。私はアップルのフォーラムでも尋ねました:https://forums.developer.apple.com/message/93020 あなたが解決策を見つけたらお知らせください。 –

答えて

0

UICollectionViewFlowLayoutのサブクラス化は、すべての空き領域の上に補足ビューをUIFocusGuideで追加するレイアウトで行います。

基本的にカスタムフローレイアウトが必要なレイアウトは、このようprepareLayoutの属性計算:

self.supplementaryViewAttributeList = [NSMutableArray array]; 
if(self.collectionView != nil) { 
    // calculate layout values 
    CGFloat contentWidth = self.collectionViewContentSize.width - self.sectionInset.left - self.sectionInset.right; 
    CGFloat cellSizeWithSpacing = self.itemSize.width + self.minimumInteritemSpacing; 
    NSInteger numberOfItemsPerLine = floor(contentWidth/cellSizeWithSpacing); 
    CGFloat realInterItemSpacing = (contentWidth - (numberOfItemsPerLine * self.itemSize.width))/(numberOfItemsPerLine - 1); 

    // add supplementary attributes 
    for (NSInteger numberOfSection = 0; numberOfSection < self.collectionView.numberOfSections; numberOfSection++) { 
     NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:numberOfSection]; 
     NSInteger numberOfSupplementaryViews = numberOfItemsPerLine - (numberOfItems % numberOfItemsPerLine); 

     if (numberOfSupplementaryViews > 0 && numberOfSupplementaryViews < 6) { 
      NSIndexPath *indexPathOfLastCellOfSection = [NSIndexPath indexPathForItem:(numberOfItems - 1) inSection:numberOfSection]; 
      UICollectionViewLayoutAttributes *layoutAttributesOfLastCellOfSection = [self layoutAttributesForItemAtIndexPath:indexPathOfLastCellOfSection]; 

      for (NSInteger numberOfSupplementor = 0; numberOfSupplementor < numberOfSupplementaryViews; numberOfSupplementor++) { 
       NSIndexPath *indexPathOfSupplementor = [NSIndexPath indexPathForItem:(numberOfItems + numberOfSupplementor) inSection:numberOfSection]; 
       UICollectionViewLayoutAttributes *supplementaryLayoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:ARNCollectionElementKindFocusGuide withIndexPath:indexPathOfSupplementor]; 
       supplementaryLayoutAttributes.frame = CGRectMake(layoutAttributesOfLastCellOfSection.frame.origin.x + ((numberOfSupplementor + 1) * (self.itemSize.width + realInterItemSpacing)), layoutAttributesOfLastCellOfSection.frame.origin.y, self.itemSize.width, self.itemSize.height); 
       supplementaryLayoutAttributes.zIndex = -1; 

       [self.supplementaryViewAttributeList addObject:supplementaryLayoutAttributes]; 
      } 
     } 
    } 
} 

してから、このようなlayoutAttributesForSupplementaryViewOfKind:方法で必要なレイアウトを返す:あなたの補足今

if ([elementKind isEqualToString:ARNCollectionElementKindFocusGuide]) { 
    for (UICollectionViewLayoutAttributes *supplementaryLayoutAttributes in self.supplementaryViewAttributeList) { 
     if ([indexPath isEqual:supplementaryLayoutAttributes.indexPath]) { 
      layoutAttributes = supplementaryLayoutAttributes; 
     } 
    } 
} 

ビューでは、補助ビュー自体と同じサイズのUIFocusGuideが必要です。それでおしまい。

記載されている方法の完全な実装では、私のためhere on gitHub

0

あなたの目標を達成するための2つの方法。少なくとも私が試したもので、それを機能させるものでした。 =)。他の方法もあるかもしれません。

1:

あなたの目標を達成するための最も簡単な方法は、水平コレクションビューが含まれている細胞を用いた縦型コレクションビューを追加することです。各水平コレクションはあなたのセクションです。

あなたは垂直コレクションビューに次のコードを追加していることを確認してください:

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

2:

あなたがUIFocusGuideを使用したい場合は、私はフォーカスガイドを追加するには良い場所は、セクションヘッダだと思います。セクションヘッダーでフォーカスガイドを確認し、各セクションにスイッチとしてpreferredFocusedViewを更新してください。私の場合は、セクションを出るときに各セクションの最初のセルを割り当てます。

関連する問題