滚动,缩放UIScrollView和界面方向旋转.如何使用自动调整大小和更多



这应该是一件很常见的事情,但是我还没能让它完全正确地工作。

我有矩形内容。它通常适合320x361:纵向模式-状态栏-广告-标签栏。

我已经把内容放到了UIScrollView中并启用了缩放。我还希望界面旋转工作。内容将始终是一个高矩形,但当缩放时,用户可能希望一次看到更大的宽度和更小的高度。

我需要在界面生成器和代码中做些什么来完成这项工作?如何在不同的视图上设置自动调整大小?我如何设置我的contentSize和contentInsets?

我已经尝试了很多不同的方法,没有一个是完全正确的。在我的各种解决方案中,我遇到的问题是,在进行了缩放、界面旋转和滚动的组合后,不再可能滚动到屏幕上的整个内容。在你看到内容的边缘之前,滚动视图会把你拉回来。

我现在做的方法大约有80%是正确的。也就是说,在10件应该做的事情中,它只做了8件。它做错的两件事是:

  1. 当在纵向模式下放大时,您可以滚动过内容的边缘,并看到黑色背景。这没什么好抱怨的。至少你可以看到所有的内容。在横向模式下,无论是否缩放,看到黑色背景超过边缘是正常的,因为内容没有足够的宽度来填充1:1缩放级别的屏幕(最小值)。

  2. 当它在运行iOS 3.0的测试设备上运行时,我仍然会得到内容卡在边缘,但它在运行4.x的我的设备上工作。——实际上这是上一个解。我的测试人员还没有尝试最新的解决方案。

这是我目前使用的解决方案。总而言之,我已经将滚动视图设置为任意方向所需的宽度和高度,因为我发现手动或自动调整它的大小会增加复杂性,而且很脆弱。

视图层次结构:

  • 视图
    • 滚动视图
      • scrollableArea

视图是320x411,并有所有的自动调整大小选项,所以符合屏幕形状

scrollView 480 x 361,从原点-80,0开始,只锁定顶部并禁用拉伸

scrollableArea 480 x 361,锁在左边和上面。由于scrollView禁用拉伸,其子视图的自动调整大小掩码无关紧要,但我还是告诉你。

内容是320x361,从原点80,0开始,并锁定到顶部

我将scrollView.contentSize设置为480x361。

shouldAutorotateToInterfaceOrientation支持所有方向,除了纵向倒立。

在didRotateFromInterfaceOrientation中,如果方向是横向的,我将底部内容插入值设置为160,如果不是重置为0。如果方向是纵向的,我将左右指示器的插入值分别设置为80,如果不是,则重置。

scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 2.0

viewForZoomingInScrollView返回scrollableArea

// in IB it would be all options activated
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scrollView.contentSize = content.frame.size; // or bounds, try both

你说的scrollableArea是什么意思?

你的minZoomScale被设置为1.0,这对肖像模式很好,但不适合风景。因为在横屏中你的高度比竖屏小,所以你需要设置一个小于1.0的值。对我来说,我使用这个实现,每次调用它,scrollView的框架确实改变了:

- (void)setMaxMinZoomScalesForCurrentBounds {
    CGSize boundsSize = self.bounds.size; // self is a UIScrollView here
    CGSize contentSize = content.bounds.size;
    CGFloat xScale = boundsSize.width / contentSize.width;
    CGFloat yScale = boundsSize.height / contentSize.height;
    CGFloat minScale = MIN(xScale, yScale);
    if (self.zoomScale < minScale) {
        [self setZoomScale:minScale animated:NO];
    }
    if (minScale<self.maximumZoomScale) self.minimumZoomScale = minScale;
    //[self setZoomScale:minScale animated:YES];
}
- (void)setFrame:(CGRect)rect { // again, this class is a UIScrollView
    [super setFrame:rect];
    [self setMaxMinZoomScalesForCurrentBounds];
}

我不认为我从你的帖子中理解了整个问题,但这里有一个我理解的答案。

据我所知(和工作与UIScrollView),内容在一个UIScrollView不会自动自动调整大小随着UIScrollView。

