【问题标题】:UIScrollView disable scrolling while rotating on iPhone/iPadUIScrollView 在 iPhone/iPad 上旋转时禁用滚动
【发布时间】:2011-05-06 15:46:02
【问题描述】:

我正在使用 UIScrollView 和其中的图像作为每页分页一个图像。我在旋转 iPhone 时遇到问题

当我旋转 iPhone 时,scrollViewDidScroll(滚动视图委托方法)正在调用。 因此,我的分页受到干扰,页码发生变化。

解决办法是什么?

【问题讨论】:

  • 遇到同样的问题...,您解决问题了吗?
  • @Maciulis..我当时到底做了什么......但我检查了代码..我没有使用方法 scrollViewDidScroll 并使用 scrollViewDidEndDecelerating.. 并使用全局变量当前页码..希望这会对您有所帮助或告诉我您想要什么

标签: iphone cocoa-touch uikit uiscrollview


【解决方案1】:

Raphaël's answer 是对问题的出色描述,并且是一个巧妙的修复。我遇到了完全相同的问题,最后修复了一个 scrollingLocked 标志,我在轮换开始之前设置为 YES(锁定),在轮换结束时设置为 NO(解锁)。可能比临时更改 contentSize 稍微简单一些:

- (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 */
}

【讨论】:

  • photoViewer 是什么组件? - 因为它不是滚动,也不是视图
  • @matheszabi,他正在使用 BOOL ivar 进行跟踪。或者,您可以只使用UIScrollViewscrollEnabled 内置属性。顺便说一句,由于某种原因,这仍然会在最后一张图片上触发scrollViewDidScroll
  • iOS 8 有类似的解决方案吗?
  • @Steven 我首先赞成你的评论,但最后这对我不起作用,因为 contentOffset 无论如何都在它之后发生了变化,正如你已经指出的那样......
【解决方案2】:

我在旋转分页的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];
}

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

【讨论】:

    【解决方案3】:

    Swift 4 解决方案:

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

    【讨论】:

      【解决方案4】:

      你可以在 Swift 上试试这个方法:

      override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
          super.viewWillTransition(to: size, with: coordinator)
          coordinator.animate(alongsideTransition: { _ in
            // Execute before rotation
          }) { _ in
            //Execute after rotation
          }
      }
      

      【讨论】:

        【解决方案5】:

        我的任务是允许滚动风景。该设计是为肖像设计的。我想出了一个想法,将 ScrollView 添加到组件中,或者在 Interface Builder 的“嵌入滚动视图”中。我预计它会起作用,但没有。我正在使用Xcode 4.4,iOS 5.1,(office 项目也需要支持 4.2),但问题是一样的。

        在 Stack Overflow 问题 iPhone SDK: UIScrollView does not scroll 中有一行解决了一个问题。

        其他尝试在 Stack Overflow 问题中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;
            }    
        }
        

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

        【讨论】:

          【解决方案6】:

          除了 Raphaël Mor 的回答。如果您从纵向切换到横向,则内容大小和页面结构将会停止。因此,为了保持当前页面结构,只需在宽度上添加额外的内容大小:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-08-17
            • 1970-01-01
            • 2016-01-23
            • 2017-09-09
            • 1970-01-01
            • 2012-06-03
            • 2013-05-11
            相关资源
            最近更新 更多