2012-09-06 139 views
6

我想帮助我的UIScrollView示例。内容跳跃缩小与UIScrollView

我创建了一个简单的程序,可以滚动和缩放内容(UIImageView)。它工作正常,除了当我尝试缩小内容时,内容经常消失在右下角。但是因为我将minimumZoomScale设置为1.0f,所以它实际上不会缩小,只有内容跳出视图。而更奇怪的是,在这之后我无法再往上滚动。显然内容大小也是混乱的。

enter image description here

的设置我在我的示例代码如下图。

enter image description here

当我检查(试图)缩小后的状态,我发现了两个错误的东西。

  • _scrollView.contentSize是小480x360,这不应该是小于1000×1000
  • _scrollView.bounds跃升至顶级不知何故(即_scrollView.bounds.origin.y始终为0)

要应付两个项目上面,我在我的UIScrollViewDelegate中添加了以下代码,现在它工作正常。

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view 
{ 
    if(scrollView == _scrollView && view == _contentView) 
    { 
     // Setting ivars for scrollViewDidZoom 
     _contentOffsetBeforeZoom = _scrollView.contentOffset; 
     _scrollViewBoundsBeforeZoom = _scrollView.bounds; 
    } 
} 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView 
{ 
    if(scrollView == _scrollView) 
    { 
     // If you zoom out, there are cases where ScrollView content size becomes smaller than original, 
     // even though minimum zoom scale = 1. In that case, it will mess with the contentOffset as well. 
     if(_scrollView.contentSize.width < CONTENT_WIDTH || _scrollView.contentSize.height < CONTENT_HEIGHT) 
     { 
      _scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT); 
      _scrollView.contentOffset = _contentOffsetBeforeZoom; 
     } 

     // If you zoom out, there are cases where ScrollView bounds goes outsize of contentSize rectangle. 
     if(_scrollView.bounds.origin.x + _scrollView.bounds.size.width > _scrollView.contentSize.width || 
      _scrollView.bounds.origin.y + _scrollView.bounds.size.height > _scrollView.contentSize.height) 
     { 
      _scrollView.bounds = _scrollViewBoundsBeforeZoom; 
     }    
    } 
} 

然而,它是否需要回到这个?这是一个非常简单的顺序,很难相信苹果要我们做这种努力。所以,我的赌注是我在这里失去了一些东西...

以下是我的原始代码。请帮我看看我做错了什么(或者错过了什么)!

#define CONTENT_WIDTH 1000 
#define CONTENT_HEIGHT 1000 

    >>>> Snip >>>> 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)]; 
    _scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT); 
    _scrollView.backgroundColor = [UIColor blueColor]; 
    _scrollView.maximumZoomScale = 8.0f; 
    _scrollView.minimumZoomScale = 1.0f; 
    _scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite; 
    _scrollView.scrollEnabled = YES; 
    _scrollView.delegate = self; 
    [self.view addSubview:_scrollView]; 

    _contentView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"sample.jpg"]]; // sample.jpg is 480x360 
    CGPoint center = (CGPoint){_scrollView.contentSize.width/2, _scrollView.contentSize.height/2}; 
    _contentView.center = center; 
    [_scrollView addSubview:_contentView]; 

    _scrollView.contentOffset = (CGPoint) {center.x - _scrollView.bounds.size.width/2, center.y - _scrollView.bounds.size.height/2};   
} 

- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView 
{ 
    if(scrollView == _scrollView) 
    { 
     return _contentView; 
    } 
    return nil; 
} 
+1

你有没有试过设置_contentView。autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;'? – Adam

+0

谢谢你的建议。但不,它不会改变这种情况... – barley

+0

我可以问你为什么你的'contentSize'是1000x1000吗? – tia

回答

10

我创建了一个快速示例项目,并且使用您粘贴的代码描述了相同的问题。我不完全知道“适当”的缩放方式是在iOS中,但我发现this教程指出,在scrollView放大后您需要重新接收contentView。我个人认为它会自动重新居中,因为它是你在viewForZoomingInScrollView委托方法中返回的视图,但显然不是。

- (void)centerScrollViewContents { 
    CGSize boundsSize = _scrollView.bounds.size; 
    CGRect contentsFrame = _contentView.frame; 

    if (contentsFrame.size.width < boundsSize.width) { 
     contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width)/2.0f; 
    } else { 
     contentsFrame.origin.x = 0.0f; 
    } 

    if (contentsFrame.size.height < boundsSize.height) { 
     contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height)/2.0f; 
    } else { 
     contentsFrame.origin.y = 0.0f; 
    } 

    _contentView.frame = contentsFrame; 
} 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView { 
    // The scroll view has zoomed, so we need to re-center the contents 
    [self centerScrollViewContents]; 
} 

上面的代码是不是我写的,但仅仅是从本教程复制。我认为它非常简单。此外,将contentView居中似乎更加优雅,然后不断更改scrollview的边界和内容大小,请尝试一下。

+0

感谢您的回答!这是有道理的,它很好地工作。 答案中唯一的事情就是'_scrollView.frame'应该在我的上下文中是__contentView.frame。我将编辑该部分并选择作为我的答案。 – barley

0

如果任何人在缩小显示的结果背景时遇到弹跳问题,请尝试在界面构建器中移除反弹(缩放)。

1

我能够解决这个问题,使用调整变焦后的比率的委托答案......但后来我想起我正在使用自动布局,并添加约束水平和垂直居中(除约束将图像绑定到滚动视图的每个边缘)为我解决了问题,而不使用委托方法。

+0

问题来自frame和struts时代,并且很高兴知道约束优雅地解决了这个问题! – barley