使用分页旋转UIScrollView的问题

时间:2010-08-29 17:21:22

标签: iphone objective-c uikit rotation

在处理旋转时,我在使用iPhone上的UIScrollView时遇到问题。我使用Apple的PageControl示例作为模型,但我自己在View中创建了scrollview。

1)当在默认纵向中加载时,滚动视图按预期工作,从左到右水平滚动

2)开箱即用时,旋转CW并重新初始化时,大多数侧面旋转,现在垂直向下旋转而不是所需的水平静止。似乎scrollview框架的宽度/高度不会改变,只是它自身的方向。

3)我尝试添加一些方向检测逻辑,以根据具有工作方向的方向正确调整和分页滚动视图,但前提是我将CCW旋转到横向。如果我去CW,它会从右侧开始向左滚动,但事情不起作用。

显然这是个hackish,所以有没有一种正确的方法来设置我的UIScrollview并使用旋转重新定位它,所以它总是从左向右滚动?


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

1 个答案:

答案 0 :(得分:2)

你没有改变你的滚动视图的contentSize,所以当它旋转时,它不知道它比它更高更宽。

此外,作为快捷方式,每个VC都已设置interfaceOrientation属性,并且内置了检测方向的函数:UIInterfaceOrientationIsPortrait(self.interfaceOrientation)和UIInterfaceOrientationIsLandscape(self.interfaceOrientation)。

最后,只是一个视觉事物,使用willRotateToInterfaceOrientation:持续时间在眼睛上更好一些,并且用户永远不会感觉到变化,因为它几乎与旋转同时发生。