2

私はドキュメントビューアに取り組んでいます。ドキュメントは の中に表示され、UIScrollViewスクロールやズームが可能です。の背景から視覚的に分離するために、ドキュメントの周りに境界線を引く必要がありUIScrollViewます。境界線はドキュメントと一緒にズームしてはなりません。ズーム スケールに関係なく、一定の太さを維持する必要があります。

私の現在のセットアップは、UIScrollView2UIViewつの子を持つ で構成されています。1 つはドキュメント用、もう 1 つは境界線用です。viewForZoomingInScrollViewドキュメント ビューを返すために : をオーバーライドしました。また、ドキュメント ビューを中央に配置するようにオーバーライドlayoutSubviewsし (ドキュメント ビューが よりも小さい場合UIScrollView)、フレームのように見えるように、境界ビューのサイズを変更してその背後に配置します。これは、ユーザーが手動でスクロールおよびズームしている場合に問題なく機能します。しかし、zoomToRect:animated:プログラムでズームを使用すると、アニメーションが開始する前に layoutSubviews が呼び出され、ボーダー ビューのサイズがすぐに変更され、ドキュメント ビューが少し遅れて追いつきます。

明確化: 境界線は、ドキュメント ビュー自体ではなく、ドキュメント ビューの周囲にぴったりと収まる必要がありUIScrollViewます。

4

4 に答える 4

1

最後に、アニメーション ズームの問題を修正することができました。私のセットアップは、質問で説明されているものと同じです。layoutSubview実行中のアニメーションを検出しUIScrollView、境界線のサイズを変更するための同様のアニメーションと一致させるために、いくつかのコードを実装に追加しました。

コードは次のとおりです。

- (void)layoutSubviews
{
  [super layoutSubviews];

  // _pageView displays the document
  // _borderView represents the border around it

  . . .


  // _pageView is now centered -- we have to move/resize _borderView
  // layers backing a view are not implicitly animated
  // the following two lines work just fine if we don't need animation
  _borderView.layer.bounds = CGRectMake(0.0, 0.0, frameToCenter.size.width + 2.0 * 15.0, frameToCenter.size.height + 2.0 * 15.0);
  _borderView.layer.position = _pageView.center;

  if (_pageView.layer.animationKeys.count > 0)
  {
    // UIScrollView is animating its content (_pageView)
    // so we need to setup a matching animation for _borderView

    [CATransaction begin];

    CAAnimation *animation = [_pageView.layer animationForKey:[_pageView.layer.animationKeys lastObject]];
    CFTimeInterval beginTime = animation.beginTime;
    CFTimeInterval duration = animation.duration;

    if (beginTime != 0.0) // 0.0 means the animation starts now
    {
      CFTimeInterval currentTime = [_pageView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
      duration = MAX(beginTime + duration - currentTime, 0.0);
    }

    [CATransaction setAnimationDuration:duration];
    [CATransaction setAnimationTimingFunction:animation.timingFunction];

    // calculate the initial state for _borderView animation from _pageView presentation layer
    CGPoint presentationPos = [_pageView.layer.presentationLayer position];
    CGRect presentationBounds = [_pageView.layer.presentationLayer frame];
    presentationBounds.origin = CGPointZero;
    presentationBounds.size.width += 2.0 * 15.0;
    presentationBounds.size.height += 2.0 * 15.0;

    CABasicAnimation *boundsAnim = [CABasicAnimation animationWithKeyPath:@"bounds"];
    boundsAnim.fromValue = [NSValue valueWithCGRect:presentationBounds];
    boundsAnim.toValue = [NSValue valueWithCGRect:_borderView.layer.bounds];
    [_borderView.layer addAnimation:boundsAnim forKey:@"bounds"];

    CABasicAnimation *posAnim = [CABasicAnimation animationWithKeyPath:@"position"];
    posAnim.fromValue = [NSValue valueWithCGPoint:presentationPos];
    posAnim.toValue = [NSValue valueWithCGPoint:_borderView.layer.position];
    [_borderView.layer addAnimation:posAnim forKey:@"position"];

    [CATransaction commit];
  }

}

ハックに見えますが、機能します。UIScrollView単純な境界線をアニメーション中に見栄えよくするために、リバース エンジニアリングを行う必要がなかったらいいのにと思います...

于 2013-06-10T08:43:08.540 に答える
0

QuartzCore フレームワークをインポートします。

#import <QuartzCore/QuartzCore.h>

ビューに色を追加します。

[scrollViewObj.layer setBorderColor:[[UIColor redColor] CGColor]];

[scrollViewObj.layer setBorderWidth:2.0f];
于 2013-05-27T12:38:24.233 に答える