Saya mencoba menimpa tindakan default tombol kembali di pengontrol navigasi. Saya telah memberikan target tindakan pada tombol khusus. Yang aneh adalah ketika menetapkannya meskipun atribut tombol punggung itu tidak memperhatikan mereka dan itu hanya muncul tampilan saat ini dan kembali ke root:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle: @"Servers"
style:UIBarButtonItemStylePlain
target:self
action:@selector(home)];
self.navigationItem.backBarButtonItem = backButton;
Segera setelah saya mengaturnya leftBarButtonItem
di navigationItem
atasnya akan memanggil tindakan saya, namun kemudian tombol tersebut terlihat seperti putaran biasa dan bukan panah kembali:
self.navigationItem.leftBarButtonItem = backButton;
Bagaimana saya bisa mendapatkannya untuk memanggil tindakan kustom saya sebelum kembali ke tampilan root? Apakah ada cara untuk menimpa aksi kembali default, atau apakah ada metode yang selalu dipanggil ketika meninggalkan tampilan ( viewDidUnload
tidak melakukan itu)?
Jawaban:
Coba letakkan ini di pengontrol tampilan tempat Anda ingin mendeteksi pers:
sumber
if (find(self.navigationController!.viewControllers as! [UIViewController],self)==nil)
Saya telah menerapkan ekstensi UIViewController-BackButtonHandler . Tidak perlu mensubclass apa pun, cukup masukkan ke proyek Anda dan timpa
navigationShouldPopOnBackButton
metode diUIViewController
kelas:Unduh aplikasi sampel .
sumber
navigationBar:shouldPopItem:
bukan metode pribadi karena ini merupakan bagian dariUINavigationBarDelegate
protokol.YES
)? atau akankah itu di masa depan? subklas mungkin merupakan opsi yang lebih amanNO
kembali tombol kembali tetap dalam keadaan dinonaktifkan (secara visual, karena masih menerima dan bereaksi terhadap sentuhan peristiwa). Saya mengatasinya dengan menambahkanelse
pernyataan keshouldPop
cek dan bersepeda melalui subviews bilah navigasi, dan menetapkanalpha
nilai kembali ke 1 jika diperlukan di dalam blok animasi: gist.github.com/idevsoftware/9754057Tidak seperti yang dikatakan Amagrammer, itu mungkin. Anda harus mensubklasifikasikan Anda
navigationController
. Saya menjelaskan semuanya di sini (termasuk kode contoh).sumber
Versi Swift:
(dari https://stackoverflow.com/a/19132881/826435 )
Di controller tampilan Anda, Anda hanya menyesuaikan diri dengan protokol dan melakukan tindakan apa pun yang Anda butuhkan:
Kemudian buat kelas, katakan
NavigationController+BackButton
, dan cukup salin-tempel kode di bawah ini:sumber
shouldPopOnBackButtonPress
harus dipanggil selama tidak ada bug.performSomeActionOnThePressOfABackButton
hanyalah metode buatan yang tidak ada.performSomeActionOnThePressOfABackButton
di controller saya untuk melakukan tindakan tertentu ketika tombol kembali ditekan, tetapi metode ini tidak pernah dipanggil, tindakan itu adalah pengembalian kembali yang normalUINavigationController
,navigationBar.delegate
diatur ke pengontrol navigasi. Jadi metode HARUS dipanggil. Namun, di Swift, saya tidak bisa membuat mereka dipanggil, bahkan di subkelas. Namun, saya membuatnya dipanggil dalam Objective-C, jadi saya hanya akan menggunakan versi Objective-C untuk saat ini. Bisa jadi bug Swift.Itu tidak mungkin dilakukan secara langsung. Ada beberapa alternatif:
UIBarButtonItem
yang divalidasi pada ketuk dan muncul jika tes lulusUITextField
metode delegasi, seperti-textFieldShouldReturn:
, yang dipanggil setelah tombolReturn
atauDone
ditekan pada keyboardKelemahan dari opsi pertama adalah bahwa gaya panah menunjuk-kiri tombol kembali tidak dapat diakses dari tombol bilah kustom. Jadi, Anda harus menggunakan gambar atau pergi dengan tombol gaya biasa.
Opsi kedua bagus karena Anda mendapatkan bidang teks kembali dalam metode delegasi, sehingga Anda dapat menargetkan logika validasi Anda ke bidang teks tertentu yang dikirim ke metode panggilan balik delegasi.
sumber
Untuk beberapa alasan threading, solusi yang disebutkan oleh @HansPinckaers tidak tepat untuk saya, tapi saya menemukan cara yang sangat mudah untuk menangkap sentuhan pada tombol kembali, dan saya ingin menjepit ini di sini kalau-kalau ini bisa menghindari jam penipuan untuk orang lain. Caranya sangat mudah: cukup tambahkan UIButton transparan sebagai subview ke UINavigationBar Anda, dan atur penyeleksi Anda untuknya seolah-olah itu adalah tombol asli! Berikut ini contoh menggunakan Monotouch dan C #, tetapi terjemahan ke objektif-c seharusnya tidak terlalu sulit untuk ditemukan.
Fakta menyenangkan: untuk tujuan pengujian dan untuk menemukan dimensi yang baik untuk tombol palsu saya, saya mengatur warna latar belakangnya menjadi biru ... Dan itu ditampilkan di belakang tombol kembali! Bagaimanapun, masih menangkap sentuhan yang menargetkan tombol asli.
sumber
Teknik ini memungkinkan Anda untuk mengubah teks tombol "kembali" tanpa mempengaruhi judul pengontrol tampilan atau melihat perubahan teks tombol kembali selama animasi.
Tambahkan ini ke metode init di controller tampilan panggilan :
sumber
Cara termudah
Anda dapat menggunakan metode delegasi UINavigationController. Metode
willShowViewController
ini dipanggil ketika tombol kembali VC Anda ditekan. Lakukan apa pun yang Anda inginkan ketika kembali dengan ditekansumber
Inilah solusi Swift saya. Di subkelas UIViewController Anda, ganti metode navigasiShouldPopOnBackButton.
sumber
Menemukan solusi yang mempertahankan gaya tombol kembali juga. Tambahkan metode berikut ke pengontrol tampilan Anda.
Sekarang berikan fungsionalitas sesuai kebutuhan dalam metode berikut:
Yang dilakukannya hanyalah menutup tombol kembali dengan tombol transparan;)
sumber
======================================
Membangun tanggapan sebelumnya dengan UIAlert di Swift5 dengan cara Asinkron
Di controller Anda
sumber
Saya tidak percaya ini mungkin, dengan mudah. Satu-satunya cara saya percaya untuk mengatasi ini adalah dengan membuat gambar panah tombol kembali Anda sendiri untuk ditempatkan di sana. Awalnya itu membuat saya frustasi, tetapi saya mengerti mengapa, demi konsistensi, itu diabaikan.
Anda dapat mendekati (tanpa panah) dengan membuat tombol biasa dan menyembunyikan tombol kembali default:
sumber
Ada cara yang lebih mudah dengan hanya subclassing metode delegasi dari
UINavigationBar
dan menimpa paraShouldPopItem
metode .sumber
solusi onegray tidak aman. Menurut dokumen resmi oleh Apple, https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html , kita harus menghindari itu.
"Jika nama metode yang dideklarasikan dalam kategori adalah sama dengan metode di kelas asli, atau metode dalam kategori lain di kelas yang sama (atau bahkan superclass), perilaku tidak ditentukan untuk metode implementasi yang digunakan saat runtime. Ini cenderung menjadi masalah jika Anda menggunakan kategori dengan kelas Anda sendiri, tetapi dapat menyebabkan masalah saat menggunakan kategori untuk menambahkan metode ke kelas standar Cocoa atau Cocoa Touch. "
sumber
Menggunakan Swift:
sumber
Berikut ini adalah versi Swift 3 dari jawaban @oneway untuk menangkap acara tombol navigasi bar sebelum dipecat. Karena
UINavigationBarDelegate
tidak dapat digunakan untukUIViewController
, Anda perlu membuat delegasi yang akan dipicu ketikanavigationBar
shouldPop
dipanggil.Dan kemudian, di controller tampilan Anda tambahkan fungsi delegasi:
Saya menyadari bahwa kami sering ingin menambahkan pengontrol lansiran bagi pengguna untuk memutuskan apakah mereka ingin kembali. Jika demikian, Anda selalu dapat
return false
dinavigationShouldPopOnBackButton()
fungsi dan menutup controller pandangan Anda dengan melakukan sesuatu seperti ini:sumber
Value of type 'UIViewController' has no member 'navigationShouldPopOnBackButton'
ketika saya mencoba untuk mengkompilasi kode Anda, untuk barisif vc.responds(to: #selector(v...
Juga,self.topViewController
mengembalikan opsional dan ada peringatan untuk itu juga.let vc = self.topViewController as! MyViewController
dan sepertinya berfungsi dengan baik sejauh ini. Jika Anda yakin itu adalah perubahan yang tepat, Anda dapat mengedit kode. Juga, jika Anda merasa bahwa itu tidak boleh dilakukan, saya akan senang mengetahui mengapa. Terima kasih untuk kode ini. Anda mungkin harus menulis posting blog tentang ini, karena jawaban ini dikubur sesuai suara.MyViewController
mungkin tidak setujuBackButtonDelegate
. Daripada memaksa membuka, Anda harus lakukanguard let vc = self.topViewController as? MyViewController else { return true }
untuk menghindari kemungkinan kecelakaan.guard let vc = self.topViewController as? MyViewController else { self.popViewController(animated: true) return true }
untuk memastikan bahwa layar bergerak ke halaman yang tepat jika itu tidak dapat dilemparkan dengan benar. Saya mengerti sekarang bahwanavigationBar
fungsi dipanggil di semua VC dan bukan hanya viewcontroller di mana kode ini ada. Mungkin akan baik untuk memperbarui kode dalam jawaban Anda juga? Terima kasih.Versi Swift 4 iOS 11.3:
Ini didasarkan pada jawaban dari kgaidis dari https://stackoverflow.com/a/34343418/4316579
Saya tidak yakin kapan ekstensi berhenti berfungsi, tetapi pada saat penulisan ini (Swift 4), tampaknya ekstensi tidak akan lagi dijalankan kecuali Anda menyatakan kesesuaian UINavigationBarDelegate seperti dijelaskan di bawah ini.
Semoga ini bisa membantu orang yang bertanya-tanya mengapa ekstensi mereka tidak lagi berfungsi.
sumber
Dengan menggunakan variabel target dan tindakan yang saat ini Anda tinggalkan 'nil', Anda harus dapat menghubungkan dialog penyimpanan Anda sehingga mereka dipanggil ketika tombol "dipilih". Awas, ini bisa dipicu pada saat-saat aneh.
Saya sebagian besar setuju dengan Amagrammer, tetapi saya tidak berpikir akan sulit untuk membuat tombol dengan panah kustom. Saya hanya akan mengganti nama tombol kembali, mengambil screenshot, photoshop ukuran tombol yang diperlukan, dan memilikinya menjadi gambar di bagian atas tombol Anda.
sumber
Anda dapat mencoba mengakses item Tombol Kanan Navigasi dan mengatur properti pemilihnya ... inilah referensi UIBarButtonItem referensi , hal lain jika pekerjaan doenst ini yang akan def bekerja adalah, mengatur item tombol kanan nav bar ke UIBarButtonItem kustom yang Anda inginkan buat dan atur pemilihnya ... semoga ini membantu
sumber
Untuk formulir yang memerlukan input pengguna seperti ini, saya akan merekomendasikan memohonnya sebagai "modal" alih-alih bagian dari tumpukan navigasi Anda. Dengan begitu mereka harus mengurus bisnis pada formulir, maka Anda dapat memvalidasinya dan mengabaikannya menggunakan tombol kustom. Anda bahkan dapat mendesain bilah navigasi yang terlihat sama dengan sisa aplikasi Anda, tetapi memberi Anda lebih banyak kontrol.
sumber
Untuk mencegat tombol Kembali, cukup tutup dengan UIControl transparan dan sentuh sentuhannya.
sumber
Setidaknya di Xcode 5, ada solusi yang sederhana dan cukup bagus (tidak sempurna). Di IB, seret Item Tombol Bilah dari panel Utilities dan letakkan di sisi kiri Bilah Navigasi tempat tombol Kembali berada. Atur label menjadi "Kembali." Anda akan memiliki tombol yang berfungsi yang dapat Anda ikat ke IBAction Anda dan tutup viewController Anda. Saya melakukan beberapa pekerjaan dan kemudian memicu segue bersantai dan bekerja dengan sempurna.
Apa yang tidak ideal adalah tombol ini tidak mendapatkan <panah dan tidak meneruskan judul VC sebelumnya, tapi saya pikir ini bisa dikelola. Untuk tujuan saya, saya mengatur tombol Kembali yang baru menjadi tombol "Selesai" sehingga tujuannya jelas.
Anda juga berakhir dengan dua tombol Kembali di navigator IB, tetapi cukup mudah untuk memberi label kejelasan.
sumber
Cepat
sumber
Pendekatan ini berhasil bagi saya (tetapi tombol "Kembali" tidak akan memiliki tanda "<"):
sumber
Versi cepat jawaban onegray
Sekarang di setiap pengontrol, cukup ikuti
RequestsNavigationPopVerification
dan perilaku ini diadopsi secara default.sumber
Menggunakan
isMovingFromParentViewController
sumber
viewDidDisappear
. Dengan begitu itu hanya akan menyala setelah tampilan benar-benar hilang.Namun, jawaban dari @William benar, jika pengguna memulai gerakan swipe-to-go-back
viewWillDisappear
metode ini dipanggil dan bahkanself
tidak akan ada di tumpukan navigasi (yaitu,self.navigationController.viewControllers
tidak akan berisiself
), bahkan jika gesek tidak selesai dan pengontrol tampilan tidak benar-benar muncul. Dengan demikian, solusinya adalah:Nonaktifkan isyarat gesek untuk kembali
viewDidAppear
dan hanya mengizinkan menggunakan tombol kembali, dengan menggunakan:Atau gunakan
viewDidDisappear
saja, sebagai berikut:sumber
Solusi yang saya temukan sejauh ini tidak terlalu baik, tetapi itu bekerja untuk saya. Mengambil jawaban ini , saya juga memeriksa apakah saya muncul secara terprogram atau tidak:
Anda harus menambahkan properti itu ke controller Anda dan mengaturnya ke YA sebelum muncul secara terprogram:
sumber
Menemukan cara baru untuk melakukannya:
Objektif-C
Cepat
sumber