WhatsApp-szerű animációk készítése iOS-ban

Hogyan hozzunk létre folyékony és következetes UITabBar és UIToolBar animációt, mint például a WhatsApp alkalmazásban.

A WhatsApp átállása egy UITabBar-ról UIToolBar-ra.Minta végrehajtása.

Azóta, hogy elkezdtem fejleszteni az iOS-alkalmazásokat, nagyobb figyelmet szenteltem annak, hogy más rendkívül sikeres alkalmazások hogyan valósítják meg az UI-átmeneteket, hogy ezeket a sajátjaimban is megvalósítsam.

Nemrég fejlesztettem ki egy alkalmazást, amelynek UICollectionView beágyazva volt egy UIViewControllerbe, amelyet viszont beágyaztam egy UICollectionViewControllerbe, és el akartam rejteni a képernyő alján található fülsávot, hogy szerkesztési módban megjelenítsen egy eszközsávot. .

A kérdéses nézethierarchia.

Az egyik alkalmazás, amelyet a legjobban használom, a WhatsApp, de eddig még nem próbáltam boncolni, hogyan kezeli az UI átmeneteit. Észrevettem, hogy az UIToolBar átalakulásának és helyzetének kezelése a képernyő alján szerkesztési módban tökéletesen megfelel annak, amit megvalósítani akartam.

Ebben a cikkben megmutatom, hogyan implementáltam az alkalmazásban, és elmagyarázom a tervezési döntéseimet. Kiderült, hogy a fentiek végrehajtása nem triviális, és időbe telt, hogy kitaláljam. Meg kellett írni egyéni kódot, és túl sok próba és hiba történt. Ezért remélem, hogy ez a cikk és a mintaprojekt megkönnyíti az életed, ha ugyanazt akarod megvalósítani.

Elemzés

Először ellenőriznünk kell, hogy a WhatsApp hogyan csinál dolgokat:

A WhatsApp animációja eredeti sebességének 10% -ára lelassult.

Amit tudok mondani, a WhatsApp elhalványítja az UITabBar-t be vagy ki, és ezzel egyidejűleg mozgatja az UIToolBar-t felfelé vagy lefelé, a szerkesztési módtól függően.

Ezért cselekvési tervünk az, hogy pontosan ezt tegyük meg.

Tervezés

Ezek a mi követelményeink:

  • Engedélyeznünk kell az UINavigationBar számára az iOS 11 nagy címeinek használatát
  • El kell rejtenünk az UIToolBar-t, amikor nem használják
  • Ugyanezt kellene tennünk az UITabBar-ra is

Támadás

Itt voltam teljesen téves. Úgy gondoltam, hogy a fentiekben tárgyalt megvalósítás egy darab tortát jelentett volna, de kiderült, hogy rendkívül összetett.

Miért?

Kiderül, hogy az alapértelmezett animáció és rendszer használata nagy címekhez csavarja fel az egyszerű helymeghatározási kódot, amelyet írhat az UIToolBar számára.

A naiv megközelítés

Az első dolog, amit megpróbáltam, az volt, hogy használtam az UINavigationController alapértelmezett UIToolBar-ját, és megváltoztattam a helyzetét az alkalmazás szerkesztési állapota szerint.

Amint azt már fentebb mondtam, ez nem igazán működik, ha nagy címeket használ.

Figyelje meg, hogy az UIToolBar hogyan mozog, ha a nagy címet animálják.

Ráadásul rájöttem, hogy manuálisan át kell méreteznem a gyűjtemény nézet határainak tulajdonságát, ha azt akarom, hogy az átfedje az UIToolBar és az UITabBar közötti teljes teret.

A megoldás

Annak érdekében, hogy ezt megkerüljük, manuálisan kell hozzáadnunk egy UIToolBar eszközt, ahelyett, hogy az alapértelmezett objektumot használnánk, amelyet a nézetvezérlőhöz társított UINavigationController objektum biztosít.

Először lustán készítjük:

privát lusta var eszköztár: UIToolbar = {return UIToolbar ()} ()

majd állítsa be a kényszereket a viewDidLoad alkalmazásban:

