在我的iPad应用中,我有一个带有小桌面视图的视图控制器。当您点击表格视图时,它会打开一个模态视图控制器,它是一个更大,更精致的小表视图版本。我想通过将图像缩小到小表视图的大小并将其缩放到全屏大小,然后用“真实”视图替换图像,从大视图控制器的预渲染图像创建动画控制器。
类似的东西:
LargeViewController* lvc = [[LargeViewController alloc] init];
[self presentModalViewController:lvc byZoomingFromRect:CGRectMake(50,50,200,300)];
我知道你可以从视图中生成图像:
- (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
但是如何让视图控制器自己绘制(在屏幕外),这样我就可以看到它并在动画中缩放图像以填充屏幕?
提前致谢。
答案 0 :(得分:3)
我想你想创建自己的动画。上个月我玩过类似的东西。我的解决方案是将自定义视图(可能从视图控制器中获取)添加到当前视图作为叠加层。这也适用于图层。
首先,从“未来”或“现在”视图控制器中获取图像,就像在上面的代码示例中所做的那样。通常,视图控制器内容在渲染到上下文时应该可用。
现在你有了这张照片。图像的操作必须由您完成。
将图像添加到UIImageView。此ImageView可以添加为子视图或图层。现在您有一个图层,您可以在实际用户界面之上自由绘制。有时您必须移动图层或视图,以便它完美地覆盖您的视图。这取决于您的视图设置。如果您正在处理Tableview,添加子视图并不容易。所以最好使用图层。
完成所有工作后,显示没有动画的新视图控制器,以便立即显示。
完成工作后从父视图中删除图层或视图,然后进行清理。
这听起来很复杂,但是一旦你完成了,你就有了一个模板。在“WWDC 2011,会话309介绍Interface Builder故事板”中,苹果推出了“自定义segues”,您可以在其中找到一种机制,准确地说明您想要做什么。下面的代码是旧项目的剪切,并且有点凌乱,必须清理。但是为了表明原则,这应该有效:
-(void) animate {
static LargeViewController* lvc = [[LargeViewController alloc] init];
UIGraphicsBeginImageContextWithOptions(self.bounds.size, view.opaque, [[UIScreen mainScreen] scale]);
[lvc.view.layer renderInContext:UIGraphicsGetCurrentContext()];
// Create a ImageView to display your "zoomed" image
static UIImageView* displayView = [[UIImageView alloc] initWithFrame:self.view.frame];
static UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Add your image to the view
displayView.image = img;
// insert the view above your actual view, adjust coordinates in the
// frame property of displayView if overlay is misaligned
[[self.view] addSubview:displayView];
// alternatively you can use the layer
// [self.view.layer addSublayer:displayView.layer];
// draw the imageView
[displayView setNeedsDisplay];
// do something in background. You may create your own
// construction, i.e. using a timer
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSDate *now = [NSDate date];
NSTimeInterval animationDuration = 3.;
NSTimeInterval t = -[now timeIntervalSinceNow];
while (t < animationDuration) {
t = -[now timeIntervalSinceNow];
// Do some animation here, by manipulation the image
// or the displayView
// <calculate animation>, do something with img
// you have exact timing information in t,
// so you can set the scalefactor derived from t
// You must not use an UIImage view. You can create your own view
// and do sth. in draw rect. Do whatever you want,
// the results will appear
// in the view if you added a subview
// or in a layer if you are using the layer
dispatch_sync(dispatch_get_main_queue(), ^{
// display the result
displayView.image = img;
[displayView setNeedsDisplay];
});
}
});
// now the animation is done, present the real view controller
[self presentModalViewController:lvc animated:NO];
// and clean up here
}
答案 1 :(得分:0)
也许你可以使用像
这样的东西CGAffineTransform tr = CGAffineTransformScale(lvc.view.transform, 0.5, 0.5);
在父视图控制器中嵌入缩小版本的视图,然后以模态方式显示lvc并在用户点击视图时恢复缩放。
答案 2 :(得分:0)
UIKit会为您完成大部分工作。虽然jbat100的解决方案也可以使用,但您应该只需将lvc
的初始帧设置为您想要开始的较小的矩形,然后将帧设置为其全尺寸时,用于更改框架的隐式动画将为您处理缩放动画。每个UIView都有一个CALayer,其内容被绘制出来,并且该图层有几个隐式动画设置,可以对某些属性(如帧或位置属性)进行动画更改。这是我未经测试的抨击:
.
.
lvc.view.frame = CGRectMake(50,50,200,300);
[self performSelector:@selector(setFrameToFullScreen) withObject:nil afterDelay:0];
}
- (void)setFrameToFullScreen {
lcv.view.frame = [UIScreen mainScreen].bounds;
}
performSelector:withObject:afterDelay
调用将导致在下一个运行循环周期中调用setFrameToFullScreen
。如果你不做那样的事情,那么只会使用最后的帧,系统将无法识别帧中的变化并将其隐式动画应用于视图层。