Saya memiliki aplikasi berbasis navigasi dan saya ingin mengubah animasi animasi push dan pop. Bagaimana saya melakukannya?
Edit 2018
Ada banyak jawaban untuk pertanyaan ini dan sudah cukup lama sekarang, saya telah memilih kembali jawaban untuk apa yang saya yakini sebagai yang paling relevan saat ini. Jika ada orang yang berpikir sebaliknya, beri tahu saya dalam komentar
ios
animation
uinavigationcontroller
Tusukan
sumber
sumber
Jawaban:
Untuk 2019, "jawaban akhir!"
Pembukaan:
Katakanlah Anda baru dalam pengembangan iOS. Yang membingungkan, Apple menyediakan dua transisi yang dapat digunakan dengan mudah. Ini adalah: "crossfade" dan "flip".
Tapi tentu saja, "crossfade" dan "flip" tidak berguna. Mereka tidak pernah digunakan. Tidak ada yang tahu mengapa Apple menyediakan dua transisi yang tidak berguna itu!
Begitu:
Katakanlah Anda ingin melakukan transisi yang biasa, umum, seperti "slide". Dalam hal ini, Anda harus melakukan sejumlah besar pekerjaan! .
Pekerjaan itu, dijelaskan dalam posting ini.
Hanya mengulangi:
Anehnya: dengan iOS, jika Anda menginginkan transisi sehari-hari yang paling sederhana, paling umum, (seperti slide biasa), Anda harus melakukan semua pekerjaan menerapkan transisi kustom penuh .
Inilah cara melakukannya ...
1. Anda perlu kebiasaan
UIViewControllerAnimatedTransitioning
Anda membutuhkan bool seperti Anda sendiri
popStyle
. (Apakah muncul, atau muncul?)Anda harus memasukkan
transitionDuration
(sepele) dan panggilan utama,animateTransition
Bahkan Anda harus menulis dua rutinitas yang berbeda untuk di dalamnya
animateTransition
. Satu untuk push, dan satu untuk pop. Mungkin nama merekaanimatePush
dananimatePop
. Di dalamanimateTransition
, cabang sajapopStyle
ke dua rutinitasContoh di bawah ini melakukan langkah sederhana / pindah
Dalam rutinitas
animatePush
dan AndaanimatePop
. Anda harus mendapatkan "dari tampilan" dan "untuk melihat". (Cara melakukannya, ditunjukkan dalam contoh kode.)dan Anda harus
addSubview
melihat "untuk" baru.dan Anda harus menelepon
completeTransition
di akhir anime AndaJadi ..
Lalu ...
2. Gunakan di pengontrol tampilan Anda.
Catatan: anehnya, Anda hanya perlu melakukan ini di pengontrol tampilan "pertama". (Yang "di bawah".)
Dengan yang Anda pop di atas , jangan lakukan apa pun . Mudah.
Jadi kelasmu ...
menjadi...
Itu dia.
Dorong dan pop persis seperti biasa, tidak ada perubahan. Untuk mendorong ...
dan untuk membuatnya, Anda dapat melakukannya jika ingin melakukannya di layar berikutnya:
Fiuh.
3. Juga nikmati jawaban lain di halaman ini yang menjelaskan cara mengganti AnimatedTransitioning
Gulir ke @AlanZeino dan @elias jawab untuk diskusi lebih lanjut tentang cara masuk
AnimatedTransitioning
di aplikasi iOS hari ini!sumber
animatePush
dananimatePop
.. dua arah yang berbeda!Saya melakukan yang berikut dan berfungsi dengan baik .. dan sederhana dan mudah dimengerti ..
Dan hal yang sama untuk mendorong ..
Versi Swift 3.0:
sumber
Animated:NO
bagian ini sangat penting. JikaYES
dilewatkan, animasi akan bercampur dan menimbulkan efek lucu.setViewControllers:
Beginilah cara saya selalu berhasil menyelesaikan tugas ini.
Untuk Push:
Untuk Pop:
Saya masih mendapatkan banyak umpan balik dari ini jadi saya akan melanjutkan dan memperbaruinya untuk menggunakan blok animasi yang merupakan cara yang disarankan Apple untuk melakukan animasi.
Untuk Push:
Untuk Pop:
sumber
super
denganself.navigationController
UIViewController
subclass nama tanpa bagian "ViewController". Nama ini lebih cocok untuk UIView.untuk mendorong
untuk pop
sumber
@Magnus menjawab, hanya untuk Swift (2.0)
Beberapa sidenotes:
Anda dapat melakukan ini juga dengan Segue, cukup laksanakan ini di
prepareForSegue
ataushouldPerformSegueWithIdentifier
. Namun , ini juga akan menyimpan animasi default di dalamnya. Untuk memperbaiki ini, Anda harus pergi ke storyboard, klik Segue, dan hapus centang pada kotak 'Animates'. Tapi ini akan membatasi aplikasi Anda untuk iOS 9.0 dan lebih tinggi (minimal ketika saya melakukannya di Xcode 7).Saat melakukan dalam segue, dua baris terakhir harus diganti dengan:
Meskipun saya salah, itu agak mengabaikannya.
sumber
Ingatlah bahwa di Swift , ekstensi pasti adalah teman Anda!
sumber
Menggunakan panggilan pribadi adalah ide yang buruk karena Apple tidak lagi menyetujui aplikasi yang melakukan itu. Mungkin Anda bisa mencoba ini:
sumber
-pushViewController:transition:forceImmediate:
yang akan menjadi ide yang buruk.Karena ini adalah hasil teratas di Google, saya pikir saya akan membagikan apa yang menurut saya cara paling waras; yang menggunakan API transisi iOS 7+. Saya menerapkan ini untuk iOS 10 dengan Swift 3.
Sangat mudah untuk menggabungkan ini dengan bagaimana
UINavigationController
menjiwai antara dua pengontrol tampilan jika Anda membuat subkelasUINavigationController
dan mengembalikan turunan kelas yang sesuai denganUIViewControllerAnimatedTransitioning
protokol.Sebagai contoh di sini adalah
UINavigationController
subclass saya :Anda dapat melihat bahwa saya mengaturnya
UINavigationControllerDelegate
sendiri, dan dalam ekstensi pada subkelas saya, saya menerapkan metodeUINavigationControllerDelegate
yang memungkinkan Anda mengembalikan pengontrol animasi khusus (yaitu,NavigationControllerAnimation
). Pengontrol animasi khusus ini akan menggantikan animasi stok untuk Anda.Anda mungkin bertanya-tanya mengapa saya melewatkan operasi ke
NavigationControllerAnimation
instance melalui inisialisasi. Saya melakukan ini sehingga dalamNavigationControllerAnimation
implementasiUIViewControllerAnimatedTransitioning
protokol saya tahu apa operasi itu (yaitu, 'push' atau 'pop'). Ini membantu untuk mengetahui jenis animasi apa yang harus saya lakukan. Sebagian besar waktu, Anda ingin melakukan animasi yang berbeda tergantung pada operasinya.Sisanya cukup standar. Terapkan dua fungsi yang diperlukan dalam
UIViewControllerAnimatedTransitioning
protokol dan hidupkan sesuka Anda:Penting untuk diingat, bahwa untuk setiap jenis operasi yang berbeda (yaitu, 'push' atau 'pop), pengontrol dari dan ke tampilan akan berbeda. Ketika Anda berada dalam operasi push, controller untuk melihat akan menjadi yang didorong. Saat Anda berada dalam operasi pop, to view controller akan menjadi salah satu yang sedang ditransisikan ke, dan controller dari view akan menjadi yang muncul.
Juga,
to
view controller harus ditambahkan sebagai subview daricontainerView
dalam konteks transisi.Ketika animasi Anda selesai, Anda harus menelepon
transitionContext.completeTransition(true)
. Jika Anda melakukan transisi interaktif, Anda harus mengembalikanBool
kecompleteTransition(didComplete: Bool)
, secara dinamis , tergantung pada apakah transisi selesai pada akhir animasi.Akhirnya ( bacaan opsional ), Anda mungkin ingin melihat bagaimana saya melakukan transisi yang sedang saya kerjakan. Kode ini sedikit lebih peretasan dan saya menulisnya dengan cepat sehingga saya tidak akan mengatakan itu kode animasi yang bagus tetapi masih menunjukkan bagaimana melakukan bagian animasi.
Milik saya adalah transisi yang sangat sederhana; Saya ingin meniru animasi yang sama dengan yang biasanya dilakukan UINavigationController, tetapi alih-alih animasi 'halaman berikutnya di atas', saya ingin menerapkan animasi 1: 1 dari pengontrol tampilan lama pada saat yang sama dengan tampilan baru pengontrol muncul. Ini memiliki efek membuat dua pengendali tampilan tampak seolah-olah mereka disematkan satu sama lain.
Untuk operasi push, yang pertama-tama mengharuskan pengaturan
toViewController
tampilan asal pada layar x-axis off, menambahkannya sebagai subview daricontainerView
, menggerakkannya ke layar dengan mengaturorigin.x
ke nol. Pada saat yang sama, saya menghidupkanfromViewController
tampilan itu denganorigin.x
mematikannya:Operasi pop pada dasarnya adalah kebalikannya. Tambahkan
toViewController
sebagai subview daricontainerView
, dan hidupkanfromViewController
ke kanan saat Anda menghidupkantoViewController
dari kiri:Inilah inti dengan seluruh file cepat:
https://gist.github.com/alanzeino/603293f9da5cd0b7f6b60dc20bc766be
sumber
Ada UINavigationControllerDelegate dan UIViewControllerAnimatedTransitioning di sana Anda dapat mengubah animasi untuk apa pun yang Anda inginkan.
Misalnya ini adalah animasi pop vertikal untuk VC:
}
Lalu
Tutorial yang berguna https://www.objc.io/issues/5-ios7/view-controller-transitions/
sumber
Berdasarkan jawaban yang diperbarui untuk swift 4
jordanperry
Untuk mendorong
UIViewController
Untuk Pop
sumber
Inilah cara saya melakukan hal yang sama di Swift:
Untuk Push:
Untuk Pop:
Saya sebenarnya melakukan ini sedikit berbeda dengan beberapa tanggapan di atas - tetapi karena saya baru dalam pengembangan Swift, itu mungkin tidak benar. Saya telah mengganti
viewWillDisappear:animated:
dan menambahkan kode pop di sana:sumber
@Luca Davanzo jawaban di Swift 4.2
sumber
Baru-baru ini saya mencoba melakukan hal serupa. Saya memutuskan saya tidak suka animasi geser dari UINavigationController, tetapi saya juga tidak ingin melakukan animasi yang UIView berikan kepada Anda seperti ikal atau semacamnya. Saya ingin melakukan cross fade antara pandangan ketika saya mendorong atau pop.
Masalah di sana melibatkan fakta bahwa tampilan secara harfiah menghapus tampilan atau muncul satu di atas yang sekarang, sehingga fade tidak berfungsi. Solusi yang saya datangi dengan melibatkan mengambil tampilan baru saya dan menambahkannya sebagai subview ke tampilan teratas saat ini pada tumpukan UIViewController's. Saya menambahkannya dengan alpha 0, lalu melakukan crossfade. Ketika urutan animasi selesai, saya mendorong tampilan ke tumpukan tanpa menggerakkannya. Saya kemudian kembali ke topView lama dan membersihkan hal-hal yang telah saya ubah.
Ini sedikit lebih rumit dari itu, karena Anda memiliki item navigasi Anda harus menyesuaikan untuk membuat transisi terlihat benar. Juga, jika Anda melakukan rotasi apa pun, Anda kemudian harus menyesuaikan ukuran bingkai saat Anda menambahkan tampilan sebagai subview sehingga mereka muncul dengan benar di layar. Ini beberapa kode yang saya gunakan. Saya subclassed UINavigationController dan mengalahkan metode push dan pop.
Seperti yang saya sebutkan dalam kode, saya selalu memiliki item tombol bilah kiri, jadi saya tidak memeriksa untuk melihat apakah nil sebelum memasukkannya ke dalam array yang saya berikan sebagai konteks untuk delegasi animasi. Jika Anda melakukan ini, Anda mungkin ingin melakukan pemeriksaan itu.
Masalah yang saya temukan adalah bahwa jika Anda crash sama sekali dalam metode delegasi, itu tidak akan crash program. Itu hanya menghentikan delegasi dari menyelesaikan tetapi Anda tidak mendapatkan peringatan apa pun.
Jadi karena saya melakukan pembersihan dalam rutinitas delegasi itu, itu menyebabkan beberapa perilaku visual yang aneh karena tidak menyelesaikan pembersihan.
Tombol kembali yang saya buat menyebut metode "goBack", dan metode itu hanya memanggil pop rutin.
Juga, inilah rutinitas pop saya.
Cukup banyak. Anda akan memerlukan beberapa kode tambahan jika Anda ingin menerapkan rotasi. Anda harus mengatur ukuran bingkai dari pandangan Anda yang Anda tambahkan sebagai subview sebelum Anda tunjukkan jika tidak Anda akan mengalami masalah orientasi adalah lansekap, tetapi terakhir kali Anda melihat tampilan sebelumnya itu potret. Jadi, kemudian Anda menambahkannya sebagai tampilan sub dan memudar di dalamnya tetapi muncul sebagai potret, lalu ketika kami muncul tanpa animasi, tampilan yang sama, tetapi yang ada di tumpukan, sekarang adalah lanskap. Semuanya terlihat sedikit funky. Implementasi rotasi setiap orang sedikit berbeda jadi saya tidak memasukkan kode saya untuk itu di sini.
Semoga ini bisa membantu beberapa orang. Saya sudah mencari-cari sesuatu seperti ini dan tidak dapat menemukan apa pun. Saya tidak berpikir ini adalah jawaban yang sempurna, tetapi ini bekerja sangat baik untuk saya pada saat ini.
sumber
Anda sekarang dapat menggunakan
UIView.transition
. Catat ituanimated:false
. Ini berfungsi dengan semua opsi transisi, pop, push, atau stack replace.sumber
Menggunakan jawaban iJordan sebagai inspirasi, mengapa tidak sekadar membuat Kategori di UINavigationController untuk digunakan di seluruh aplikasi Anda alih-alih menyalin / menempelkan kode animasi ini di semua tempat?
UINavigationController + Animation.h
UINavigationController + Animation.m
Kemudian cukup impor file UINavigationController + Animation.h dan panggil secara normal:
sumber
Ini sangat sederhana
sumber
Lihat ADTransitionController , setetes pengganti untuk UINavigationController dengan animasi transisi khusus (API-nya cocok dengan API UINavigationController) yang kami buat di Applidium.
Anda dapat menggunakan berbagai animasi yang telah ditentukan sebelumnya untuk aksi push dan pop seperti Swipe , Fade , Cube , Carrousel , Zoom dan sebagainya.
sumber
Walaupun semua jawaban di sini bagus dan sebagian besar berfungsi dengan sangat baik, ada metode yang sedikit lebih sederhana yang mencapai efek yang sama ...
Untuk Push:
Untuk Pop:
sumber
Saya tidak mengetahui cara apa pun untuk mengubah animasi transisi secara publik.
Jika tombol "kembali" tidak diperlukan, Anda harus menggunakan pengontrol tampilan modal untuk mendapatkan transisi "push from bottom" / "flip" / "fade" / (≥3.2) "page curl".
Di sisi pribadi , metode ini
-pushViewController:animated:
memanggil metode tidak berdokumen-pushViewController:transition:forceImmediate:
, jadi mis. Jika Anda menginginkan transisi flip-dari-kiri-ke-kanan, Anda dapat menggunakanAnda tidak dapat mengubah transisi "pop" dengan cara ini.
sumber
Lihat jawaban saya untuk pertanyaan ini untuk cara melakukannya dalam baris kode yang jauh lebih sedikit. Metode ini memungkinkan Anda untuk menghidupkan "Push" pseudo- dari pengontrol tampilan baru dengan cara apa pun yang Anda suka, dan ketika animasi selesai ia mengatur Pengontrol Navigasi seperti jika Anda telah menggunakan metode Push standar. Contoh saya memungkinkan Anda menggerakkan slide-in dari kiri atau dari kanan. Kode diulangi di sini untuk kenyamanan:
sumber
Dari aplikasi sampel, periksa variasi ini. https://github.com/mpospese/MPFoldTransition/
sumber
Cukup gunakan:
sumber
Menyadari ini adalah pertanyaan lama. Saya masih ingin memposting jawaban ini, karena saya memiliki beberapa masalah muncul
viewControllers
dengan jawaban yang diajukan. Solusi saya adalah dengan subkelasUINavigationController
dan mengganti semua metode pop dan push.FlippingNavigationController.h
FlippingNavigationController.m:
sumber
Saya tahu utas ini sudah tua, tetapi saya pikir saya akan memasukkan dua sen saya. Anda tidak perlu membuat animasi khusus, ada cara sederhana (mungkin gila) untuk melakukannya. Alih-alih menggunakan push, buat pengontrol navigasi baru, buat pengontrol tampilan baru pengontrol tampilan akar pengontrol nav itu, dan kemudian sajikan pengontrol nav dari pengontrol nav asli. Present mudah disesuaikan dengan banyak gaya, dan tidak perlu membuat animasi kustom.
Sebagai contoh:
Dan Anda dapat mengubah gaya presentasi sesuai keinginan Anda.
sumber
Saya menemukan cara rekursif ringan untuk melakukan ini yang berfungsi untuk tujuan saya. Saya memiliki variabel instan BOOL yang saya gunakan untuk memblokir animasi popping normal dan mengganti pesan pop non-animasi saya sendiri. Variabel awalnya diatur ke NO. Ketika tombol kembali ditekan, metode delegasi menetapkannya ke YES dan mengirim pesan pop non-animasi baru ke bilah navigasi, sehingga memanggil metode delegasi yang sama lagi, kali ini dengan variabel yang disetel ke YES. Dengan variabel disetel ke YA, metode delegasi menetapkannya ke TIDAK dan mengembalikan YA untuk memungkinkan pop non-animasi terjadi. Setelah panggilan delegasi kedua kembali, kami kembali ke yang pertama, di mana NO dikembalikan, memblokir pop animasi asli! Ini sebenarnya tidak berantakan seperti kedengarannya. Metode shouldPopItem saya terlihat seperti ini:
Bekerja untukku.
sumber