Bagaimana cara melakukan Unwind segue secara terprogram?

307

Menggunakan storyboard ini sangat mudah. Anda cukup menyeret tindakan ke "Keluar". Tetapi bagaimana saya harus menyebutnya dari kode saya?

tadasz
sumber
33
Saya menemukan ini pertanyaan yang valid - saya punya sendiri. Anda dapat melakukan pelepasan segue secara terprogram dengan 1. membuat segue manual (ctrl-drag dari File's Owner ke Exit), 2. memberinya nama dalam IB, kemudian 3. melakukan normal -performSegueWithIdentifier: pengirim: dalam kode Anda.
Yang Meyer
6
Seharusnya IMO tidak ditutup. Pengguna yang memilih untuk menutup pertanyaan ini tampaknya tidak memiliki latar belakang Obj-C / Cocoa Touch.
LJ Wilson
Yang: Bagaimana Anda memberi nama?
sarfata
Saya hanya menggunakan [self dismissViewControllerAnimated: YES completion: nil]; untuk keluar secara terprogram. Saya tidak tahu itu cara yang benar atau tidak.
tangqiaoboy
1
sarfata: Pertama-tama Anda membuat "manual relax segue" dengan ctrl-drag dari viewcontroller ke "Exit". Kemudian Anda dapat menemukan segue di Document Outline.
huggie

Jawaban:

283
  1. Buat segue manual ( ctrl-drag dari Pemilik File ke Keluar),
  2. Pilih di Menu Pengontrol Kiri di bawah tombol EXIT hijau.

Pilih di Menu Pengontrol Kiri di bawah tombol EXIT hijau

Masukkan Nama Segue untuk melepas lelah.

Kemudian, - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender.dengan mengidentifikasi segue Anda.

Vadim
sumber
25
1) "Pemilik File" - bukankah itu terminologi lama? Ini berhasil bagi saya untuk mengontrol drag dari view controller ke ikon Exit-nya. 2) Meskipun seharusnya jelas, Xcode mencari deklarasi di Antarmuka IBAction yang mengambil argumen UIStoryboardSegue; sesi WWDC 2012 sesi 407 tidak menyebutkan hal itu dan tidak menyisipkan kode itu. Tanpa itu, ikon Keluar saya tidak akan aktif ketika kontrol-menyeret ke sana. 3) Sangat keren bahwa di ujung panah merah besar Anda, di bidang Action, Anda dapat menekan panah "pergi ke sana"!
tobinjim
71
Bagi siapa pun yang, seperti saya, masih kesulitan menerapkan jawaban ini, saya mengumpulkan langkah-langkah dan contoh yang lebih teliti dalam repo ini: github.com/bradley/iOSUnwindSegueProgramatically (Tidak mencoba mengiklankan diri, saya hanya membenturkan kepala ke dinding. selama berjam-jam tentang ini dan melihat pengaturan yang berfungsi membantu saya.)
bradleygriffith
3
@bradleygriffith Kamu luar biasa sangat luar biasa. Terima kasih untuk langkah-langkah hebatnya!
Eli_Rozen
7
@bradleygriffith Saya berharap Anda membuat jawaban ini sehingga saya bisa menandai itu juga! Kontribusi unik Anda adalah menetapkan pengontrol tampilan mana yang mendapatkan kode apa . Tidak dapat menemukannya di mana pun. Terima kasih!
Aaron Vegh
3
Kuncinya, bagi siapa pun yang masih bingung dengan hal ini, adalah bahwa IBACTION harus ada di view controller yang Anda kembalikan, bukan yang sedang Anda masuki. @Bradleygriffith menguraikan ini di GitHub, tapi saya belum melihat bahwa disebutkan di tempat lain. Bagian itu sangat penting.
Axeva
163

Inilah jawaban lengkap dengan Objective C dan Swift:

1) Buat IBActionsegue bersantai di pengontrol tampilan tujuan Anda (tempat Anda ingin segue). Di mana saja dalam file implementasi.

// Objective C

    - (IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue {

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

2) Pada pengontrol tampilan sumber (controller yang Anda pilih), ⌃ + seret dari "Nama aktivitas" untuk keluar. Anda harus melihat segmen pelepasan yang dibuat pada langkah 1 di sembulan. (Jika Anda tidak melihatnya, tinjau langkah pertama). Pilih relaxToContainerVC: dari sembulan, atau apa pun yang Anda beri nama metode Anda untuk menghubungkan pengontrol sumber Anda ke IBAction pelepasan.

masukkan deskripsi gambar di sini

3) Pilih segue dalam garis besar dokumen viewer controller dari storyboard (akan terdaftar di dekat bagian bawah), dan berikan pengenal .

