2015-12-06 14 views
7

Uso uno standard UICollectionView con sezioni. Le mie cellule sono disposte come una griglia. La cella successiva in una direzione prescelta viene messa a fuoco correttamente se l'utente sposta l'attenzione sul telecomando Apple TV. Ma se c'è un "buco" nella griglia, il motore di messa a fuoco predefinito salta sopra le sezioni. Lo fa per mettere a fuoco una cella che potrebbe essere di diverse sezioni ma si trova nella stessa colonna.Comportamento del motore con messa a fuoco personalizzata per UICollectionView

Semplice esempio: Ci sono 3 sezioni. La prima sezione ha 3 celle. Il secondo ha 2 celle e l'ultimo ha ancora 3 celle. Vedere la seguente immagine:

enter image description here

Se la cella verde è concentrata e l'utente tocca la direzione verso il basso, la cella gialla viene concentrata e la sezione due viene saltata dal motore di messa a fuoco.

Vorrei forzare che nessuna sezione possa essere saltata. Quindi, invece di focalizzare la cella gialla, vorrei mettere a fuoco la cella blu.

Ho appreso che il motore di Apple TV Focus funziona internamente come un sistema a griglia e che il comportamento descritto è quello predefinito. Per consentire altri movimenti (ad es. In diagonale), è necessario aiutare il motore di messa a fuoco immettendo gli UIFocusGuide invisibili che possono reindirizzare il motore di messa a fuoco su un preferredFocusedView.

Quindi nell'immagine seguente c'è una guida di messa a fuoco rossa invisibile posizionata nello spazio vuoto di una sezione UICollectionView che reindirizza il fuoco verso il basso alla cella blu desiderata. Penso che sarebbe la soluzione perfetta, in theorie.

enter image description here

Ma come potrei aggiungere UIFocusGuide s per tutti gli spazi vuoti di UICollectionView sezioni? Ho provato diverse cose ma non ha funzionato. Forse aggiungilo come Vista Decoratore ma sembra sbagliato. O come celle aggiuntive, ma che interrompe il livello dati e gli ancoraggi vincoli non funzionano.

Qualcuno ha un'idea su come aggiungere UIFocusGuide s a UICollectionView?

+0

Stesso problema per me. Hai provato a sovrascrivere collectionView: canFocusItemAtIndexPath e restituisce falso alla cella gialla? –

+0

No, non ho. Ma immagino che potrebbe creare un po 'di confusione, perché le celle dovrebbero essere focalizzabili. Preferisco ancora la tecnica 'UIFocusGuide'. Ma ancora non so come raggiungerlo. Ho chiesto anche nei forum di apple: https://forums.developer.apple.com/it/message/93020 Per favore informami se hai trovato una soluzione. –

risposta

0

Una soluzione è la sottoclasse UICollectionViewFlowLayout con un layout che aggiunge Visualizzazioni supplementari con UIFocusGuide s in cima per tutte le aree vuote.

Fondamentalmente il layout di flusso personalizzato calcola attribuisce il layout necessario nel prepareLayout come questo:

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]; 
      } 
     } 
    } 
} 

e quindi restituisce i layout necessari nel metodo layoutAttributesForSupplementaryViewOfKind: in questo modo:

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

Ora il vostro supplementare Le viste hanno solo bisogno di un UIFocusGuide delle stesse dimensioni della vista supplementare stessa. Questo è tutto.

Una piena applicazione del metodo descritto può essere trovato here on gitHub

0

Due modi per raggiungere il tuo obiettivo. Almeno quello che ho provato e fatto funzionare. =). Potrebbero esserci anche altri modi.

1:

Il modo più semplice per raggiungere il tuo obiettivo è aggiungere vista collezione verticale con celle contenente vista collezione orizzontale. Ogni collezione orizzontale è la tua sezione.

assicurarsi di aggiungere il seguente codice alla vista collezione verticale:

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

2:

Se si desidera utilizzare UIFocusGuide Penso che un buon posto per aggiungere guida fuoco è un'intestazione di sezione. Accertati di avere la guida per la messa a fuoco nell'intestazione della sezione e aggiorna PreferitiFocusedView come interruttore su ciascuna sezione. Nel mio caso assegno la prima cella di ogni sezione quando esco dalla sezione.

Problemi correlati