Saya punya satu masalah dan saya telah menjelaskannya di bawah ini.
Saya menggunakan UIViewControllerContextTransitioning
untuk transisi khusus.
Saya memiliki 2 pengontrol tampilan, pengontrol tampilan pertama dan pengontrol tampilan kedua.
Sekarang saya ingin menambahkan pengontrol tampilan kedua pada pengontrol tampilan pertama dengan animasi. Saya telah mencapainya, sekarang pengontrol tampilan kedua transparan, jadi kita bisa melihat pengontrol tampilan pertama di bawah pengontrol tampilan kedua.
Tetapi saya tidak dapat melihat pengontrol tampilan pertama, dan saya hanya dapat melihat layar hitam di bawah pengontrol tampilan kedua.
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
self.transitionContext = transitionContext;
if(self.isPresenting){
[self executePresentationAnimation:transitionContext];
}
else{
[self executeDismissalAnimation:transitionContext];
}
}
-(void)executePresentationAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
UIView* inView = [transitionContext containerView];
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
CGRect offScreenFrame = inView.frame;
offScreenFrame.origin.y = inView.frame.size.height;
toViewController.view.frame = offScreenFrame;
toViewController.view.backgroundColor = [UIColor clearColor];
fromViewController.view.backgroundColor = [UIColor clearColor];
inView.backgroundColor = [UIColor clearColor];
[inView insertSubview:toViewController.view aboveSubview:fromViewController.view];
// [inView addSubview:toViewController.view];
CFTimeInterval duration = self.presentationDuration;
CFTimeInterval halfDuration = duration/2;
CATransform3D t1 = [self firstTransform];
CATransform3D t2 = [self secondTransformWithView:fromViewController.view];
[UIView animateKeyframesWithDuration:halfDuration delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:0.5f animations:^{
fromViewController.view.layer.transform = t1;
}];
[UIView addKeyframeWithRelativeStartTime:0.5f relativeDuration:0.5f animations:^{
fromViewController.view.layer.transform = t2;
}];
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:duration delay:(halfDuration - (0.3*halfDuration)) usingSpringWithDamping:0.7f initialSpringVelocity:6.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
toViewController.view.frame = inView.frame;
} completion:^(BOOL finished) {
[self.transitionContext completeTransition:YES];
}];
}
Saat [self.transitionContext completeTransition:YES];
dipanggil, tiba-tiba pengontrol tampilan pertama menghilang dan layar hitam ditampilkan di bawah pengontrol tampilan kedua.
Apakah ada yang punya ide? Terima kasih.
sumber
modalPresentationStyle = UIModalPresentationFullScreen
. Anda tentu saja masih mendapatkan animasi transisi kustom Anda.Saya merasa alasan di balik ini harus dijelaskan dengan lebih baik.
Tampilan tersebut menghilang karena Anda mengeluarkan tampilan pengontrol tampilan penyajian dari lokasi aslinya (hierarki tampilan), meletakkannya di dalam containerView yang disediakan oleh animator Anda tetapi tidak pernah mengembalikannya setelah animasi selesai. Sehingga tampilan pengontrol tampilan dihapus dengan superview (containerView) dari jendela sepenuhnya.
Di iOS 7, sistem selalu mengembalikan tampilan pengontrol tampilan yang terlibat dalam presentasi (menyajikan dan disajikan) ke tempat aslinya setelah transisi selesai dianimasikan secara otomatis. Itu tidak lagi terjadi untuk beberapa gaya presentasi di iOS 8.
Aturannya sangat sederhana: animator hanya boleh memanipulasi tampilan pengontrol tampilan penyajian jika tampilan pengontrol tampilan tersebut akan disembunyikan (dihapus dari hierarki tampilan) sepenuhnya pada akhir transisi . Dengan kata lain, ini berarti bahwa setelah animasi presentasi awal selesai, hanya tampilan pengontrol tampilan yang disajikan yang akan terlihat, bukan tampilan pengontrol tampilan yang menyajikan. Misalnya, jika Anda menyetel opasitas tampilan pengontrol tampilan yang disajikan menjadi 50% dan menggunakan UIModalPresentationFullScreen, Anda tidak akan dapat melihat tampilan pengontrol tampilan di bawah yang disajikan, tetapi jika Anda menggunakan UIModalPresentationOverFullscreen - Anda akan melakukannya (
shouldRemovePresentersView
metode UIPresentationController bertanggung jawab untuk menentukannya).Mengapa tidak mengizinkan animator memanipulasi tampilan pengontrol tampilan presentasi setiap saat? Pertama-tama, jika tampilan pengontrol tampilan penyajian akan tetap terlihat setelah animasi selesai selama seluruh siklus hidup presentasi, tidak perlu menganimasikannya sama sekali - itu hanya tetap di tempatnya. Kedua, jika kepemilikan untuk pengontrol tampilan tersebut ditransfer ke pengontrol presentasi, pengontrol presentasi kemungkinan besar tidak akan tahu bagaimana menata letak tampilan pengontrol tampilan tersebut saat diperlukan misalnya ketika orientasi berubah, tetapi pemilik asli dari pengontrol tampilan yang menyajikan tidak .
Di iOS 8
viewForKey:
metode diperkenalkan untuk mendapatkan tampilan yang dimanipulasi oleh animator. Pertama, ada baiknya untuk mengikuti aturan yang dijelaskan di atas dengan mengembalikan nol setiap kali animator tidak boleh menyentuh tampilan. Kedua, ini mungkin mengembalikan tampilan berbeda untuk animator untuk dianimasikan. Bayangkan Anda sedang melaksanakan presentasi yang mirip dengan lembar formulir. Dalam hal ini Anda ingin menambahkan bayangan atau hiasan di sekitar tampilan pengontrol tampilan yang disajikan. Animator akan menganimasikan dekorasi itu dan tampilan pengontrol tampilan yang disajikan akan menjadi turunan dari dekorasi.viewControllerForKey:
tidak hilang, ini masih dapat digunakan jika akses langsung ke pengontrol tampilan diperlukan tetapi animator tidak boleh membuat asumsi apa pun tentang tampilan yang diperlukan untuk dianimasikan.Ada beberapa hal yang dapat Anda lakukan untuk benar memperbaiki masalah dengan pandangan menghilang menyajikan controller tampilan ketika Anda secara eksplisit menempatkannya dalam pandangan wadah animator ini:
Jika tidak perlu menganimasikan tampilan pengontrol tampilan penyajian, gunakan
viewForKey:
agar tampilan dianimasikan daripada menjangkau tampilan pengontrol secara langsung.viewForKey:
dapat mengembalikan pandangan nihil atau bahkan sama sekali berbeda.Jika Anda ingin menganimasikan tampilan pengontrol tampilan penyajian, Anda harus mempertimbangkan untuk menggunakan
UIModalPresentationFullScreen
gaya atau terus menggunakanUIModalPresentationCustom
dan mengimplementasikan subkelas UIPresentationController Anda sendiri denganshouldRemovePresentersView
mengembalikanYES
. Faktanya, penerapan metode ini adalah perbedaan utama antara pengontrol presentasi internal yang ditentukan olehUIModalPresentationFullScreen
danUIModalPresentationCustom
gaya terlepas dari fakta bahwa yang terakhir memungkinkan Anda untuk menggunakan pengontrol presentasi kustom.Dalam semua kasus yang jarang terjadi, Anda harus mengembalikan tampilan pengontrol tampilan penyajian ke lokasi aslinya seperti yang disarankan jawaban lain.
sumber
viewControllerForKey:
'sview
s hanya ketikaviewForKey:
kembali nil, dan saya masih harus menambahkannya kembali ke jendela secara manual. Apakah Anda memiliki contoh kode yang berfungsi tanpa solusi ini?viewForKey:
mengembalikan nihil maka pasti Anda harus menambahkan kembali tampilan pengontrol tampilan presentasi ke jendela jika Anda menghapusnya di animator Anda. Jika viewForKey mengembalikan tampilan pengontrol tampilan sebenarnya, aman untuk memindahkan tampilan itu karena UIKit akan memindahkannya kembali ke posisi semula setelah siklus hidup presentasi selesai.Di iOS 8, Anda harus memanipulasi tampilan yang dikembalikan oleh
viewForKey:
alih-alih.view
properti pengontrol tampilan yang dikembalikan olehviewControllerForKey:
. Ini tidak terlalu jelas dari dokumentasi beta, tetapi jika Anda melihat sumber untuk UIViewControllerTransitioning.h Anda akan melihat komentar ini di atasviewControllerForKey:
:Jadi, alih-alih menyesuaikan bingkai, dll.
toViewController.view
, Gunakan nilai kembalian[transitionContext viewForKey:UITransitionContextToViewKey]
.Jika aplikasi Anda perlu mendukung iOS7 dan / atau Xcode 5, Anda dapat menggunakan metode kategori sederhana di UIViewController seperti berikut:
Kemudian, dapatkan milik Anda
toViewController
danfromViewController
seperti biasa, tetapi dapatkan tampilan menggunakan[toViewController viewForTransitionContext:transitionContext]
.Sunting: Tampaknya ada bug, di mana tampilan pengontrol tampilan penyajian adalah nol saat dikembalikan dari
viewForKey
, yang mencegah Anda membuat transisi modal yang menganimasikan tampilan penyajian sama sekali (seperti menggeser off, atau membalik-horizontal). Saya melaporkan bug untuk iOS8 di rdar: // 17961976 ( http://openradar.appspot.com/radar?id=5210815787433984 ). Lihat juga proyek sampel di http://github.com/bcherry/TransitionBugSunting 2: Terima kasih kepada graveley atas sarannya, menggunakan UIModalPresentationFullScreen memperbaiki masalah. Mungkin ini bukan bug. Apple mungkin bermaksud agar UIModalPresentationCustom hanya mengubah tampilan modal masuk. Jika Anda ingin mengubah tampilan keluar, Anda perlu menjamin presentasi layar penuh dari tampilan baru? Bagaimanapun, Anda harus menggunakan
viewForKey
dan UIModalPresentationFullScreen.sumber
manipulating
pandangan VC atau tidak ...viewForKey
bug di GM juga. Apakah orang lain juga? Sudahkah Anda menemukan solusi yang masuk akal untuk itu?- viewForKey
// viewForKey: mungkin mengembalikan nihil yang akan menunjukkan bahwa animator tidak boleh memanipulasi tampilan pengontrol tampilan terkait. Kembalinil
bukanlah bug.viewForKey
mengembalikan tampilan dari dan ke tampilan. Jadi mungkin disengaja ia mengembalikan nihil untuk UIModalPresentationCustom. Saya memperbarui laporan bug saya dan akan memposting kembali di sini jika saya mendapat kabar dari Apple tentang hal itu.Tidak menyetel
modalPresentationStyle
ke UIModalPresentationCustom memperbaiki masalah saya.Dengan kata lain, tetap menggunakan default UIModalPresentationFullScreen alih-alih menentukan UIModalPresentationCustom memperbaiki masalah tampilan menghilang. Perhatikan bahwa protokol UIViewControllerTransitioningDelegate tampaknya masih diikuti bahkan ketika membiarkannya di default. Jika saya ingat dengan benar, sekali waktu UIModalPresentationCustom adalah persyaratan.
Bekerja sejauh ini, hanya mencoba ini untuk animasi non-interaktif.
sumber
viewForKey:
bukannya.view
padaviewControllerForKey:
perbaikan semua masalah bagi saya.Saya telah menemukan jawaban yang sangat berguna ini dalam utas terkait oleh Lefteris: https://stackoverflow.com/a/27165723/3709173
Singkatnya:
+1 dalam transisi ubahsuaian Anda, jangan tambahkan keTampilan saat animasi penutupan terjadi.
Ditunjukkan di sini:
https://www.dropbox.com/s/7rpkyamv9k9j18v/CustomModalTransition.zip?dl=0 tanpa peretasan! itu seperti sulap! :)
sumber
Di iOS 8, Anda perlu membuat UIPresentationController dan mengimplementasikan metode di bawah ini, di UIViewControllerTransitioningDelegate.
Untuk informasi lebih lanjut, tonton video WWDC 2014:
https://developer.apple.com/videos/wwdc/2014/?include=228
Ada juga kode contoh dari WWDC yang disebut "LookInside: Presentation Controllers Adaptivity and Custom Animator Objects", yang dapat Anda unduh dari halaman kode contoh WWDC 2014.
Anda mungkin perlu sedikit mengubah kode sampel. Metode init UIPresentationController diubah menjadi:
Sebelum dipresentasikan dan kemudian dipresentasikan. Tukar saja dan itu akan berhasil.
sumber
bukannya [inView insertSubview: toViewController.view aboveSubview: fromViewController.view]; cukup tambahkan: [inView addSubview: toViewController.view];
Anda dapat melihat contohnya di sini: tautan dan berfungsi di iOS 7 dan iOS 8
sumber
Ini adalah versi Objective C dari perbaikan Ash.
Saya harus menukar urutan dan memanggil metode [transisiContext completeTransition:] setelah menambahkan tampilan kembali untuk mendapatkan penyajian pengontrol tampilan baru dari blok penyelesaian pemecatan dari pengontrol tampilan lain untuk bekerja dengan benar.
Saya tidak tahu bahwa ini akan memperbaikinya untuk semua orang tetapi berfungsi di aplikasi saya. Bersulang!
sumber
Saya menemukan ini berfungsi dengan baik untuk Obj-C:
Sepertinya bekerja dengan baik di ios7 dan ios8.
sumber
Saya menemukan bahwa
viewForKey:UITransitionContextToViewKey
mengembalikan nol pada ios8. Jadi jika nihil, saya ambil view dari 'to' view controller.Namun, hal ini tampaknya mengakibatkan tampilan 'ke' tidak dipindahkan dari penampung ke jendela saat
completeTransition:YES
dipanggil. Jadi jikaviewForKey:UITransitionContextToViewKey
mengembalikan nihil, saya jatuh ketoVC.view
, dan melacak fakta bahwa itu kembali nihil, dan setelah selesai saya memindahkannya ke tampilan awal wadah (yang kebetulan jendela).Jadi kode ini berfungsi di iOS7 serta iOS8, dan harus berfungsi di iOS9 juga meskipun mereka memperbaikinya atau tidak.
sumber
Saya menemukan bahwa bug ini (dan banyak lagi!) Lenyap jika Anda menyetelnya
modalPresentationStyle = UIModalPresentationFullScreen
. Anda tentu saja masih mendapatkan animasi transisi kustom Anda.sumber
Saya juga terjebak dalam masalah ini. Saya sedang mencari untuk membuat transisi kustom dengan latar belakang semi-transparan di mana saya masih bisa melihat pengontrol tampilan saya berasal tetapi saya hanya mendapatkan latar belakang hitam. Saya menemukan jawaban Mark Aron di utas ini membantu saya tetapi itu ditulis di Objective C jadi inilah versi Swift 3 dari jawaban itu yang telah saya uji untuk iOS 9 dan iOS 10:
Buat subclass UIPresentationController. Ganti shouldRemovePresentersView menjadi false sebagai berikut:
Di tempat Anda membuat instantiating pengontrol tampilan baru dan menyetel delegasi transisinya, tunjukkan bahwa Anda ingin menampilkan gaya presentasi modal kustom sebagai berikut:
Sekarang ganti metode presentasiController dari UIViewControllerTransitioningDelegate Anda dan kembalikan UIPresentationController kustom Anda. Saya memiliki milik saya sebagai perpanjangan dari kelas saya saat ini:
Satu hal lain yang perlu diperhatikan adalah Anda tidak boleh mencoba dan mereferensikan fromView di kelas presentAnimator Anda. Ini akan menjadi nol dan Anda akan mendapatkan kesalahan saat runtime. Selain itu jika Anda menerapkan hal-hal seperti hal-hal, Anda akan mendapatkan transisi khusus dengan animasinya dan latar belakang semi transparan jika Anda membuatnya.
sumber
presentationController(forPresented presented UIViewController,...
karena API cepat sebelumnya tidak mengecewakan pemohon tetapi tidak dipanggil.Setelah menghadapi masalah ini, saya sangat bingung, karena saya telah menulis sesuatu yang hampir sama belum lama ini yang berfungsi dengan baik. Datang ke sini mencari jawaban untuk menemukan perbaikan yang terlihat cukup hack, dan sepertinya tidak memahami akar penyebabnya ... sebenarnya sangat mudah untuk diperbaiki.
Beberapa jawaban menyebutkan berubah
modalPresentationStyle
menjadi.overFullScreen
. Ini benar,.overCurrentContext
akan berhasil juga. Ini diharapkan, dan perilaku dokumen Apple. Tetapi mengapa ini tidak berhasil untuk semua orang? Mengapa semua kode hacky, dan kombinasinya dengan sesuatu yang lain, dan hal-hal gila yang tidak boleh Anda lakukan?Ternyata, Anda perlu mengatur gaya presentasi SEBELUM TAMPILAN BEBAN . Tidak setelahnya. Lakukan di init, atau lakukan dari pengontrol sebelumnya, atau sesuka Anda - selama itu sebelum tampilan dimuat.
sumber
.overCurrentContext
sebelum tampilan dimuat (diinit
pengontrol tampilan) dan masalah masih terjadiMenggunakan UIModalPresentationOverCurrentContext baru memperbaikinya untuk saya. Transisi asli saya di iOS 7 hanya memiliki latar belakang kabur dari tampilan di bawah modal.
sumber
Oke, teman-teman, saya pikir saya menyelesaikan satu kasus bahwa 'animator yang berfungsi' berhenti berfungsi dengan baik ketika Anda membangun aplikasi di iOS 13 dan lebih tinggi.
Env Xcode 11.1, iOS 13.1
Masalah
Yang ingin saya lakukan sangat sederhana: Saya memiliki tampilan koleksi, ketika sel diketuk, sel akan beralih ke tampilan detail. Alih-alih menggunakan gaya default yang membosankan dari 'present modally', saya ingin membuatnya lebih menarik, jadi saya menulis animator untuk transisi pengontrol tampilan.
Saya mengatur segue di IB dengan drag-and-drop dari VC koleksi saya ke detail VC. Gaya segue adalah 'Present modally' dan presentasi diatur ke 'Full Screen'.
Ketika itu menunjukkan tampilan detail, semuanya bekerja seperti yang diharapkan. Namun, saat saya mengabaikan tampilan detail dan kembali ke tampilan koleksi, saya hanya dapat melihat tampilan detail animasi, tampilan koleksi hilang begitu saja. Saya menyodok di sana-sini dan saya memiliki beberapa penemuan
1. Tepat setelah baris berikut dipanggil dari fungsi 'animateTransition ()', tampilan koleksi dilanjutkan dan muncul
2. Selama tampilan detail tidak sepenuhnya menutupi tampilan koleksi, tampilan koleksi tidak akan hilang saat kembali dari tampilan detail
Larutan
Sejujurnya, saya hanya tahu sedikit tentang cara kerja transisi animasi. Jadi saya hanya bisa mengikuti postingan ini dan yang lainnya , coba masing-masing jawabannya. Sayangnya, tidak ada yang berhasil untuk saya. Akhirnya, saya sampai pada titik di mana satu-satunya hal yang dapat saya atur adalah gaya presentasi segue di IB (yang seharusnya saya lakukan di awal). Ketika saya mengatur presentasi ke 'Over Full Screen', keajaiban terjadi dan masalah saya terpecahkan. Tampilan detail dapat ditampilkan dalam layar penuh dengan animasi dan ketika ditutup, saya dapat melihat tampilan koleksi sebagai tampilan detail latar belakang dan animasi.
Kemudian satu penemuan lagi di sepanjang jalan
3. Untuk merujuk ke 'toView' dan 'fromView', kedua metode berikut berfungsi
Cara tidak langsung:
Cara langsung:
Tapi ketika saya mengganti gaya segue ke 'Over Full Screen', cara langsung mengembalikan 'nil' untuk 'toView' dan 'fromView' dan hanya cara tidak langsung berfungsi, masalah ini juga disebutkan di posting lain , jadi saya pikir itu layak untuk memposting penemuan kecil saya di sini.
Semoga ini bisa membantu seseorang di masa depan.
sumber
Saya mengalami masalah yang sama saat menutup pengontrol tampilan konten.
Aplikasi saya memiliki pengontrol tampilan orang tua yang menampilkan pengontrol tampilan anak (menampilkan vc) secara modally. Kemudian ketika subview di childVC disadap, itu menunjukkan vc lain (yang saya sebut pengontrol tampilan konten (disajikan vc))
Masalah saya adalah, ketika Menutup contentVC (sekarang vc presentasi), itu harus pergi ke VC anak (sekarang VC yang disajikan) tetapi segera setelah transisi kustom saya selesai, childVC tiba-tiba menghilang, menunjukkan VC induk.
Apa yang saya lakukan untuk mengatasi masalah ini adalah untuk
.modalPresentationStyle
childVC yang disajikan oleh parentVC dari default.automatic
menjadi.fullscreen
..modalPresentationStyle
contentVC menjadi.fullscreen
juga.Ini menyelesaikan masalah. tetapi itu tidak akan menampilkan VC anak Anda sebagai lembar bergaya kartu di atas parentVC (saat menggunakan
.overCurrentContext
atau otomatis) yang baru di iOS 13.Ingin mengetahui apakah ada solusi yang akan mempertahankan lembar bergaya kartu untuk childVC saat disajikan oleh orang tua.
sumber
menambahkan pengontrol tampilan sebagai anak dari pengontrol tampilan lain.
periksa dan beri tahu saya.
sumber