masukkan deskripsi gambar di sini

4) Panggil segue bersantai menggunakan metode ini dari pengontrol tampilan sumber , gantikan nama segue bersantai Anda.

// Tujuan C

[self performSegueWithIdentifier:@"unwindToContainerVC" sender:self];

// Swift

self.performSegueWithIdentifier("unwindToContainerVC", sender: self)

NB. Gunakan properti sourceViewController dari parameter segue pada metode bersantai untuk mengakses properti yang terbuka pada pengontrol sumber. Juga, perhatikan bahwa framework menangani memberhentikan pengontrol sumber. Jika Anda ingin mengonfirmasi ini, tambahkan metode dealloc ke pengontrol sumber dengan pesan log yang akan diaktifkan setelah terbunuh. Jika dealloc tidak menyala, Anda mungkin memiliki siklus tetap.

smileBot
sumber
2
Program saya tidak berfungsi, bahkan tidak dipanggil(IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue
xhg
2
solusi ini tidak berfungsi ketika view controller, Anda tidak mau, hanya ada di storyboard Anda, alias tidak memiliki kebiasaan dalam implementasi kode
mnl
@ mnl tidak yakin persis apa yang Anda katakan, tetapi berfungsi dengan adegan papan cerita atau biji. Jika Anda membuat adegan viewcontroller dalam kode, maka Anda tidak akan menggunakan metode apa pun yang "mengembalikan" IB dalam namanya, yang bagaimanapun juga benar-benar batal karena ini melayani tujuan komunikasi antara kode dan IB. Apakah itu menanggapi komentar Anda?
smileBot
1
Gambar Anda menunjukkan ctrl+dragdari ViewControllerke Exitsangat membantu. Terima kasih!
kbpontius
Untuk Swift 4.2 gunakan: self.performSegue (withIdentifier: "melepasToVC", pengirim: mandiri)
Reefwing
81

bradleygriffithJawabannya bagus. Saya mengambil langkah 10 dan membuat tangkapan layar untuk penyederhanaan. Ini adalah tangkapan layar di Xcode 6.

  1. Kontrol-tarik dari ikon oranye ke ikon Keluar merah untuk membuat pelepasan tanpa tindakan / tombol di tampilan.

masukkan deskripsi gambar di sini

  1. Kemudian pilih unwind seguedi bilah sisi:

masukkan deskripsi gambar di sini

  1. Tetapkan string Pengidentifikasi Segue:

masukkan deskripsi gambar di sini

  1. Akses pengenal itu dari kode:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];
Dekan
sumber
4
Pertama-tama, metode untuk melepaskan harus dimasukkan ke dalam UIViewController. Maka solusi Anda akan berhasil
Alex Cio
5
dan Anda harus mengatur Pengenal ke segue baru ini! Jangan lupakan itu.
kraag22
1
Apakah mungkin untuk membuat koneksi "keluar" di pengontrol tampilan sumber secara terprogram?
Andrew Kirna
13

Saya menggunakan [self dismissViewControllerAnimated: YES completion: nil];yang akan mengembalikan Anda ke panggilan ViewController.

Larry Gibson
sumber
6
Larry, itu pendekatan yang benar-benar valid jika Anda ingin kembali ke pengontrol tampilan sebelumnya, yaitu yang mempresentasikan yang sekarang Anda keluar. Pertanyaan muncul karena baru di Xcode 4.5 adalah kemampuan untuk "melepas" dari satu pengontrol tampilan di suatu tempat dalam urutan presentasi ke pengontrol tampilan yang jauh sebelumnya. Lihat WWDC 2012 sesi 407 untuk detailnya.
tobinjim
11

Mengutip teks dari Catatan Teknis Apple pada Segmen Unwind: Untuk menambahkan segue bersantai yang hanya akan dipicu secara programatik, kontrol + seret dari ikon pengontrol tampilan adegan ke ikon keluarnya, lalu pilih tindakan pelepasan untuk segue baru dari menu sembulan.

Tautan ke Catatan Teknis

Vishal Chaudhry
sumber
6

Jawaban Vishal Chaudhry di atas berhasil untukku. Saya juga akan menambahkan itu untuk memicu seque secara manual menggunakan:

[self performSegueWithIdentifier:@"mySegueName" sender:self];

dari dalam ViewController Anda juga harus memilih segue bersantai di bawah Scene ViewController's di storyboard dan dalam tampilan properti di RHS memastikan bahwa bidang Indentifier berisi penamaan yang Anda maksud dalam kode ("mySegueName" pada contoh di atas ).

