3 Stimmen

Probleme beim Drehen von UIScrollView mit Paging

Ich habe Probleme mit einem UIScrollView auf dem IPhone beim Umgang mit Rotation. Ich habe Apples PageControl Beispiel als Modell verwendet, aber bin die Scrollview selbst in einer Ansicht erstellen.

1) Die Bildlaufansicht funktioniert wie erwartet, wenn sie im Standard-Portrait geladen wird, und scrollt horizontal von links nach rechts

2) Beim Drehen von CW und Neuinitialisierung wird das Bild meist auf die Seite gedreht und dreht sich nun vertikal nach unten, anstatt wie gewünscht horizontal. Es scheint, dass sich die Breite/Höhe des Scrollview-Rahmens nicht ändert, sondern nur die Ausrichtung des Rahmens selbst.

3) Ich habe versucht, einige Orientierungserkennungslogik hinzufügen, um richtig Größe und Seite die Scrollview basierend auf Ausrichtung, die Art von gearbeitet hat, aber nur, wenn ich CCW zu Querformat drehen. Wenn ich gehen CW es beginnt auf der rechten Seite und scrollt nach links, und die Dinge nicht funktionieren.

Offensichtlich ist dies immer hackish, so gibt es eine richtige Art und Weise der Einrichtung meiner UIScrollview und reintializing es mit Rotationen, so dass es immer links nach rechts scrollt?

- (void)loadView {
    [self setupPage];
}

-(void) setupPage {
  // lazy init view controllers
  NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (unsigned i = 0; i = kNumberOfPages) return;

    // replace the placeholder if necessary
    MyViewController *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        controller = [[MyViewController alloc] initWithPageNumber:page];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    // add the controller's view to the scroll view
    if (nil == controller.view.superview) {
        CGRect frame = scrollView.frame;

        int x = 0;
        int y = 0;
        UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
        if(orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){
            x = 0;
            y = frame.size.height * page; 
        } else {
            x = frame.size.width * page;
            y = 0;
        }

        frame.origin.x = x;
        frame.origin.y = y;
        controller.view.frame = frame;
        [scrollView addSubview:controller.view];
    }
}

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    // We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
    // which a scroll event generated from the user hitting the page control triggers updates from
    // the delegate method. We use a boolean to disable the delegate logic when the page control is used.
    if (pageControlUsed) {
        // do nothing - the scroll was initiated from the page control, not the user dragging
        return;
    }

    // Switch the indicator when more than 50% of the previous/next page is visible
    CGFloat pageWidth = scrollView.frame.size.width;
    int offset = 0;
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    if(orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){
        pageWidth = scrollView.frame.size.height;
        offset = scrollView.contentOffset.y; 
    } else {
        pageWidth = scrollView.frame.size.width;
        offset = scrollView.contentOffset.x ;
    }

    //CGFloat pageWidth = scrollView.frame.size.width;
    int page = floor((offset - pageWidth / 2) / pageWidth) + 1;
    pageControl.currentPage = page;

    // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
    [self loadScrollViewWithPage:page - 1];
    [self loadScrollViewWithPage:page];
    [self loadScrollViewWithPage:page + 1];

    // A possible optimization would be to unload the views+controllers which are no longer visible
}

// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    pageControlUsed = NO;
}

// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlUsed = NO;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{
    [self setupPage];
}

2voto

MishieMoo Punkte 6479

Du änderst die contentSize deines scrollview nicht, so dass es beim Drehen nicht weiß, dass es breiter ist als es höher ist.

Außerdem hat jeder VC bereits eine interfaceOrientation-Eigenschaft, und es gibt Funktionen zur Erkennung der Ausrichtung: UIInterfaceOrientationIsPortrait(self.interfaceOrientation) und UIInterfaceOrientationIsLandscape(self.interfaceOrientation).

Schließlich, nur eine visuelle Sache, mit willRotateToInterfaceOrientation:duration ist ein bisschen netter auf die Augen, und der Benutzer nie eine Änderung wahrnehmen, wie es fast gleichzeitig mit der Drehung geschieht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X