我正在尝试获得类似于zoomRectToVisible
UIScrollview 的 -method 的效果。但是我的方法应该能够在缩放时将特定矩形居中在图层中,并且它应该能够在设备方向改变后重新调整。
我正在尝试编写一个类似 marvel-comic 应用程序的软件,并且需要一个在页面中显示每个面板的视图。
对于我的实现,我使用 CALayer 和 Core Animation 来通过 CATransform3D-transformations 获得所需的效果。我的问题是,我无法使缩放的矩形/面板居中。
我的实现结构如下所示:我有一个 UIScrollview 的子类,其中添加了一个 UIView 作为子视图。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 方法的原因。
所以我必须知道如何正确计算转换的转换参数。
我希望有人可以指导我获得正确的参数。