Jika Anda mengabaikan langkah ini, baris di atas akan mengeluarkan pengecualian bahwa nama seque tidak dikenal.

Jason Crocker
sumber
3

Solusi kompatibel yang akan bekerja untuk versi sebelum ios6, bagi mereka yang tertarik:

- (void)unwindToViewControllerOfClass:(Class)vcClass animated:(BOOL)animated {

    for (int i=self.navigationController.viewControllers.count - 1; i >= 0; i--) {
        UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:i];
        if ([vc isKindOfClass:vcClass]) {
            [self.navigationController popToViewController:vc animated:animated];
            return;
        }
    }
}
Joel Teply
sumber
2
Seg Unwind melakukan jauh lebih banyak daripada muncul kembali ke kelas tertentu di tumpukan pengontrol navigasi.
Steve Moser
2

SWIFT 4 :

1. Buat @IBAction dengan pengontrol bagian dalam segue yang ingin Anda lepas :

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

2. Di storyboard, dari controller yang ingin Anda segue (lepas) dari ctrl + seret dari tanda controller untuk keluar dari sign dan pilih metode yang Anda buat sebelumnya:

masukkan deskripsi gambar di sini

3. Sekarang Anda dapat melihat bahwa dalam garis besar dokumen Anda memiliki baris baru dengan judul "Unwind segue ....". Sekarang Anda harus mengklik pada baris ini dan membuka inspektur atribut untuk menetapkan pengenal (dalam kasus saya relaxSegueIdentifier ).

masukkan deskripsi gambar di sini

4. Anda hampir selesai! Sekarang Anda perlu membuka pengontrol tampilan yang ingin Anda hilangkan dan membuat beberapa metode yang akan melakukan segue. Misalnya Anda dapat menambahkan tombol, hubungkan dengan kode dengan @IBAction , setelah itu di dalam IBAction ini tambahkan perfromSegue (withIdentifier: sender :) metode:

     @IBAction func unwindToSomeVCWithSegue(_ sender: UIButton) {
         performSegue(withIdentifier: "unwindSegueIdentifier", sender: nil)
     }

Jadi itu yang harus Anda lakukan!

wm.p1us
sumber
Apakah mungkin untuk membuat koneksi "keluar" di pengontrol tampilan sumber secara terprogram?
Andrew Kirna
1

Swift 4.2, Xcode 10+

Bagi mereka yang bertanya-tanya bagaimana melakukan ini dengan VC tidak diatur melalui storyboard (mereka yang datang ke pertanyaan ini dari mencari "secara terprogram" + "bersantai segue").

Mengingat bahwa Anda tidak dapat membuat segmen bersantai secara terprogram, solusi terprogram semata-mata adalah menelepon:

navigationController?.popToRootViewController(animated: true)

yang akan memunculkan semua pengontrol tampilan di stack kembali ke pengontrol tampilan root Anda.


Untuk memunculkan pengontrol tampilan paling atas dari tumpukan navigasi, gunakan:

navigationController?.popViewController(animated: true)

10623169
sumber
1
itu biasanya lebih dari yang Anda inginkan - untuk pop satu kembali cukup lakukan: [self.navigationController popViewControllerAnimated: YES];
Andy Weinstein
Memang, saya telah menambahkan itu ke jawaban saya - terima kasih @AndyWeinstein
10623169
0

FYI: Agar jawaban @ Vadim bekerja dengan aksi seque bersantai manual yang dipanggil dari dalam View Controller, Anda harus menempatkan perintah:

[self performSegueWithIdentifier:(NSString*) identifier sender:(id) sender];

di dalam metode viewDidAppear kelas overriden seperti:

-(void) viewDidAppear:(BOOL) animated
{
    [super viewDidAppear: animated];

    [self performSegueWithIdentifier:@"SomeSegueIdentifier" sender:self];
}

Jika Anda memasukkannya ke metode ViewController lain seperti viewDidLoad atau viewWillAppear itu akan diabaikan.

John Verco
sumber
3
Jelas salah. Panggil performSegueWithIdentifier dari mana pun Anda inginkan.
smileBot
Tidakkah ini hanya melakukan segue bersantai segera setelah tampilan dimuat? Alih-alih melakukan ketika ANDA ingin, misalnya setelah menekan tombol.
Pahnev
@Pahnev ya itu akan terjadi. Saya tidak tahu bagaimana jawaban ini mendapat perbaikan. Memanggil performSegueWithIdentfiermelakukan hal itu: melakukan segue dari satu ViewController ke yang lain
ezcoding
Benar-benar salah. Itu hanya akan mundur segera saat diluncurkan.
Lee Probert