2011-10-07 51 views
9

在我的iPad應用程序中,我有一個帶有小表視圖的視圖控制器。當你點擊表格視圖時,它會打開一個模式視圖控制器,它是小型表格視圖的一個更大和更精緻的版本。我想從大視圖控制器的預渲染圖像創建一個動畫,方法是將圖像縮小爲小表視圖的大小並將其縮放爲全屏大小,然後用「真實」視圖替換圖像控制器。如何通過縮放呈現UIViewController?

喜歡的東西:

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; 
} 

但如何使視圖控制器平局本身(屏幕外),所以我可以把它的在動畫中查看和縮放圖像以填充屏幕?

在此先感謝。

回答

3

我想你想創建你自己的動畫。上個月我玩過類似的東西。我的解決方案是將自定義視圖(可能從視圖控制器獲取)作爲疊加層添加到當前視圖。這也適用於圖層。

首先你從你的「未來」或「現在的」視圖控制器獲取圖像,就像你在上面的代碼示例中那樣。通常情況下,視圖控制器內容在渲染到上下文時應該可用。

現在你有圖像。圖像的操作必須由您完成。

將圖像添加到UIImageView。這個ImageView可以添加爲子視圖或圖層。現在你有了一個可以自由繪製在實際用戶界面上的圖層。有時你必須移動圖層或視圖,以便完美覆蓋視圖。這取決於你的視圖設置。如果您正在處理Tableviews,添加子視圖並不那麼容易。所以最好使用圖層。

完成所有工作後,不帶動畫地呈現新的視圖控制器,以便它立即出現。

工作完成後清除父視圖中的圖層或視圖並進行清理。

這聽起來很複雜,但一旦你完成了,你有一個模板。在「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 
} 
+0

終於有時間來測試你的,非常詳細的建議。奇蹟般有效!非常感謝您的意見!而且,與定製seques的WWDC 2011會議309也會有很好的效果。 –

0

也許你可以使用類似

CGAffineTransform tr = CGAffineTransformScale(lvc.view.transform, 0.5, 0.5); 

在父視圖控制器,那麼目前LVC模態嵌入視圖的縮小版本,當用戶點擊視圖恢復比例。

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要在下次運行循環週期調用。如果你不這樣做,那麼只會使用最後一幀,系統將無法識別幀中的變化,並將其隱式動畫應用於視圖圖層。

+0

的問題是,一個視圖控制器沒有一個框架的性能,因爲它不是一個視圖類。我知道顯示視圖控制器的唯一方法是使用presentModalViewController:animated:方法,該方法設置動畫本身。 –

+0

你的權利!視圖控制器沒有框架,但它的視圖。我編輯了上面的代碼來反映這一點。 – Logachu

相關問題