UIScrollView在iPhone / iPad上旋转时禁用滚动

问题描述 投票:19回答:5

我正在使用UIScrollView及其中的图像作为每页分页一个图像。旋转iPhone

时出现问题

当我旋转iPhone时,正在调用scrollViewDidScroll(滚动视图委托方法)。因此,我的寻呼被打乱了,页码也改变了。

解决方案是什么?

iphone cocoa-touch uikit uiscrollview
5个回答
24
投票

Raphaël's answer是对该问题的出色描述,而且是一种精巧的解决方案。我遇到了完全相同的问题,最终以scrollingLocked标志修复了问题,该标志在旋转开始之前设置为YES(锁定),在旋转结束时设置为NO(解锁)。也许比暂时更改contentSize的hacky少一些:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
                                duration:(NSTimeInterval)duration
{
    self.photoViewer.scrollingLocked = YES;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation
{
    self.photoViewer.scrollingLocked = NO;
}

- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
    if (self.scrollingLocked)
    {
        return;
    }
    /* do normal scrollViewDidScroll: stuff */
}

14
投票

旋转分页的UIScrollView时,发现了一个奇怪的未记录的行为。

当滚动视图位于最后一页并且用户更改了方向时,操作系统会将UIScrollView向后滚动几个像素以补偿高度和宽度之间的差异。

基本上我收到了以下任何页面的电话。

willRotateToInterfaceOrientation:duration
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:

最后一页:

willRotateToInterfaceOrientation:duration
scrollViewDidScroll:
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:

这也弄乱了我的页面。问题在于,在willRotate中,边界尚未由操作系统更新,在willAnimate中,您具有新的边界并且可以计算新的大小,但是为时已晚...

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    CGSize tempSize = [self.pagingScrollView contentSize];
    NSUInteger padding = abs(pagingScrollView.frame.size.width - pagingScrollView.frame.size.height);
    tempSize.width += padding;
    [self.pagingScrollView setContentSize:tempSize];
    [...]
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration{
    CGSize newSize = ... // Compute new content size based on new orientation
    [self.pagingScrollView setContentSize:newSize];
}

这只是一种解决方法,但是我在这个问题上花费了无数小时,找不到一个好的解决方案。


0
投票

我的任务是允许滚动景观。该设计是为肖像而设计的。我想出了一个向组件添加ScrollView的想法,或者在Interface Builder的“嵌入Scroll View中”。我期望它会起作用,但不会。我正在使用Xcode 4.4,iOS 5.1(办公项目也需要4.2的支持),但是问题是相同的。

在堆栈溢出问题iPhone SDK: UIScrollView does not scroll中,有一行可以解决问题。

[其他尝试在堆栈溢出问题iOS - UIScrollView is not working (it doesn't scroll at all - the image stays fixed)中,这与其他结合在一起帮助了我,所以这是我的可滚动景观代码:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation
{ 
    if( UIInterfaceOrientationIsPortrait( [[UIApplication sharedApplication] statusBarOrientation] ) ){
        scrollView.contentSize = portaitScrollSize;
    }
    else{//statusbar is Landscape
        scrollView.contentSize = landscapeScrollSize;
    }    
}

ScrollView绑定到Interface Builder中的iVar视图。 portaitScrollSizelandscapeScrollSize是私有变量。它们已初始化且不会更改。在my.h文件中:

IBOutlet UIScrollView *scrollView;

my.m文件中:

CGSize portaitScrollSize, landscapeScrollSize;

...

portaitScrollSize = CGSizeMake(320,440);
landscapeScrollSize = CGSizeMake(480,480);

我希望它可以帮助某人为肖像设计添加旋转+滚动功能。

不要忘记在顶部组件上使用肖像和风景:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return TRUE;
}

0
投票

除了拉斐尔·莫(RaphaëlMor)的回答。如果从纵向切换为横向,内容大小和页面结构将停止。因此,为了保持当前的页面结构,只需在宽度上添加额外的内容大小即可:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    [self.scrollView setContentSize:CGSizeMake(self.scrollView.contentSize.width + 400, self.scrollView.contentSize.height)];
}

并确保更改方向后再次设置contentsize和offset:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.scrollView setContentSize:CGSizeMake(self.scrollView.bounds.size.width *3, self.scrollView.bounds.size.height)];
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width * self.pageControl.currentPage, 0) animated:NO];

}

0
投票

Swift 4解决方案:

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        lui.l("apply previousTraitCollection: \(previousTraitCollection)")
        canScroll = true
    }

© www.soinside.com 2019 - 2024. All rights reserved.