共用方式為


Xamarin.iOS 中的核心動畫

本文會檢查 Core Animation 架構,示範如何在 UIKit 中啟用高效能、流暢的動畫,以及如何將其直接用於較低層級的動畫控件。

iOS 包含 核心動畫 ,可為應用程式中的檢視提供動畫支援。 iOS 中的所有超平滑動畫,例如數據表卷動,並在不同的檢視之間撥動執行,以及它們執行,因為它們在內部依賴核心動畫。

核心動畫和核心圖形架構可以共同建立美觀的動畫 2D 圖形。 事實上,核心動畫甚至可以在 3D 空間中轉換 2D 圖形,創造驚人的電影體驗。 不過,若要建立真正的 3D 圖形,您必須使用 OpenGL ES 之類的專案,或讓遊戲轉向 MonoGame 之類的 API,雖然 3D 超出本文的範圍。

Core Animation

iOS 使用核心動畫架構來建立動畫效果,例如在檢視、滑動功能表和卷動效果之間轉換,以命名幾個。 有兩種方式可以處理動畫:

  • 透過UIKit,其中包含以檢視為基礎的動畫,以及控制器之間的動畫轉換。
  • 透過核心動畫,直接分層,允許更精細的控制。

使用UIKit動畫

UIKit 提供數個功能,可讓您輕鬆地將動畫新增至應用程式。 雖然它在內部使用 Core Animation,但它會將其抽象化,因此您只能使用檢視和控制器。

本節討論 UIKit 動畫功能,包括:

  • 控制器之間的轉換
  • 在檢視之間轉換
  • 檢視屬性動畫

檢視控制器轉換

UIViewController 提供透過 PresentViewController 方法在檢視控制器之間轉換的內建支援。 使用 PresentViewController時,轉換至第二個控制器可以選擇性地產生動畫效果。

例如,假設有兩個控制器的應用程式,其中觸控第一個控制器中的按鈕會呼叫 PresentViewController 以顯示第二個控制器。 若要控制用來顯示第二個控制器的轉換動畫,只要設定其 ModalTransitionStyle 屬性,如下所示:

SecondViewController vc2 = new SecondViewController {
  ModalTransitionStyle = UIModalTransitionStyle.PartialCurl
};

在此情況下 PartialCurl ,會使用動畫,但有數個其他動畫可供使用,包括:

  • CoverVertical – 從螢幕底部向上投影片
  • CrossDissolve – 舊檢視淡出 , 新檢視淡入
  • FlipHorizontal - 水平由右至左翻轉。 關閉時,轉換會由左至右翻轉。

若要讓轉換產生動畫效果,請將 作為第二個自變數傳遞 truePresentViewController

PresentViewController (vc2, true, null);

下列螢幕快照顯示案例的轉換外觀 PartialCurl

此螢幕快照顯示 PartialCurl 轉換

檢視轉換

除了在控制器之間轉換之外,UIKit 也支援在檢視之間產生動畫轉換,以交換另一個檢視。

例如,假設您有控制器, UIImageView其中點選影像應該會顯示第二 UIImageView個 。 若要以動畫顯示影像檢視的超級檢視,以轉換至第二個影像檢視,就像呼叫 UIView.Transition一樣簡單,傳遞 toView 它,如下所示 fromView

UIView.Transition (
  fromView: view1,
  toView: view2,
  duration: 2,
  options: UIViewAnimationOptions.TransitionFlipFromTop |
    UIViewAnimationOptions.CurveEaseInOut,
  completion: () => { Console.WriteLine ("transition complete"); });

UIView.Transition 也會採用 duration 參數,控制動畫執行的時間長度,以及 options 指定要使用的動畫和 Easing 函式等專案。 此外,您可以指定動畫完成時所呼叫的完成處理程式。

下列螢幕快照顯示使用時 TransitionFlipFromTop 影像檢視之間的動畫轉換:

此螢幕快照顯示使用 TransitionFlipFromTop 時影像檢視之間的動畫轉換

檢視屬性動畫

UIKit 支援免費在 類別上建立各種屬性的 UIView 動畫效果,包括:

  • Frame
  • Bounds
  • 置中
  • Alpha
  • 轉換
  • Color

這些動畫會在傳遞至靜態UIView.Animate方法的NSAction委派中指定屬性變更,以隱含方式發生。 例如,下列程式代碼會以動畫顯示 的中心 UIImageView點:

pt = imgView.Center;

UIView.Animate (
  duration: 2,
  delay: 0,
  options: UIViewAnimationOptions.CurveEaseInOut |
    UIViewAnimationOptions.Autoreverse,
  animation: () => {
    imgView.Center = new CGPoint (View.Bounds.GetMaxX ()
      - imgView.Frame.Width / 2, pt.Y);},
  completion: () => {
    imgView.Center = pt; }
);

這會導致影像在畫面頂端來回產生動畫效果,如下所示:

在畫面頂端來回動畫作為輸出的影像

Transition如同方法,Animate允許設定持續時間以及 Easing 函式。 這個範例也使用了 UIViewAnimationOptions.Autoreverse 選項,這會導致動畫從值動畫回到初始值。 不過,程式代碼也會在完成處理程式中將 設定 Center 回其初始值。 雖然動畫會隨著時間插補屬性值,但 屬性的實際模型值一律是已設定的最終值。 在此範例中,值是靠近超級檢視右側的點。 若未將 設定 Center 為初始點,也就是動畫因為設定完成而完成 Autoreverse 的位置,影像會在動畫完成之後向右貼齊,如下所示:

若未將中心設定為初始點,影像會在動畫完成之後回復到右側

使用核心動畫

UIView 動畫允許許多功能,而且應該盡可能使用,因為實作容易。 如先前所述,UIView 動畫會使用核心動畫架構。 不過,有些事情無法透過 UIView 動畫來完成,例如以檢視建立動畫效果的其他屬性,或沿著非線性路徑插補。 在您需要更精細的控制的情況下,也可以直接使用 Core Animation。

圖層

使用 Core 動畫時,動畫會透過屬於 類型的CALayer層次進行。 圖層在概念上類似於有圖層階層的檢視,就像有檢視階層一樣。 實際上,層層檢視,檢視會新增對用戶互動的支援。 您可以透過檢視的屬性存取任何檢視的 Layer 圖層。 事實上,在方法UIView中使用的Draw內容實際上是從圖層建立的。 在內部,備份 的 UIView 圖層會將其委派設定為檢視本身,也就是所謂的 Draw。 因此,當繪製至 UIView時,您實際上是繪製到其圖層。

層次動畫可以是隱含或明確的。 隱含動畫為宣告式。 您只要宣告應該變更哪些圖層屬性,動畫就能正常運作。 另一方面,會透過新增至圖層的動畫類別來建立明確的動畫。 明確動畫允許新增對動畫建立方式的控制。 下列各節深入探討隱含和明確的動畫。

隱式動畫

以動畫顯示圖層屬性的其中一種方式是透過隱含動畫。 UIView 動畫會建立隱含動畫。 不過,您也可以直接針對圖層建立隱含動畫。

例如,下列程式代碼會從影像設定圖層的 Contents 、設定框線寬度和色彩,並將圖層新增為檢視層的子圖層:

public override void ViewDidLoad ()
{
  base.ViewDidLoad ();

  layer = new CALayer ();
  layer.Bounds = new CGRect (0, 0, 50, 50);
  layer.Position = new CGPoint (50, 50);
  layer.Contents = UIImage.FromFile ("monkey2.png").CGImage;
  layer.ContentsGravity = CALayer.GravityResize;
  layer.BorderWidth = 1.5f;
  layer.BorderColor = UIColor.Green.CGColor;

  View.Layer.AddSublayer (layer);
}

若要為圖層新增隱含動畫,只需在 中 CATransaction包裝屬性變更即可。 這可讓無法使用檢視動畫產生動畫效果的屬性,例如 BorderWidth ,如下所示 BorderColor

public override void ViewDidAppear (bool animated)
{
  base.ViewDidAppear (animated);

  CATransaction.Begin ();
  CATransaction.AnimationDuration = 10;
  layer.Position = new CGPoint (50, 400);
  layer.BorderWidth = 5.0f;
  layer.BorderColor = UIColor.Red.CGColor;
  CATransaction.Commit ();
}

此程式代碼也會以動畫顯示圖層的 Position,這是從超層座標左上方測量的圖層錨點位置。 圖層的錨點是圖層座標系統中的標準化點。

下圖顯示位置和錨點:

此圖顯示位置和錨點

執行範例時,和 BorderWidthBorderColorPosition以動畫顯示,如下列螢幕快照所示:

執行範例時,Position、BorderWidth 和 BorderColor 動畫,如下所示

明確動畫

除了隱含動畫之外,Core Animation 還包含繼承自 CAAnimation 的各種類別,可讓您封裝然後明確新增至圖層的動畫。 這些允許更精細地控制動畫,例如修改動畫的起始值、將動畫分組,以及指定主要畫面格以允許非線性路徑。

下列程式代碼示範使用稍早所顯示圖層的 明確動畫 CAKeyframeAnimation 範例(在隱含動畫一節中):

public override void ViewDidAppear (bool animated)
{
  base.ViewDidAppear (animated);

  // get the initial value to start the animation from
  CGPoint fromPt = layer.Position;

  /* set the position to coincide with the final animation value
  to prevent it from snapping back to the starting position
  after the animation completes*/
  layer.Position = new CGPoint (200, 300);

  // create a path for the animation to follow
  CGPath path = new CGPath ();
  path.AddLines (new CGPoint[] { fromPt, new CGPoint (50, 300), new CGPoint (200, 50), new CGPoint (200, 300) });

  // create a keyframe animation for the position using the path
  CAKeyFrameAnimation animPosition = (CAKeyFrameAnimation)CAKeyFrameAnimation.FromKeyPath ("position");
  animPosition.Path = path;
  animPosition.Duration = 2;

  // add the animation to the layer.
  /* the "position" key is used to overwrite the implicit animation created
  when the layer positino is set above*/
  layer.AddAnimation (animPosition, "position");
}

此程式代碼會藉由建立用來定義主要畫面格動畫的路徑,來變更 Position 層次的 。 請注意,圖層的 Position 會從動畫中設定為 的最終值 Position 。 如果沒有這個,圖層會突然回到動畫之前, Position 因為動畫只會變更表示值,而不是實際模型值。 藉由將模型值設定為動畫的最終值,圖層會保留在動畫結尾。

下列螢幕快照顯示圖層,其中包含透過指定路徑產生動畫效果的影像:

此螢幕快照顯示圖層,其中包含透過指定路徑產生動畫效果的影像

摘要

在本文中,我們已探討透過 核心動畫架構所提供的動畫 功能。 我們檢查了 Core Animation,顯示它在 UIKit 中如何提供動畫功能,以及如何直接用於較低層級的動畫控件。