把UIScrollView看作是一个窗口/门户,它通向你的内容所在的另一个世界。当自动调整UIScrollView的大小时,你只是改变了查看窗口的形状/大小…而不是另一个宇宙内容的大小

然而,如果需要,你可以拦截旋转事件,并手动更改你的内容也(与动画,使它看起来不错)。

为了正确的自动调整大小,你应该改变scrollView的contentSize(这样它就知道你的宇宙的大小),但也要改变UIView的大小。我想这就是为什么你可以滚动看到黑色内容的原因。也许你只是更新了contentSize,但现在实际的内容视图

就我个人而言,我还没有遇到过任何需要随着UIScrollView调整内容大小的情况,但我希望这将使您在正确的方向上开始

如果我理解正确的话,你想要一个带有图像的滚动视图。它需要全屏开始,你需要能够放大。最重要的是,你希望它能够根据方向旋转。

好吧,我一直在原型与此在过去,如果所有以上是正确的,下面的代码应该为您工作。

我为bar/custombars留下了一点白色区域。

- (void)viewDidLoad
{  
    [super viewDidLoad];
    //first inits and allocs
    scrollView2 = [[UIScrollView alloc] initWithFrame:self.view.frame];
    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImageName"]];
    [scrollView2 addSubview:imageView];
    [self drawContent]; //refreshing the content
    [self.view addSubview:scrollView2];
}
-(void)drawContent
{
    //this refreshes the screen to the right sizes and zoomscales.
    [scrollView2 setBackgroundColor:[UIColor blackColor]];
    [scrollView2 setCanCancelContentTouches:NO];
    scrollView2.clipsToBounds = YES;
    [scrollView2 setDelegate:self];
    scrollView2.indicatorStyle = UIScrollViewIndicatorStyleWhite;
    [scrollView2 setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
    [scrollView2 setScrollEnabled:YES];
    float minZoomScale;
    float zoomHeight = imageView.frame.size.height / scrollView2.frame.size.height;
    float zoomWidth = imageView.frame.size.width / scrollView2.frame.size.width;
    if(zoomWidth > zoomHeight)
    {
        minZoomScale = 1.0 / zoomWidth;
    }
    else
    {
        minZoomScale = 1.0 / zoomHeight;
    }
    [scrollView2 setMinimumZoomScale:minZoomScale];
    [scrollView2 setMaximumZoomScale:7.5];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        // Portrait 
        //the 88pxls is the white area that is left for the navbar etc.
        self.scrollView2.frame = CGRectMake(0, 88, [UIScreen mainScreen].bounds.size.width, self.view.frame.size.height - 88);
        [self drawContent];
    }
    else {
        // Landscape
        //the 88pxls is the white area that is left for the navbar etc.
        self.scrollView2.frame = CGRectMake(0, 88, [UIScreen mainScreen].bounds.size.height, self.view.frame.size.width);
        [self drawContent];
    }
    return YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}
我希望这会解决你的麻烦。如果没有,请留下评论。

当你想把一个内容(一个UIView实例,让我们叫它theViewInstance)放在UIScrollView然后滚动/缩放theViewInstance,方法是:

  • viewinstance 应该被添加为UIScrollView
  • 的子视图
  • 设置委托给UIScrollView实例并实现选择器以返回应该用于缩放/滚动的视图:

    -(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {  
          return theViewInstance;  
    } 
    
  • 设置UIScrollView的内容大小默认为theViewInstance的框架:

    scrollView.contentSize=theViewInstance.frame.size;
    

    (此外,可以在UIScrollView:中设置可接受的缩放级别)

    scrollView.minimumZoomScale=1.0;
    scrollView.maximumZoomScale=3.0;
    

这是在UIImage上实现缩放的方式:UIImageView被添加到UIScrollView中,在UIScrollViewDelegate实现中,UIImageView被返回(如这里所述)。

对于旋转支持,这是在UIViewController中完成的它的UIView包含了我们刚刚讨论过的UIScrollView

最新更新