private var toolBarConstraints = [NSLayoutConstraint] ()
...
felülbírálja a func viewDidLoad () {super.viewDidLoad () ... navBar.prefersLargeTitles = valódi navigációs vezérlőt! : self.view.leftAnchor); ])}

Ezután létrehozunk néhány kiszámított tulajdonságot, amelyeket a minta nézet-vezérlőben használunk az egyedi UIToolBar helyes beállításához:

private var screenHeight: CGFloat {return UIScreen.main.bounds.height} private varBarYPos: CGFloat {if currentState == .normal {return screenHeight} // Ideális esetben ellenőrizze, hogy vannak-e más államok itt, de mivel csak kettőnk van, akkor tartsuk meg / / egyszerű; megtenne valami hasonlót: egyébként, ha az currentState == .edit {else {return screenHeight - toolBar.frame.height}}

Végül ezeket a kiszámított tulajdonságokat használjuk az UIToolBar és / vagy az UITabBar helyes helyzetbe helyezésére bizonyos esetekben. Tehát amikor a felhasználó megérinti a Szerkesztés vagy a Kész gombot:

Az animáció, amit akartunk.

és ezt (részben, de leginkább) ezzel a kóddal érjük el:

@IBAction func onEditBtnTouchUp (_ küldő: Bármelyik) {// Váltás szerkesztési módra, ha currentState == .normal {currentState = .edit fade (tabBar, toAlpha: 0, withDuration: 0.2, andHide: true) UIView.animate (withDuration : 0,2, animációk: {// Szerkesztés beállítása kész self.navigationItem.leftBarButtonItem = UIBarButtonItem (barButtonSystemItem: .done, target: self, action: #selector (self.onDoneBtnTouchUp)) // Elhalványulás + btn self.plusBtn.isEnabled = hamis self.plusBtn.tintColor = UIColor.clear // Helyezze az eszköztárat self.toolBar.frame.origin.y = self.toolBarYPos})}}} @objc func onDoneBtnTouchUp (_ küldő: Bármelyik) {// Váltás normál állapotba if currentState == .edit {currentState = .normal fade (tabBar, toAlpha: 1, withDuration: 0.2, andHide: false) UIView.animate (withDuration: 0.2, animációk: {// A szerkesztés beállítása kész self.navigationItem.leftBarButtonItem = UIBarButtonItem (barButtonSystemItem: .edit, target: self, action: #selector (self.onEditBtnTouchUp)) // Fade in + btn self.plusBtn.isEnabled = true s elf.plusBtn.tintColor = nulla // Helyezze az eszköztárat self.toolBar.frame.origin.y = self.toolBarYPos})}

Következtetések

A végeredménynek így kell kinéznie:

Beállítottam egy tárolót a mintaprojekttel, hogy el tudja olvasni a teljes kódot:

Azt javaslom, hogy ellenőrizze, mivel szándékosan hiányoztam a cikk néhány részletét a rövidség kedvéért.

Hosszú időbe telt, hogy ezt kitaláljam, mert a különböző UIKit elemek közötti kölcsönhatás nem működött a vártnak megfelelően.

Az iOS rendszeren a Swiftnél fejlettebb felhasználói felület-interakciók fejlesztésekor a fő elvihetőségek:

  1. Először próbálja ki a legegyszerűbb megoldást; ha ez működik, jó!
  2. Ha nem, próbálkozzon újakkal és kísérletezzen.
  3. Nagyon frusztráló lehet, de ne add fel!

Ha tetszik ez a fajta cucc, kövess engem a Twitteren: twitter.com/albtaiuti

Ennek a bejegyzésnek a stílusát részben Nathan Gitter Közepes hozzászólásai ihlette, és néhány kódot is használtam. Köszönjük, hogy megosztotta velünk, Nathan!

Kövess minket a közösségi média platformon: Facebook: facebook.com/AppCodamobile/ Twitter: twitter.com/AppCodaMobile Instagram: instagram.com/AppCodadotcom

Ha tetszett ez a cikk, kérjük, kattintson a gombra, és ossza meg, hogy mások megtalálják! Nyugodtan hagyjon megjegyzést alább.