Wie kann man das scrollen zu einer sichtbaren Zelle in der UICollectionView mit benutzerdefinierten layout?

Arbeite ich an eigenen Wert-picker inspiriert von UIPickerView. Es sieht so aus:
Wie kann man das scrollen zu einer sichtbaren Zelle in der UICollectionView mit benutzerdefinierten layout?

Wie Sie sehen können, eines der wichtigsten Merkmale dieser Farbauswahl ist die zentrale Zelle der sollte breiter sein als andere, um die Nachbarn sichtbar neben der zentralen frame. Wenn Sie scrollen Sie die Farbauswahl mit einem pan-Geste, es soll sich dynamisch verändern, zentralen Wert und passen Sie die Zellen nach der Logik oben. Und es funktioniert einfach perfekt:
Wie kann man das scrollen zu einer sichtbaren Zelle in der UICollectionView mit benutzerdefinierten layout?

Das problem ist in der tap-Geste. Wenn der Benutzer wählen Sie ein beliebiges Element auf dem picker durch die Durchführung Tippen Sie auf auf es dem picker versucht, scrollen Sie zu diesem Element. Aber da das offset geändert wurde, indem Sie das benutzerdefinierte layout UIScrollView Schriftrollen an der falschen Stelle. Und es sieht so aus, dass:
Wie kann man das scrollen zu einer sichtbaren Zelle in der UICollectionView mit benutzerdefinierten layout?

Wenn ich versuche zu scrollen, um den offscreen-Zelle alle Sachen funktioniert einwandfrei - das Handy war nicht betroffen durch die Anordnung und die Koordinaten korrekt sind. Die Frage erhebt sich nur auf sichtbare Zellen. Ich bin völlig außer irgendwelche Ideen wie zu korrigieren. Sie könnte das ganze Projekt hier: Karussell Sammlung Anzeigen-Test-Projekt

Finden Sie einige wichtige code unten.

//CarouselLayout.m

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;

    CGRect center = CGRectMake(CGRectGetMidX(visibleRect) - 1.0, 0.0, 2.0, CGRectGetHeight(visibleRect));
    CGFloat coreWidth = CGRectGetWidth(self.centralFrame) / 3.0;

    for (UICollectionViewLayoutAttributes *attributes in array) {
        if (CGRectIntersectsRect(attributes.frame, rect)){
            CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
            CGFloat offset = 0.0;
            CGRect coreFrame = CGRectMake(attributes.center.x - (coreWidth / 2.0), 0.0, coreWidth, CGRectGetHeight(self.centralFrame));
            if (CGRectIntersectsRect(center, coreFrame)) {
                if (attributes.indexPath.item % 2 == 0) {
                    self.centralItemOffset = (CGRectGetWidth(self.centralFrame) - CGRectGetWidth(attributes.frame) - 4.0) / 2.0;
                    if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:didChangeCentralItem:)]) {
                        [(id <CarouselLayoutDelegate>)self.collectionView.delegate collectionView:self.collectionView layout:self didChangeCentralItem:attributes.indexPath];
                    }
                }
            }
            offset = (distance > 0) ? -self.centralItemOffset : self.centralItemOffset;
            attributes.center = CGPointMake(attributes.center.x + offset, attributes.center.y);
        }
    }
    return array;
}

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    CGFloat offsetAdjustment = MAXFLOAT;
    CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0);
    CGRect targetRectHorizontal = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);

    NSArray *array = [super layoutAttributesForElementsInRect:targetRectHorizontal];
    for (UICollectionViewLayoutAttributes *attributes in array) {
        if (attributes.indexPath.item % 2 == 1) {
            continue;
        }
        CGFloat itemHorizontalCenter = attributes.center.x;
        if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemHorizontalCenter - horizontalCenter;
        }
    }

    return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}

//ViewController.m

- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.item % 2 == 1) {
        return;
    }
    NSString *nextValue = [self valueAtIndexPath:indexPath];
    [self scrollToValue:nextValue animated:YES];
    self.currentValue = nextValue;
}

- (void)scrollToValue:(NSString *)value animated:(BOOL)animated {
    NSIndexPath *targetPath = nil;
    NSIndexPath *currentPath = nil;
    for (NSString *item in self.itemsArray) {
        if (!targetPath && [value isEqualToString:item]) {
            targetPath = [NSIndexPath indexPathForItem:([self.itemsArray indexOfObject:item] * 2) inSection:0];
        }
        if (!currentPath && [self.currentValue isEqualToString:item]) {
            currentPath = [NSIndexPath indexPathForItem:([self.itemsArray indexOfObject:item] * 2) inSection:0];
        }
        if (targetPath && currentPath) {
            break;
        }
    }
    if (targetPath && currentPath) {
        [self.itemsCollectionView scrollToItemAtIndexPath:targetPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:animated];
    }
}

Wenn es nicht reicht, bitte Fragen Sie nach zusätzlichen code in die Kommentare.

  • Ich denke das Problem bezieht sich auf die Verwendung eines UICollectionViewFlowLayout Unterklasse vs Ihre eigenen UICollectionViewLayout. Passen Sie die center in layout-Attribute aber nicht layoutAttributesForItemAtIndexPath als gut. Und ich Wette, die Größe des Inhalts der flow-layout gibt, die nicht wissen, über Ihre änderung, oder, wenn Sie es tut ist es zu spät. Versuchen Sie, Rollen Ihre eigenen layout.
  • Ich bin mir ziemlich sicher, dass Ihr Ansatz ist viel mehr richtig, als mir. Aber wenn ich versucht habe zu implementieren, die mein eigenes layout, das ich mit den gleichen Problemen und auch ein paar andere. Da die richtige Antwort war da unten habe ich mich dazu entschieden meine pause Forschung an dieser Stelle, da ich keine Zeit mehr habe für dieses Steuerelement.
  • können Sie senden Sie mir Ihre benutzerdefinieren layout gleiche Problem auf meinem layout
  • es ist schon fast drei Jahre her, dass post und ich bin mir nicht sicher, ob dieser code noch kompiliert werden. Aber wie auch immer Sie finden konnten, indem Sie den link in meinem post. Aber du solltest besser lernen, wie Sie Ihre eigenen CollectionLayout und nicht hacks benutzen, beschrieben in meinem post.
Schreibe einen Kommentar