zoomRectToVisible
UIScrollviewのメソッドのような効果を得ようとしています。しかし、私の方法は、ズーム中にレイヤー内の特定の四角形を中央に配置できるはずであり、デバイスの向きが変更された後に再調整できるはずです。
marvel-comic アプリのようなソフトウェアを作成しようとしていますが、各パネルをページに表示するビューが必要です。
私の実装では、CALayer と Core Animation を使用して、CATransform3D 変換で目的の効果を得ています。私の問題は、ズームされた四角形/パネルを中央に配置できないことです。
私の実装の構造は次のようになります。サブビューとして UIView が追加された UIScrollview のサブクラスがあります。UIView には CALayer.contents の画像/ページが含まれており、コア アニメーションを使用してズームとセンタリングの効果を得ています。各パネルのズーム効果は正しく機能しますが、センタリングはオフです。センタリングのための正しい変換変換を計算できません。
効果を実装するための私のコードは次のとおりです。
- (void) zoomToRect:(CGRect)rect animated:(BOOL)animated {
CGSize scrollViewSize = self.bounds.size;
// get the current panel boundingbox
CGRect panelboundingBox = CGPathGetBoundingBox([comicPage panelAtIndex:currentPanel]);
// compute zoomfactor depending on the longer dimension of the panelboundingBox size
CGFloat zoomFactor = (panelboundingBox.size.height > panelboundingBox.size.width) ? scrollViewSize.height/panelboundingBox.size.height : scrollViewSize.width/panelboundingBox.size.width;
CGFloat translateX = scrollViewSize.width/2 - (panelboundingBox.origin.x/2 + panelboundingBox.size.width/2);
CGFloat translateY = scrollViewSize.height/2 - (panelboundingBox.size.height/2 - panelboundingBox.origin.y);
// move anchorPoint to panelboundingBox center
CGPoint anchor = CGPointMake(1/contentViewLayer.bounds.size.width * (panelboundingBox.origin.x + panelboundingBox.size.width/2), 1/contentViewLayer.bounds.size.height * (contentViewLayer.bounds.size.height - (panelboundingBox.origin.y + panelboundingBox.size.height/2)));
// create the nessesary transformations
CATransform3D translateMatrix = CATransform3DMakeTranslation(translateX, -translateY, 1);
CATransform3D scaleMatrix = CATransform3DMakeScale(zoomFactor, zoomFactor, 1);
// create respective core animation for transformation
CABasicAnimation *zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
zoomAnimation.fromValue = (id) [NSValue valueWithCATransform3D:contentViewLayer.transform];
zoomAnimation.toValue = (id) [NSValue valueWithCATransform3D:CATransform3DConcat(scaleMatrix, translateMatrix)];
zoomAnimation.removedOnCompletion = YES;
zoomAnimation.duration = duration;
// create respective core animation for anchorpoint movement
CABasicAnimation *anchorAnimatione = [CABasicAnimation animationWithKeyPath:@"anchorPoint"];
anchorAnimatione.fromValue = (id)[NSValue valueWithCGPoint:contentViewLayer.anchorPoint];
anchorAnimatione.toValue = (id) [NSValue valueWithCGPoint:anchor];
anchorAnimatione.removedOnCompletion = YES;
anchorAnimatione.duration = duration;
// put them into an animation group
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = [NSArray arrayWithObjects:zoomAnimation, anchorAnimatione, nil] ;
/////////////
NSLog(@"scrollViewBounds (w = %f, h = %f)", self.frame.size.width, self.frame.size.height);
NSLog(@"panelBounds (x = %f, y = %f, w = %f, h = %f)", panelboundingBox.origin.x, panelboundingBox.origin.y, panelboundingBox.size.width, panelboundingBox.size.height);
NSLog(@"zoomfactor: %f", zoomFactor);
NSLog(@"translateX: %f, translateY: %f", translateX, translateY);
NSLog(@"anchorPoint (x = %f, y = %f)", anchor.x, anchor.y);
/////////////
// add animation group to layer
[contentViewLayer addAnimation:group forKey:@"zoomAnimation"];
// trigger respective animations
contentViewLayer.anchorPoint = anchor;
contentViewLayer.transform = CATransform3DConcat(scaleMatrix, translateMatrix);
}
したがって、ビューには次の点が必要です。
- 現在のデバイスの向きに応じて、レイヤー/ビューの長方形/パネルをズームして中央に配置できるはずです。(UIScrollview の zoomRectToVisible は四角形を中央に配置しません)
- 必要に応じて(デバイスの向きが変更されたか、パネルの回転が必要な場合)、ズームされたパネル/四角形は回転できる必要があります
- アニメーションの長さはユーザーの好みによって異なります。( UIScrollView の zoomRectToVisible のデフォルトのアニメーション時間を変更できるかどうかわかりませんか?)
これらの点が、UIScrollView の zoomRectToVisible メソッドを上書きする理由です。
そのため、変換の変換パラメーターを正しく計算する方法を知る必要があります。
正しいパラメーターを取得するために誰かが私を案内してくれることを願っています。