2015-12-06 6 views
7

Ich verwende einen Standard UICollectionView mit Abschnitten. Meine Zellen sind wie ein Gitter ausgelegt. Die nächste Zelle in einer ausgewählten Richtung wird korrekt fokussiert, wenn der Benutzer den Fokus mit der Apple TV-Fernbedienung bewegt. Wenn es jedoch eine "Lücke" im Raster gibt, springt die Standard-Fokus-Engine über Abschnitte. Dies dient dazu, eine Zelle zu fokussieren, die mehrere Abschnitte entfernt sein kann, sich jedoch in derselben Spalte befindet.Benutzerdefinierte Fokus-Motor-Verhalten für UICollectionView

Einfaches Beispiel: Es gibt 3 Abschnitte. Der erste Abschnitt hat 3 Zellen. Der zweite hat 2 Zellen und der letzte hat wieder 3 Zellen. Siehe folgendes Bild:

enter image description here

Wenn die grüne Zelle konzentriert und berührt der Benutzer die Abwärtsrichtung, wird die gelbe Zelle fokussiert und Abschnitt zwei wird durch den Fokus Motor übersprungen.

Ich möchte es zwingen, dass keine Abschnitte übersprungen werden können. Anstatt die gelbe Zelle zu fokussieren, möchte ich die blaue Zelle fokussieren.

Ich habe gelernt, dass die Apple TV Focus-Engine intern wie ein Grid-System funktioniert und dass das beschriebene Verhalten das Standardverhalten ist. Um andere Bewegungen (z. B. diagonal) zuzulassen, müssen wir der Fokus-Engine helfen, indem wir unsichtbare UIFocusGuide s platzieren, die die Fokus-Engine zu einer preferredFocusedView umleiten können.

In der folgenden Abbildung befindet sich ein unsichtbarer roter Fokus-Guide, der in den leeren Bereich eines UICollectionView-Bereichs platziert wird, der den Down-Fokus auf die gewünschte blaue Zelle umlenkt. Ich denke, das wäre die perfekte Lösung in der Theorie.

enter image description here

Aber wie würde ich hinzufügen UIFocusGuide s auf alle leeren Räume von UICollectionView Abschnitte? Ich habe mehrere Dinge ausprobiert, aber nichts hat funktioniert. Vielleicht fügen Sie es als eine Dekorationsansicht hinzu, aber das scheint falsch zu sein. Oder als zusätzliche Zellen, aber das bricht die Datenschicht und die Constraints-Anker funktionieren nicht.

Hat jemand eine Idee, wie man UIFocusGuide s zu einem UICollectionView hinzufügt?

+0

Das gleiche Problem gefunden werden. Haben Sie versucht, collectionView zu überschreiben: canFocusItemAtIndexPath und false an gelbe Zelle zurückgeben? –

+0

Nein, habe ich nicht. Aber ich denke, das könnte ein wenig Durcheinander verursachen, denn die Zellen sollten fokussierbar sein. Ich bevorzuge immer noch die 'UIFocusGuide' Technik. Aber ich weiß immer noch nicht, wie ich es erreichen kann. Ich fragte auch in den Apple-Foren: https://forums.developer.apple.com/message/93020 Bitte informieren Sie mich, wenn Sie eine Lösung gefunden haben. –

Antwort

0

Eine Lösung ist die Unterklasse UICollectionViewFlowLayout mit einem Layout, das zusätzliche Ansichten mit UIFocusGuide s oben für alle leeren Bereiche hinzufügt.

Grundsätzlich ist die individuelle Flow Layout berechnet das benötigte Layout in der prepareLayout wie diese Attribute:

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

und kehrt dann die benötigten Layouts in der layoutAttributesForSupplementaryViewOfKind: Methode wie folgt:

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

Jetzt ist Ihre Ergänzungs Ansichten brauchen nur eine UIFocusGuide die gleiche Größe wie die ergänzende Ansicht selbst. Das ist es.

Eine vollständige Umsetzung des beschriebenen Verfahrens kann für mich here on gitHub

0

Zwei Möglichkeiten, um Ihr Ziel zu erreichen. Zumindest was ich versucht habe und es funktioniert hat. =). Es könnte auch andere Wege geben.

1:

Der einfachste Weg, um Ihr Ziel zu erreichen, ist mit Zellen vertikale Sammlung Ansicht hinzufügen, die horizontale Sammlung Ansicht enthält. Jede horizontale Sammlung ist Ihre Sektion.

Stellen Sie sicher, dass Sie hinzugefügt, um den folgenden Code in die vertikale Sammlung Ansicht:

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

2:

Wenn Sie UIFocusGuide verwenden ich ein guter Ort denken Fokus Führer hinzufügen Abschnittskopf ist. Stellen Sie sicher, dass Ihr Fokusführer in der Abschnittsüberschrift ist und preferredFocusedView als Wechsel zu jedem Abschnitt aktualisiert. In meinem Fall weise ich die erste Zelle jedes Abschnitts zu, wenn ich den Abschnitt verlasse.

Verwandte Themen