2012-09-06 17 views
6

私のUIScrollViewサンプルに関するヘルプが必要です。コンテンツはUIScrollViewでズームアウト時にジャンプする

コンテンツをスクロールしてズームする簡単なプログラムを作成しました(UIImageView)。ズームアウトしようとするとコンテンツが頻繁に右下に消えてしまうことを除いて、正常に動作します。しかし、私はminimumZoomScaleを1.0fに設定しているので、実際にはズームアウトされていません。コンテンツだけがビューから飛び出しています。そしてさらに奇妙なことは、私がこれ以降スクロールできないということです。どうやらコンテンツのサイズも混乱しているようです。

enter image description here

私は私のサンプルコードで持っている設定は下図の通りです。

enter image description here

私はズームアウト(しよう)した後の状態をチェックすると、私は2つの間違ったことを発見しました。

  • _scrollView.contentSize 1000×1000
  • _scrollView.bounds 2つの項目に対応するため
  • (すなわち、 _scrollView.bounds.origin.yは常に0である)何とかトップに

を跳んだより小さくすべきではない480×360であり、私は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; 
     }    
    } 
} 

ただし、これにする必要はありますか?これは非常にシンプルなシーケンスであり、Appleがこのような努力を払う必要があると考えるのは難しいです。だから、私の賭けはここに何かを見逃している...

以下は私のオリジナルコードです。私が間違っていること(または何かがないこと)を見つけるのを助けてください!

#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の設定を試したことがありますか?自動サイズ変更マスク= 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の中央揃えは、よりスムーズになり、スクロールビューの範囲とコンテンツサイズを絶えず変更していますので、試してみてください。

+0

答えをありがとう!それは理にかなっており、うまく機能しました。 私の文脈では、 '_scrollView.frame'は' _contentView.frame'でなければいけません。私はその部分を編集し、私の答えとして選択します。 – barley

0

結果の背景を表示するときにバウンスの問題が発生した場合は、Interface Builderでバウンス(バウンスズーム)を削除してみてください。

1

ズーム後にレートを調整したデリゲートの回答を使用してこの問題を修正できましたが、自動レイアウトを使用していて、横方向と縦方向のセンタリングの制約を追加していたことを思い出しました。スクロールビューの各端にイメージを結びつける)、デリゲートメソッドを使わずに私の問題を解決しました。

+0

質問はフレームとストラット時代のものでしたが、制約がエレガントにこの問題を解決することを知ってうれしいです! – barley

関連する問題