Podstawowa animacja na platformie Xamarin.iOS

W tym artykule opisano strukturę Core Animation, pokazującą, jak umożliwia wysoką wydajność, animacje płynów w zestawie UIKit, a także sposób używania go bezpośrednio do sterowania animacjami niższego poziomu.

System iOS zawiera animację Core Animation w celu zapewnienia obsługi animacji dla widoków w aplikacji. Wszystkie ultraładne animacje w systemie iOS, takie jak przewijanie tabel i przesuwanie między różnymi widokami, działają, jak również działają, ponieważ polegają wewnętrznie na animacji podstawowej.

Podstawowe struktury animacji i grafiki core mogą współpracować, aby tworzyć piękne, animowane grafiki 2D. W rzeczywistości Core Animation może nawet przekształcić grafikę 2D w przestrzeni 3D, tworząc niesamowite, kinowe doświadczenia. Jednak aby utworzyć prawdziwą grafikę 3D, należy użyć czegoś takiego jak OpenGL ES lub w przypadku gier włączyć interfejs API, taki jak MonoGame, chociaż 3D wykracza poza zakres tego artykułu.

Podstawowe funkcje animacji

System iOS używa platformy Core Animation do tworzenia efektów animacji, takich jak przechodzenie między widokami, przesuwane menu i efekty przewijania, aby wymienić kilka. Istnieją dwa sposoby pracy z animacją:

Korzystanie z animacji UIKit

Zestaw UIKit udostępnia kilka funkcji, które ułatwiają dodawanie animacji do aplikacji. Mimo że używa ona animacji core wewnętrznie, abstrahuje od niej, aby pracować tylko z widokami i kontrolerami.

W tej sekcji omówiono funkcje animacji UIKit, w tym:

  • Przejścia między kontrolerami
  • Przejścia między widokami
  • Wyświetlanie animacji właściwości

Przejścia kontrolera widoku

UIViewController Zapewnia wbudowaną obsługę przechodzenia między kontrolerami widoku za pomocą PresentViewController metody . W przypadku korzystania z PresentViewControllerprogramu przejście do drugiego kontrolera można opcjonalnie animować.

Rozważmy na przykład aplikację z dwoma kontrolerami, gdzie dotknięcie przycisku w pierwszym kontrolerze wywołuje PresentViewController w celu wyświetlenia drugiego kontrolera. Aby kontrolować, jaka animacja przejścia jest używana do wyświetlania drugiego kontrolera, po prostu ustaw jego ModalTransitionStyle właściwość, jak pokazano poniżej:

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

W takim przypadku jest używana animacja PartialCurl , chociaż dostępnych jest kilka innych, w tym:

  • CoverVertical — Przesuwa się w górę z dołu ekranu
  • CrossDissolve - Stary widok zanika i nowy widok zanika w
  • FlipHorizontal - Pozioma odrzuć od prawej do lewej. Po odrzuceniu przejście przerzuca lewą do prawej.

Aby animować przejście, przekaż true jako drugi argument do PresentViewControllerelementu :

PresentViewController (vc2, true, null);

Poniższy zrzut ekranu przedstawia, jak wygląda przejście w przypadku:PartialCurl

This screenshot shows the PartialCurl transition

Wyświetlanie przejść

Oprócz przejść między kontrolerami zestaw UIKit obsługuje również animowanie przejść między widokami, aby zamienić jeden widok na inny.

Załóżmy na przykład, że masz kontroler z elementem UIImageView, gdzie naciśnięcie obrazu powinno wyświetlić drugą UIImageViewwartość . Aby animować widok superwyświetlania widoku obrazu w celu przejścia do drugiego widoku obrazu, jest tak proste, jak wywoływanie UIView.Transitionmetody , przekazywanie go do toView elementu i fromView , jak pokazano poniżej:

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

UIView.Transition Przyjmuje duration również parametr, który kontroluje czas uruchomienia animacji, a także options określa elementy, takie jak animacja do użycia i funkcja easing. Ponadto można określić procedurę obsługi uzupełniania, która zostanie wywołana po zakończeniu animacji.

Poniższy zrzut ekranu przedstawia animowane przejście między widokami obrazów w przypadku TransitionFlipFromTop użycia:

This screenshot shows the animated transition between the image views when TransitionFlipFromTop is used

Wyświetlanie animacji właściwości

Zestaw UIKit obsługuje animowanie różnych właściwości w UIView klasie bezpłatnie, w tym:

  • Ramka
  • Granice
  • Wyśrodkuj
  • Wersja alfa
  • Przekształcanie
  • Color

Te animacje są wykonywane niejawnie przez określenie zmian właściwości w NSAction delegacie przekazanym do metody statycznej UIView.Animate . Na przykład poniższy kod animuje punkt środkowy elementu 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; }
);

Powoduje to animowanie obrazu w górnej części ekranu, jak pokazano poniżej:

An image animating back and forth across the top of the screen as the output

Podobnie jak w przypadku Transition metody, Animate umożliwia ustawienie czasu trwania wraz z funkcją easing. W tym przykładzie użyto UIViewAnimationOptions.Autoreverse również opcji, która powoduje, że animacja animuje się z wartości z powrotem do początkowej. Jednak kod ustawia Center również z powrotem wartość początkową w procedurze obsługi uzupełniania. Podczas gdy animacja interpoluje wartości właściwości w czasie, rzeczywista wartość modelu właściwości jest zawsze ostateczną wartością, która została ustawiona. W tym przykładzie wartość jest punktem w pobliżu prawej strony superoglądu. Bez ustawienia Center wartości na początkowy punkt, w którym animacja zostanie ukończona z powodu Autoreverse ustawienia, obraz zostanie przyciągnięty z powrotem do prawej strony po zakończeniu animacji, jak pokazano poniżej:

Without setting the Center to the initial point, the image would snap back to the right side after the animation completes

Korzystanie z animacji podstawowej

UIView animacje umożliwiają wiele możliwości i powinny być używane, jeśli to możliwe ze względu na łatwość implementacji. Jak wspomniano wcześniej, animacje UIView używają platformy Core Animation. Nie można jednak wykonać niektórych czynności z UIView animacjami, takimi jak animowanie dodatkowych właściwości, których nie można animować za pomocą widoku animowania, ani interpolacji wzdłuż ścieżki nieliniowej. W takich przypadkach, w których potrzebujesz bardziej precyzyjnej kontrolki, animacja Core może być również używana bezpośrednio.

Warstwy

Podczas pracy z animacją core animacja odbywa się za pośrednictwem warstw, które są typu CALayer. Warstwa jest koncepcyjnie podobna do widoku, w przypadku którego istnieje hierarchia warstw, podobnie jak w przypadku hierarchii widoków. W rzeczywistości warstwy widoków wstecznych z widokiem dodającym obsługę interakcji użytkownika. Dostęp do warstwy dowolnego widoku można uzyskać za pośrednictwem właściwości widoku Layer . W rzeczywistości kontekst używany w Draw metodzie UIView metody jest faktycznie tworzony na podstawie warstwy. Wewnętrznie warstwa wspierana przez UIView element ma swój delegat ustawiony na widok, który wywołuje metodę Draw. Dlatego podczas rysowania na element UIView, faktycznie rysujesz na jej warstwie.

Animacje warstw mogą być niejawne lub jawne. Niejawne animacje są deklaratywne. Wystarczy zadeklarować, jakie właściwości warstwy powinny ulec zmianie, a animacja działa. Z drugiej strony jawne animacje są tworzone za pośrednictwem klasy animacji dodawanej do warstwy. Jawne animacje umożliwiają dodawanie kontroli nad sposobem tworzenia animacji. Poniższe sekcje zagłębiają się w niejawne i jawne animacje w bardziej szczegółowy sposób.

Animacje niejawne

Jednym ze sposobów animowania właściwości warstwy jest niejawna animacja. UIView animacje tworzą niejawne animacje. Można jednak tworzyć niejawne animacje bezpośrednio względem warstwy.

Na przykład poniższy kod ustawia warstwę Contents na podstawie obrazu, ustawia szerokość i kolor obramowania i dodaje warstwę jako podwarstwową warstwy widoku:

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

Aby dodać niejawną animację dla warstwy, po prostu zawijaj zmiany właściwości w obiekcie CATransaction. Umożliwia to animowanie właściwości, które nie byłyby animatowalne z animacją widoku, taką jak i BorderWidthBorderColor , jak pokazano poniżej:

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

Ten kod animuje również warstwę Position, która jest lokalizacją punktu kotwicy warstwy mierzonego od lewej górnej części współrzędnych superwarstwowych. Punkt zakotwiczenia warstwy jest znormalizowanym punktem w układzie współrzędnych warstwy.

Na poniższej ilustracji przedstawiono położenie i punkt zakotwiczenia:

This figure shows the position and anchor point

Po uruchomieniu przykładu PositionBorderWidth element i BorderColor animowanie go, jak pokazano na poniższych zrzutach ekranu:

When the example is run, the Position, BorderWidth and BorderColor animate as shown

Animacje jawne

Oprócz niejawnych animacji, animacja Core zawiera różne klasy dziedziczone z CAAnimation tej funkcji, które pozwalają hermetyzować animacje, które następnie są jawnie dodawane do warstwy. Umożliwiają one bardziej szczegółową kontrolę nad animacjami, taką jak modyfikowanie wartości początkowej animacji, grupowanie animacji i określanie ramek kluczowych w celu zezwolenia na ścieżki nieliniowe.

Poniższy kod przedstawia przykład jawnej animacji przy użyciu CAKeyframeAnimation elementu dla warstwy pokazanej wcześniej (w sekcji Niejawna animacja):

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

Ten kod zmienia Position warstwę, tworząc ścieżkę, która jest następnie używana do definiowania animacji ramki kluczy. Zwróć uwagę, że warstwa Position jest ustawiona na wartość końcową Position z animacji. Bez tego warstwa nagle powróci do jej Position przed animacją, ponieważ animacja zmienia tylko wartość prezentacji, a nie rzeczywistą wartość modelu. Ustawiając wartość modelu na wartość końcową z animacji, warstwa pozostanie na końcu animacji.

Na poniższych zrzutach ekranu przedstawiono warstwę zawierającą obraz animujący przez określoną ścieżkę:

This screenshot shows the layer containing the image animating through the specified path

Podsumowanie

W tym artykule przyjrzeliśmy się możliwościom animacji udostępnianym za pośrednictwem platform animacji Core. Zbadaliśmy animację core, przedstawiającą zarówno sposób, w jaki obsługuje animacje w zestawie UIKit, jak i jak można go używać bezpośrednio do kontroli animacji niższego poziomu.