如何通过缩放呈现UIViewController?

Påh*_*lin 9 iphone objective-c ipad ios

在我的iPad应用程序中,我有一个带有小表视图的视图控制器.当您点击表格视图时,它会打开一个模态视图控制器,它是一个更大,更精致的小表视图版本.我想通过将图像缩小到小表视图的大小并将其缩放到全屏大小,然后用"真实"视图替换图像,从大视图控制器的预渲染图像创建动画控制器.

就像是:

LargeViewController* lvc = [[LargeViewController alloc] init];
[self presentModalViewController:lvc byZoomingFromRect:CGRectMake(50,50,200,300)];
Run Code Online (Sandbox Code Playgroud)

我知道你可以从视图中生成图像:

- (UIImage *) imageWithView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}
Run Code Online (Sandbox Code Playgroud)

但是如何让视图控制器自己绘制(在屏幕外),这样我就可以看到它并在动画中缩放图像以填充屏幕?

提前致谢.

Jac*_*rse 3

我想您想创建自己的动画。上个月我就玩过类似的东西。我的解决方案是将自定义视图(可能从视图控制器获取)添加到当前视图作为覆盖。这也适用于图层。

首先,您从“未来”或“当前”视图控制器中获取图像,就像您在上面的代码示例中所做的那样。通常,视图控制器内容在渲染到上下文时应该可用。

现在你有了图像。图像的处理必须由您完成。

将图像添加到 UIImageView。此 ImageView 可以添加为子视图或图层。现在您有了一个可以在实际用户界面上方自由绘制的图层。有时您必须移动图层或视图,以便它完美地覆盖您的视图。这取决于您的视图设置。如果您正在处理 Tableview,添加子视图并不那么容易。所以最好使用图层。

完成所有工作后,呈现没有动画的新视图控制器,以便它立即出现。

工作完成后,从父视图中删除图层或视图并进行清理。

这听起来很复杂,但是一旦完成,您就拥有了一个模板。在“WWDC 2011,Session 309 Introducing Interface Builder Storyboarding”中,苹果引入了“自定义转场”,您可以在其中找到一种完全可以完成您想要做的事情的机制。下面的代码是从旧项目中剪下来的,有些混乱,必须清理。但为了展示原理,这应该可行:

-(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
}
Run Code Online (Sandbox Code Playgroud)