Xamarin.iOS 中的核心動畫
本文會檢查 Core Animation 架構,示範如何在 UIKit 中啟用高效能、流暢的動畫,以及如何將其直接用於較低層級的動畫控件。
iOS 包含 核心動畫 ,可為應用程式中的檢視提供動畫支援。 iOS 中的所有超平滑動畫,例如數據表卷動,並在不同的檢視之間撥動執行,以及它們執行,因為它們在內部依賴核心動畫。
核心動畫和核心圖形架構可以共同建立美觀的動畫 2D 圖形。 事實上,核心動畫甚至可以在 3D 空間中轉換 2D 圖形,創造驚人的電影體驗。 不過,若要建立真正的 3D 圖形,您必須使用 OpenGL ES 之類的專案,或讓遊戲轉向 MonoGame 之類的 API,雖然 3D 超出本文的範圍。
Core Animation
iOS 使用核心動畫架構來建立動畫效果,例如在檢視、滑動功能表和卷動效果之間轉換,以命名幾個。 有兩種方式可以處理動畫:
使用UIKit動畫
UIKit 提供數個功能,可讓您輕鬆地將動畫新增至應用程式。 雖然它在內部使用 Core Animation,但它會將其抽象化,因此您只能使用檢視和控制器。
本節討論 UIKit 動畫功能,包括:
- 控制器之間的轉換
- 在檢視之間轉換
- 檢視屬性動畫
檢視控制器轉換
UIViewController
提供透過 PresentViewController
方法在檢視控制器之間轉換的內建支援。 使用 PresentViewController
時,轉換至第二個控制器可以選擇性地產生動畫效果。
例如,假設有兩個控制器的應用程式,其中觸控第一個控制器中的按鈕會呼叫 PresentViewController
以顯示第二個控制器。 若要控制用來顯示第二個控制器的轉換動畫,只要設定其 ModalTransitionStyle
屬性,如下所示:
SecondViewController vc2 = new SecondViewController {
ModalTransitionStyle = UIModalTransitionStyle.PartialCurl
};
在此情況下 PartialCurl
,會使用動畫,但有數個其他動畫可供使用,包括:
CoverVertical
– 從螢幕底部向上投影片CrossDissolve
– 舊檢視淡出 , 新檢視淡入FlipHorizontal
- 水平由右至左翻轉。 關閉時,轉換會由左至右翻轉。
若要讓轉換產生動畫效果,請將 作為第二個自變數傳遞 true
至 PresentViewController
:
PresentViewController (vc2, true, null);
下列螢幕快照顯示案例的轉換外觀 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
影像檢視之間的動畫轉換:
檢視屬性動畫
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
,這是從超層座標左上方測量的圖層錨點位置。 圖層的錨點是圖層座標系統中的標準化點。
下圖顯示位置和錨點:
執行範例時,和 BorderWidth
BorderColor
會Position
以動畫顯示,如下列螢幕快照所示:
明確動畫
除了隱含動畫之外,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 中如何提供動畫功能,以及如何直接用於較低層級的動畫控件。