Pertanyaan ini tampaknya sangat populer di sini di stackoverflow, jadi saya pikir saya akan mencoba dan memberikan jawaban yang lebih baik untuk membantu orang-orang yang memulai di dunia iOS seperti saya.
Saya harap jawaban ini cukup jelas untuk dipahami orang dan saya tidak melewatkan apa pun.
Melewati Data Maju
Mengirimkan data ke pengontrol tampilan dari pengontrol tampilan lain. Anda akan menggunakan metode ini jika Anda ingin meneruskan objek / nilai dari satu pengontrol tampilan ke pengontrol tampilan lain yang mungkin Anda dorong ke tumpukan navigasi.
Untuk contoh ini, kita akan memiliki ViewControllerA
danViewControllerB
Untuk meneruskan BOOL
nilai dari ViewControllerA
ke ViewControllerB
kami akan melakukan hal berikut.
di ViewControllerB.h
buat properti untukBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
di ViewControllerA
Anda perlu menceritakannya tentang ViewControllerB
jadi gunakan
#import "ViewControllerB.h"
Lalu di mana Anda ingin memuat tampilan misalnya. didSelectRowAtIndex
atau IBAction
Anda perlu mengatur properti ViewControllerB
sebelum Anda mendorongnya ke nav stack.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.isSomethingEnabled = YES;
[self pushViewController:viewControllerB animated:YES];
Ini akan mengatur isSomethingEnabled
dalam ViewControllerB
untuk BOOL
nilai YES
.
Melewati Data Maju menggunakan Segues
Jika Anda menggunakan Storyboard, kemungkinan besar Anda menggunakan segue dan akan membutuhkan prosedur ini untuk meneruskan data. Ini mirip dengan di atas tetapi alih-alih meneruskan data sebelum Anda mendorong pengontrol tampilan, Anda menggunakan metode yang disebut
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
Jadi untuk lulus BOOL
dari ViewControllerA
keViewControllerB
kita akan melakukan hal berikut:
di ViewControllerB.h
buat properti untukBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
di ViewControllerA
Anda perlu menceritakannya tentang ViewControllerB
jadi gunakan
#import "ViewControllerB.h"
Buat segmen dari ViewControllerA
hinggaViewControllerB
di papan cerita dan beri pengenal, dalam contoh ini kita akan menyebutnya"showDetailSegue"
Selanjutnya, kita perlu menambahkan metode ViewControllerA
yang dipanggil ketika setiap segmen dilakukan, karena ini kita perlu mendeteksi segmen mana yang dipanggil dan kemudian melakukan sesuatu. Dalam contoh kami, kami akan memeriksa "showDetailSegue"
dan jika itu dilakukan kami akan memberikan BOOL
nilai kamiViewControllerB
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
controller.isSomethingEnabled = YES;
}
}
Jika pandangan Anda tertanam di pengontrol navigasi, Anda perlu mengubah metode di atas sedikit menjadi yang berikut
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
controller.isSomethingEnabled = YES;
}
}
Ini akan mengatur isSomethingEnabled
dalam ViewControllerB
untuk BOOL
nilai YES
.
Melewati Data Kembali
Untuk meneruskan data kembali dari ViewControllerB
ke ViewControllerA
Anda perlu menggunakan Protokol dan Delegasi atau Blok , yang terakhir dapat digunakan sebagai mekanisme yang digabungkan secara longgar untuk panggilan balik.
Untuk melakukan ini kami akan membuat ViewControllerA
delegasi dari ViewControllerB
. Ini memungkinkanViewControllerB
untuk mengirim pesan kembali agar ViewControllerA
kami dapat mengirim data kembali.
Untuk ViewControllerA
menjadi delegasi ViewControllerB
harus sesuai dengan ViewControllerB
protokol yang harus kita tentukan. Ini memberitahu ViewControllerA
metode mana yang harus diimplementasikan.
Di ViewControllerB.h
, di bawah #import
, tetapi di atas @interface
Anda menentukan protokol.
@class ViewControllerB;
@protocol ViewControllerBDelegate <NSObject>
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
@end
selanjutnya masih dalam ViewControllerB.h
Anda perlu mengatur delegate
properti dan mensintesis dalamViewControllerB.m
@property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
Dalam ViewControllerB
kita memanggil pesan pada delegate
saat kita pop controller tampilan.
NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
Itu untuk ViewControllerB
. Sekarang ViewControllerA.h
, beri tahu ViewControllerA
untuk mengimpor ViewControllerB
dan mematuhi protokolnya.
#import "ViewControllerB.h"
@interface ViewControllerA : UIViewController <ViewControllerBDelegate>
Dalam ViewControllerA.m
mengimplementasikan metode berikut dari protokol kami
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
{
NSLog(@"This was returned from ViewControllerB %@",item);
}
Sebelum mendorong viewControllerB
ke tumpukan navigasi kita perlu mengatakan ViewControllerB
bahwa itu ViewControllerA
adalah delegasinya, kalau tidak kita akan mendapatkan kesalahan.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.delegate = self
[[self navigationController] pushViewController:viewControllerB animated:YES];
Referensi
- Menggunakan Delegasi untuk Berkomunikasi Dengan View Controllers Lain di Panduan Pemrograman View Controller
- Delegasikan Pola
NSNotification center
Ini cara lain untuk meneruskan data.
// add observer in controller(s) where you want to receive data
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeepLinking:) name:@"handleDeepLinking" object:nil];
-(void) handleDeepLinking:(NSNotification *) notification {
id someObject = notification.object // some custom object that was passed with notification fire.
}
// post notification
id someObject;
[NSNotificationCenter.defaultCenter postNotificationName:@"handleDeepLinking" object:someObject];
Melewati Data kembali dari satu kelas ke kelas lain (Sebuah kelas dapat berupa pengontrol apa saja, manajer jaringan / sesi, subkelas UIView atau kelas lainnya)
Blok adalah fungsi anonim.
Contoh ini meneruskan data dari Kontroler B ke Kontroler A
tentukan blok
@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h
tambahkan block handler (listener) di
mana Anda memerlukan suatu nilai (misalnya Anda memerlukan respons API Anda di ControllerA atau Anda memerlukan data ContorllerB pada A)
// in ContollerA.m
- (void)viewDidLoad {
[super viewDidLoad];
__unsafe_unretained typeof(self) weakSelf = self;
self.selectedVoucherBlock = ^(NSString *voucher) {
weakSelf->someLabel.text = voucher;
};
}
Pergi ke Pengendali B
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];
vc.sourceVC = self;
[self.navigationController pushViewController:vc animated:NO];
blok api
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
NSString *voucher = vouchersArray[indexPath.row];
if (sourceVC.selectVoucherBlock) {
sourceVC.selectVoucherBlock(voucher);
}
[self.navigationController popToViewController:sourceVC animated:YES];
}
Contoh Kerja Lain untuk Blok
@class ViewControllerB;
definisi @protocol di atas? Tanpa itu saya mendapatkan kesalahan "Diharapkan jenis" pada ViewControllerB di baris:- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
dalam@protocol
deklarasiNavigationController
Anda harus menggunakan[self.navigationController pushViewController:viewController animated:YES];
sebagai gantinya[self pushViewController:viewControllerB animated:YES];
Cepat
Ada berton-ton penjelasan di sini dan di sekitar StackOverflow, tetapi jika Anda seorang pemula hanya mencoba untuk mendapatkan sesuatu yang mendasar untuk bekerja, cobalah menonton tutorial YouTube ini (Ini yang membantu saya akhirnya mengerti bagaimana melakukannya).
Melewati data ke depan ke View Controller berikutnya
Berikut ini adalah contoh berdasarkan video. Idenya adalah untuk meneruskan string dari bidang teks di Pengendali Tampilan Pertama ke label di Pengendali Tampilan Kedua.
Buat tata letak storyboard di Interface Builder. Untuk membuat segue, Anda cukup Controlklik tombol dan seret ke Pengendali Tampilan Kedua.
Pengontrol Tampilan Pertama
Kode untuk Pengendali Tampilan Pertama adalah
Pengendali Tampilan Kedua
Dan kode untuk Pengendali Tampilan Kedua adalah
Jangan lupa
UITextField
danUILabel
.Melewati data kembali ke View Controller sebelumnya
Untuk meneruskan data dari pengontrol tampilan kedua ke pengontrol tampilan pertama, Anda menggunakan protokol dan delegasi . Video ini berjalan sangat jelas melalui proses itu:
Berikut ini adalah contoh berdasarkan video (dengan beberapa modifikasi).
Buat tata letak storyboard di Interface Builder. Sekali lagi, untuk membuat segue, Anda cukup Controlmenyeret dari tombol ke Pengendali Tampilan Kedua. Setel pengidentifikasi segue ke
showSecondViewController
. Juga, jangan lupa menghubungkan outlet dan tindakan menggunakan nama-nama dalam kode berikut.Pengontrol Tampilan Pertama
Kode untuk Pengendali Tampilan Pertama adalah
Perhatikan penggunaan
DataEnteredDelegate
protokol khusus kami .Pengendali dan Protokol Tampilan Kedua
Kode untuk pengontrol tampilan kedua adalah
Perhatikan bahwa di
protocol
luar kelas View Controller.Itu dia. Menjalankan aplikasi sekarang Anda harus dapat mengirim data kembali dari pengontrol tampilan kedua ke yang pertama.
sumber
secondViewController.delegate = self
berarti "Saya setuju untuk menjadi pekerja bos." Lihat jawaban ini untuk contoh lain dan penjelasan lebih lanjut.M dalam MVC adalah untuk "Model" dan dalam paradigma MVC peran kelas model adalah untuk mengelola data program. Model adalah kebalikan dari tampilan - tampilan tahu cara menampilkan data, tetapi tidak tahu apa yang harus dilakukan dengan data, sedangkan model tahu segalanya tentang cara bekerja dengan data, tetapi tidak ada tentang cara menampilkannya. Model bisa rumit, tetapi tidak harus seperti itu - model untuk aplikasi Anda mungkin sesederhana serangkaian string atau kamus.
Peran pengontrol adalah memediasi antara tampilan dan model. Oleh karena itu, mereka memerlukan referensi ke satu atau lebih objek tampilan dan satu atau lebih objek model. Katakanlah model Anda adalah array kamus, dengan setiap kamus mewakili satu baris di tabel Anda. Tampilan root untuk aplikasi Anda menampilkan tabel itu, dan mungkin bertanggung jawab untuk memuat array dari file. Ketika pengguna memutuskan untuk menambahkan baris baru ke tabel, mereka mengetuk beberapa tombol dan controller Anda membuat kamus baru (bisa berubah) dan menambahkannya ke array. Untuk mengisi baris, controller membuat controller tampilan detail dan memberikan kamus baru. Pengontrol tampilan detail mengisi kamus dan kembali. Kamus sudah menjadi bagian dari model, jadi tidak ada lagi yang perlu terjadi.
sumber
Ada berbagai cara dimana data dapat diterima ke kelas yang berbeda di iOS. Sebagai contoh -
NSUserDefaults
- untuk mengaksesnya nantiTetapi untuk skenario sederhana menyampaikan nilai ke kelas yang berbeda yang alokasi dilakukan di kelas saat ini, metode yang paling umum dan disukai adalah pengaturan langsung nilai setelah alokasi. Ini dilakukan sebagai berikut: -
Kita dapat memahaminya menggunakan dua pengontrol - Controller1 dan Controller2
Misalkan di kelas Controller1 Anda ingin membuat objek Controller2 dan dorong dengan nilai String yang diteruskan. Ini dapat dilakukan karena ini: -
Dalam implementasi kelas Controller2 akan ada fungsi ini sebagai-
Anda juga bisa langsung mengatur properti dari kelas Controller2 dengan cara yang sama seperti ini:
Untuk melewati beberapa nilai, Anda dapat menggunakan beberapa parameter seperti: -
Atau jika Anda harus melewati lebih dari 3 parameter yang terkait dengan fitur umum, Anda dapat menyimpan nilai-nilai ke kelas Model dan meneruskan modelObject ke kelas berikutnya
Jadi singkatnya jika Anda ingin -
Semoga ini membantu
sumber
Setelah penelitian lebih lanjut tampak bahwa Protokol dan Delegasi adalah cara yang benar / Apple lebih suka melakukan ini.
Saya akhirnya menggunakan contoh ini
Berbagi data antara pengontrol tampilan dan objek lainnya @ iPhone Dev SDK
Bekerja dengan baik dan memungkinkan saya untuk melewatkan sebuah string dan array maju dan mundur di antara pandangan saya.
Terima kasih atas seluruh bantuan Anda
sumber
Saya menemukan versi paling sederhana dan paling elegan dengan blok yang lewat. Mari kita beri nama view controller yang menunggu data yang dikembalikan sebagai "A" dan kembali view controller sebagai "B". Dalam contoh ini kita ingin mendapatkan 2 nilai: pertama dari Type1 dan yang kedua dari Type2.
Dengan asumsi kita menggunakan Storyboard, controller pertama menetapkan blok callback, misalnya selama persiapan segue:
dan "B" view controller harus mendeklarasikan properti callback, BViewController.h:
Daripada di file implementasi BViewController.m setelah kita menginginkan nilai untuk mengembalikan panggilan balik kita harus dipanggil:
Satu hal yang perlu diingat adalah bahwa menggunakan blok seringkali perlu mengelola referensi yang kuat dan __weak seperti dijelaskan di sini
sumber
Ada beberapa informasi yang baik di banyak jawaban yang diberikan, tetapi tidak ada yang menjawab pertanyaan sepenuhnya.
Pertanyaannya adalah tentang meneruskan informasi antara pengontrol tampilan. Contoh spesifik yang diberikan menanyakan tentang meneruskan informasi antar tampilan, tetapi mengingat kebaruan yang dinyatakan sendiri untuk iOS, poster asli kemungkinan dimaksudkan antara viewControllers, bukan antara view (tanpa keterlibatan dari ViewControllers). Tampaknya semua jawaban fokus pada dua pengendali tampilan, tetapi bagaimana jika aplikasi berevolusi perlu melibatkan lebih dari dua pengendali tampilan dalam pertukaran informasi?
Poster asli juga bertanya tentang Singletons dan penggunaan AppDelegate . Pertanyaan-pertanyaan ini perlu dijawab.
Untuk membantu orang lain melihat pertanyaan ini, yang menginginkan jawaban penuh, saya akan berusaha memberikannya.
Skenario Aplikasi
Alih-alih mengadakan diskusi abstrak yang sangat hipotetis, lebih baik memikirkan aplikasi konkret. Untuk membantu menentukan situasi dua-view-controller dan situasi lebih-dari-dua-view-controller, saya akan mendefinisikan dua skenario aplikasi konkret.
Skenario satu: maksimum dua pengendali tampilan yang perlu berbagi informasi. Lihat diagram satu.
Ada dua pengendali tampilan dalam aplikasi. Ada ViewControllerA (Formulir Entri Data), dan View Controller B (Daftar Produk). Item yang dipilih dalam daftar produk harus cocok dengan item yang ditampilkan di kotak teks dalam formulir entri data. Dalam skenario ini, ViewControllerA dan ViewControllerB harus berkomunikasi langsung satu sama lain dan tidak ada pengontrol tampilan lainnya.
Skenario dua : lebih dari dua pengendali tampilan perlu berbagi informasi yang sama. Lihat diagram dua.
Ada empat pengendali tampilan dalam aplikasi. Ini adalah aplikasi berbasis tab untuk mengelola inventaris rumah. Tiga pengendali tampilan menyajikan tampilan yang disaring berbeda dari data yang sama:
Setiap kali suatu item dibuat atau diedit, item tersebut juga harus disinkronkan dengan pengontrol tampilan lainnya. Misalnya, jika kita menambahkan perahu di ViewControllerD, tetapi belum diasuransikan, maka perahu tersebut harus muncul ketika pengguna masuk ke ViewControllerA (Barang Mewah), dan juga ViewControllerC (Seluruh Perlengkapan Rumah), tetapi tidak ketika pengguna pergi ke ViewControllerB (Item Non-Tertanggung). Kita perlu khawatir tidak hanya dengan menambahkan item baru, tetapi juga menghapus item (yang mungkin diizinkan dari salah satu dari empat pengontrol tampilan), atau mengedit item yang ada (yang mungkin diizinkan dari "Tambahkan Formulir Item Baru", menggunakan kembali yang sama untuk mengedit).
Karena semua pengontrol tampilan harus berbagi data yang sama, keempat pengontrol tampilan harus tetap dalam sinkronisasi, dan oleh karena itu perlu ada semacam komunikasi dengan semua pengontrol tampilan lainnya, setiap kali pengontrol tampilan tunggal mengubah data yang mendasarinya. Seharusnya cukup jelas bahwa kita tidak ingin masing-masing pengontrol tampilan berkomunikasi secara langsung dengan masing-masing pengontrol tampilan lain dalam skenario ini. Jika tidak jelas, pertimbangkan jika kami memiliki 20 pengontrol tampilan yang berbeda (bukan hanya 4). Seberapa sulit dan rawan kesalahan untuk memberi tahu masing-masing dari 19 pengontrol tampilan lainnya setiap kali satu pengontrol tampilan melakukan perubahan?
Solusi: Delegasi dan Pola Pengamat, dan Lajang
Dalam skenario satu, kami memiliki beberapa solusi yang layak, seperti jawaban lain yang diberikan
Dalam skenario dua, kami memiliki solusi lain yang layak:
Sebuah tunggal adalah turunan dari kelas, bahwa contoh menjadi satu-satunya contoh yang ada selama masa pakai baterai. Singleton mendapatkan namanya dari fakta bahwa itu adalah contoh tunggal. Biasanya pengembang yang menggunakan lajang memiliki metode kelas khusus untuk mengaksesnya.
Sekarang kita mengerti apa itu singleton, mari kita bahas bagaimana singleton cocok dengan pola pengamat. Pola pengamat digunakan untuk satu objek untuk merespons perubahan oleh objek lain. Dalam skenario kedua, kami memiliki empat pengontrol tampilan yang berbeda, yang semuanya ingin tahu tentang perubahan pada data yang mendasarinya. "Data dasar" harus dimiliki oleh satu instance, singleton. "Tahu tentang perubahan" dicapai dengan mengamati perubahan yang dilakukan pada singleton.
Aplikasi inventaris rumah akan memiliki satu instance kelas yang dirancang untuk mengelola daftar item inventaris. Manajer akan mengelola koleksi barang-barang rumah tangga. Berikut ini adalah definisi kelas untuk pengelola data:
Ketika koleksi item inventaris rumah berubah, pengontrol tampilan harus dibuat sadar akan perubahan ini. Definisi kelas di atas tidak menjelaskan bagaimana ini akan terjadi. Kita harus mengikuti pola pengamat. Pengontrol tampilan harus secara formal mengamati Manajer bersama. Ada dua cara untuk mengamati objek lain:
Dalam skenario dua, kami tidak memiliki properti tunggal dari HouseholdInventoryManager yang dapat diamati menggunakan KVO. Karena kami tidak memiliki satu properti yang mudah diamati, pola pengamat, dalam hal ini, harus diimplementasikan menggunakan NSNotificationCenter. Masing-masing dari empat pengontrol tampilan akan berlangganan pemberitahuan, dan Manajer bersama akan mengirim pemberitahuan ke pusat pemberitahuan bila perlu. Manajer inventaris tidak perlu mengetahui apa pun tentang pengontrol tampilan atau instance dari kelas lain yang mungkin tertarik mengetahui kapan koleksi item inventaris berubah; NSNotificationCenter menangani detail implementasi ini. View Controllers hanya berlangganan notifikasi, dan pengelola data hanya memposting notifikasi.
Banyak programmer pemula mengambil keuntungan dari kenyataan bahwa selalu ada persis satu Aplikasi Delegate di dalam masa aplikasi, yang dapat diakses secara global. Pemrogram pemula menggunakan fakta ini untuk memasukkan benda dan fungsi ke dalam appDelegate sebagai kenyamanan untuk akses dari mana saja dalam aplikasi. Hanya karena AppDelegate adalah singleton, tidak berarti harus mengganti semua lajang lainnya. Ini adalah praktik yang buruk karena menempatkan terlalu banyak beban pada satu kelas, melanggar praktik berorientasi objek yang baik. Setiap kelas harus memiliki peran yang jelas yang mudah dijelaskan, seringkali hanya dengan nama kelas.
Setiap kali Delegasi Aplikasi Anda mulai membengkak, mulailah untuk menghapus fungsionalitas menjadi lajang. Misalnya, Core Data Stack tidak boleh ditinggalkan di AppDelegate, tetapi sebaliknya harus diletakkan di kelasnya sendiri, kelas coreDataManager.
Referensi
sumber
OP tidak menyebutkan view controller tetapi begitu banyak jawabannya, bahwa saya ingin membaur dengan apa yang beberapa fitur baru dari LLVM memungkinkan untuk membuat ini lebih mudah ketika ingin meneruskan data dari satu pengontrol tampilan ke yang lain dan kemudian mendapatkan beberapa hasil kembali.
Segues storyboard, blok ARC dan LLVM membuat ini lebih mudah bagi saya. Beberapa jawaban yang disebutkan di atas storyboard dan segues sudah tetapi masih mengandalkan delegasi. Mendefinisikan delegasi tentu berhasil tetapi beberapa orang mungkin merasa lebih mudah untuk melewatkan pointer atau blok kode.
Dengan UINavigator dan segue, ada cara mudah untuk menyampaikan informasi ke pengontrol yang tunduk dan mendapatkan kembali informasi tersebut. ARC membuat passing pointer ke hal-hal yang berasal dari NSObjects sederhana jadi jika Anda ingin pengontrol yang tunduk menambahkan / mengubah / memodifikasi beberapa data untuk Anda, berikan pointer ke instance yang dapat diubah. Blok memudahkan aksi passing, jadi jika Anda ingin pengendali bawahan memanggil aksi pada kontroler level yang lebih tinggi, berikan blok. Anda menentukan blok untuk menerima sejumlah argumen yang masuk akal bagi Anda. Anda juga dapat mendesain API untuk menggunakan banyak blok jika hal itu lebih cocok.
Berikut adalah dua contoh sepele dari lem segue. Yang pertama adalah langsung menunjukkan satu parameter dilewati untuk input, yang kedua untuk output.
Contoh kedua ini menunjukkan melewati blok panggilan balik untuk argumen kedua. Saya suka menggunakan blok karena menjaga detail yang relevan berdekatan di sumber - sumber tingkat yang lebih tinggi.
sumber
Melewati data kembali dari ViewController 2 (tujuan) ke viewController 1 (Sumber) adalah hal yang lebih menarik. Dengan asumsi Anda menggunakan storyBoard, itulah yang saya temukan:
Itu sudah dibahas di sini.
Saya menemukan ada lebih banyak cara:
-Menggunakan Blok panggilan balik:
gunakan dalam
prepareForSegue
metode di VC1-Menggunakan storyboard Unwind (Exit)
Menerapkan metode dengan argumen UIStoryboardSegue di VC 1, seperti ini:
Dalam storyBoard kait tombol "kembali" ke tombol Keluar hijau (Unwind) dari vc. Sekarang Anda memiliki segue yang "kembali" sehingga Anda dapat menggunakan properti destinationViewController di prepForSegue VC2 dan mengubah properti VC1 sebelum kembali.
Opsi lain untuk menggunakan storyboard Undwind (Exit) - Anda dapat menggunakan metode yang Anda tulis di VC1
Dan di prepForSegue of VC1 Anda dapat mengubah properti apa pun yang ingin Anda bagikan.
Dalam kedua opsi pelepasan, Anda dapat mengatur properti tag tombol dan memeriksanya di prepForSegue.
Semoga saya menambahkan sesuatu ke diskusi.
:) Bersulang.
sumber
Ada beberapa metode untuk berbagi data.
Anda selalu dapat berbagi data menggunakan
NSUserDefaults
. Tetapkan nilai yang ingin Anda bagikan sehubungan dengan kunci pilihan Anda dan dapatkan nilai dari yangNSUserDefault
terkait dengan kunci itu di pengontrol tampilan berikutnya.Anda cukup membuat properti di
viewcontrollerA
. Buat objekviewcontrollerA
dalamviewcontrollerB
dan berikan nilai yang diinginkan ke properti itu.Anda juga dapat membuat delegasi khusus untuk ini.
sumber
Jika Anda ingin meneruskan data dari satu pengontrol ke yang lain, coba kode ini
FirstViewController.h
SecondViewController.h
FirstViewController.m
sumber
Ini adalah jawaban yang sangat lama dan ini anti pola, silakan gunakan delegasi. Jangan gunakan Pendekatan ini !!
1. Buat instance View Controller pertama di View Controller kedua dan buat propertinya
@property (nonatomic,assign)
.2. Tetapkan
SecondviewController
instance dari view controller ini.2. Ketika Anda menyelesaikan operasi pemilihan salin array ke View Controller pertama, Ketika Anda menurunkan SecondView, FirstView akan memegang Array Data.
Semoga ini membantu.
sumber
Saya mencari solusi ini untuk waktu yang lama, Atlast saya menemukannya. Pertama-tama deklarasikan semua objek dalam file SecondViewController.h Anda
Sekarang dalam file implementasi Anda mengalokasikan memori untuk objek-objek seperti ini
Sekarang Anda telah mengalokasikan memori untuk
Array
dan objek. sekarang Anda dapat mengisi memori itu sebelum mendorong iniViewController
Pergi ke SecondViewController.h Anda dan tulis dua metode
dalam file implementasi Anda dapat mengimplementasikan fungsi
berharap bahwa Anda
CustomObject
harus memiliki fungsi setter dengannya.sekarang pekerjaan dasar Anda selesai. pergi ke tempat di mana Anda ingin mendorong
SecondViewController
dan melakukan hal-hal berikutJaga kesalahan pengejaan.
sumber
Ini bukan cara untuk melakukannya, Anda harus menggunakan delegasi, saya akan menganggap kami memiliki dua pengontrol tampilan ViewController1 dan ViewController2 dan hal pemeriksaan ini adalah yang pertama dan ketika keadaannya berubah, Anda ingin melakukan sesuatu di ViewController2, untuk capai itu dengan cara yang tepat, Anda harus melakukan hal berikut:
Tambahkan file baru ke file proyek Anda (Objective-C Protocol) -> Baru, sekarang beri nama ViewController1Delegate atau apa pun yang Anda inginkan dan tulis ini di antara arahan @interface dan @end.
Sekarang buka ViewController2.h dan tambahkan
kemudian ubah definisi menjadi
Sekarang pergi ke ViewController2.m dan di dalam implementasinya tambahkan:
Sekarang buka ViewController1.h dan tambahkan properti berikut:
Sekarang jika Anda membuat ViewController1 di dalam ViewController2 setelah beberapa kejadian, maka Anda harus melakukannya dengan menggunakan file NIB:
Sekarang Anda sudah siap, setiap kali Anda mendeteksi acara cek diubah di ViewController1, yang harus Anda lakukan adalah di bawah ini
Tolong beri tahu saya jika ada sesuatu yang tidak jelas jika saya tidak memahami pertanyaan Anda dengan benar.
sumber
Jika Anda ingin mengirim data dari satu ke viewController lain, berikut ini caranya:
Katakanlah kita memiliki viewControllers: viewControllerA dan viewControllerB
Sekarang di viewControllerB.h
Di viewControllerB.m
Di viewControllerA.m
Jadi ini adalah bagaimana Anda dapat melewatkan data dari viewControllerA ke viewControllerB tanpa mengatur delegasi. ;)
sumber
Saya tahu ini adalah subjek yang dikalahkan, tetapi bagi mereka yang mencari untuk menjawab pertanyaan ini dengan miring SWIFT dan ingin contoh sederhana, di sini metode masuk-ke saya untuk meneruskan data jika Anda menggunakan segue untuk berkeliling.
Ini mirip dengan di atas tetapi tanpa tombol, label dan semacamnya. Cukup dengan mengirimkan data dari satu tampilan ke tampilan berikutnya.
Siapkan Papan Cerita
Ada tiga bagian.
Ini adalah tata letak tampilan yang sangat sederhana dengan segue di antaranya.
Ini adalah pengaturan untuk pengirim
Ini adalah pengaturan untuk penerima.
Terakhir, pengaturan untuk segue.
Lihat Pengontrol
Kami menjaga ini tetap sederhana sehingga tidak ada tombol, bukan tindakan, kami hanya memindahkan data dari pengirim ke penerima ketika aplikasi dimuat dan kemudian mengeluarkan nilai yang dikirimkan ke konsol.
Halaman ini mengambil nilai yang awalnya dimuat dan meneruskannya.
Halaman ini hanya mengirimkan nilai variabel ke konsol saat dimuat. Pada titik ini, film favorit kami harus dalam variabel itu.
Itulah cara Anda dapat mengatasinya jika Anda ingin menggunakan segue dan Anda tidak memiliki halaman Anda di bawah pengontrol navigasi.
Setelah dijalankan, ia harus beralih ke tampilan penerima secara otomatis dan meneruskan nilai dari pengirim ke penerima, menampilkan nilai di konsol.
sumber
Dalam kasus saya, saya menggunakan kelas tunggal yang dapat berfungsi sebagai objek global yang memungkinkan akses ke data dari hampir semua bagian aplikasi. Hal pertama adalah membangun kelas singleton. Silakan merujuk ke halaman, “ Seperti apa bentuk singleton Objective-C saya? ” Dan apa yang saya lakukan untuk membuat objek dapat diakses secara global adalah hanya mengimpornya
appName_Prefix.pch
untuk menerapkan pernyataan impor di setiap kelas. Untuk mengakses objek ini dan menggunakannya, saya cukup menerapkan metode kelas untuk mengembalikan instance bersama, yang berisi variabel sendirisumber
Ada beberapa opsi untuk Passing Data antara View Controllers.
Saya akan menulis ulang logikanya dalam Swift dengan Kerangka iOS terbaru
Langkah 1. Deklarasikan variabel di ViewControllerB
Langkah 2. Cetak Variabel dalam metode ViewDidLoad ViewControllerB
Langkah 3. Di ViewControllerA Lulus Data sambil mendorong melalui Pengontrol Navigasi
Jadi di sini adalah kode lengkap untuk:
ViewControllerA
ViewControllerB
Langkah 1. Buat Segue dari ViewControllerA ke ViewControllerB dan berikan Identifier = showDetailSegue di Storyboard seperti yang ditunjukkan di bawah ini
Langkah 2. Di ViewControllerB Deklarasikan yang layak bernama isSomethingEnabled dan cetak nilainya.
Langkah 3. Di PassControllerA pass adalah nilai sesuatuSomethingEnabled saat melewati Segue
Jadi di sini adalah kode lengkap untuk:
ViewControllerA
ViewControllerB
Langkah 1. Deklarasikan Protokol ViewControllerBDelegate dalam file ViewControllerB tetapi di luar kelas
Langkah 2. Mendeklarasikan instance variabel Delegasi di ViewControllerB
Langkah 3. Kirim data untuk didelegasikan di dalam metode viewDidLoad dari ViewControllerB
Langkah 4. Konfirmasikan ViewControllerBDelegate di ViewControllerA
Langkah 5. Konfirmasikan bahwa Anda akan menerapkan delegasi di ViewControllerA
Langkah 6. Terapkan metode delegasi untuk menerima data di ViewControllerA
Jadi di sini adalah kode lengkap untuk:
ViewControllerA
ViewControllerB
Langkah 1. Setel dan Posting data dalam Pengamat pemberitahuan di ViewControllerB
Langkah 2. Tambahkan Pengamat Pemberitahuan di ViewControllerA
Langkah 3. Terima nilai data Notifikasi di ViewControllerA
Jadi di sini adalah kode lengkap untuk:
ViewControllerA
ViewControllerB
Langkah 1. Deklarasikan blok di ViewControllerB
var authorizationCompletionBlock: ((Bool) -> ())? = {_ in}
Langkah 2. Atur data dalam blok di ViewControllerB
Langkah 3. Terima data blok di ViewControllerA
Jadi di sini adalah kode lengkap untuk:
ViewControllerA
ViewControllerB
Anda dapat menemukan contoh aplikasi lengkap di GitHub saya. Mohon beri tahu saya jika ada pertanyaan tentang ini.
sumber
Melewati Data antara FirstViewController ke SecondViewController seperti di bawah ini
Sebagai contoh:
Nilai FirstViewController String sebagai
jadi kita bisa meneruskan nilai ini di kelas dua menggunakan langkah di bawah ini
1> Kita perlu membuat objek string dalam file SecondViewController.h
2> Perlu mendeklarasikan properti seperti di bawah ini deklarasi dalam file .h
3> Perlu mensintesis nilai tersebut dalam file FirstViewController.m di bawah deklarasi header
dan di FirstViewController.h:
4> Di FirstViewController, Dari metode mana kita menavigasi ke tampilan kedua, silakan tulis kode di bawah ini dalam metode itu.
sumber
Saat ini saya berkontribusi pada solusi open source untuk masalah ini melalui proyek bernama MCViewFactory, yang dapat ditemukan di sini:
https://github.com/YetiHQ/manticore-iosviewfactory
Idenya adalah meniru paradigma niat Android, menggunakan pabrik global untuk mengelola tampilan mana yang Anda lihat dan menggunakan "niat" untuk beralih dan meneruskan data di antara tampilan. Semua dokumentasi ada di halaman github, tetapi di sini ada beberapa highlight:
Anda mengatur semua tampilan Anda dalam file .XIB dan mendaftarkannya dalam delegasi aplikasi, sambil menginisialisasi pabrik.
Sekarang, di VC Anda, kapan pun Anda ingin pindah ke VC baru dan meneruskan data, Anda membuat maksud baru dan menambahkan data ke kamusnya (saveInstanceState). Kemudian, cukup tetapkan maksud pabrik saat ini:
Semua pandangan Anda yang sesuai dengan ini haruslah subclass dari MCViewController, yang memungkinkan Anda mengganti metode onResume: yang baru, yang memungkinkan Anda mengakses data yang telah Anda lewati.
Semoga sebagian dari Anda menemukan solusi ini bermanfaat / menarik.
sumber
Buat properti selanjutnya
view controller .h
dan tentukan pengambil dan penyetel.Tambahkan ini
property
di NextVC.h di nextVCMenambahkan
@synthesize indexNumber;
dalam NextVC.mDan terakhir
sumber
Ada banyak cara untuk melakukan ini dan penting untuk memilih yang tepat. Mungkin salah satu keputusan arsitektur terbesar terletak pada bagaimana kode model akan dibagikan atau diakses di seluruh aplikasi.
Saya menulis posting blog tentang ini beberapa waktu lalu: Berbagi Model Kode . Berikut ringkasan singkatnya:
Data bersama
Salah satu pendekatan adalah untuk membagikan pointer ke objek model antara pengontrol tampilan.
Karena bersiap untuk segue adalah yang paling umum di sini adalah contoh:
Akses independen
Pendekatan lain adalah dengan menangani layar penuh data pada suatu waktu dan alih-alih menyambungkan pengontrol tampilan satu sama lain, masing-masing pasangan pengontrol tampilan ke sumber data tunggal yang dapat mereka peroleh secara mandiri.
Cara paling umum yang pernah saya lihat dilakukan adalah contoh tunggal . Jadi, jika objek singleton
DataAccess
Anda, Anda bisa melakukan hal berikut dalam metode viewDidLoad dari UIViewController:Ada alat tambahan yang juga membantu meneruskan data:
Data Inti
Hal yang menyenangkan tentang Core Data adalah bahwa ia memiliki hubungan terbalik. Jadi, jika Anda hanya ingin memberikan NotesViewController objek catatan Anda bisa karena itu akan memiliki hubungan terbalik dengan sesuatu yang lain seperti notebook. Jika Anda membutuhkan data pada buku catatan di NotesViewController Anda dapat berjalan mundur grafik objek dengan melakukan hal berikut:
Baca lebih lanjut tentang ini di posting blog saya: Berbagi Model Kode
sumber
NewsViewController
NewsDetailViewController.h
NewsDetailViewController.m
sumber
Delegasi adalah satu-satunya solusi untuk melakukan operasi seperti itu ketika Anda menggunakan file .xib namun semua jawaban yang dijelaskan di atas adalah untuk
storyboard
file .xib yang Anda butuhkan untuk menggunakan delegasi. itu hanya solusi yang Anda bisa.Solusi lain adalah menggunakan pola kelas tunggal menginisialisasi sekali dan menggunakannya di seluruh aplikasi Anda.
sumber
jika Anda ingin meneruskan data dari ViewControlerOne ke ViewControllerTwo coba ini ..
lakukan ini di ViewControlerOne.h
lakukan ini di ViewControllerTwo.h
Mensintesis str2 di ViewControllerTwo.m
lakukan ini di ViewControlerOne.m
pada acara klik tombol lakukan ini ..
lakukan ini di ViewControllerTwo.m
sumber
Anda dapat menyimpan data dalam delegasi Aplikasi untuk mengaksesnya di seluruh pengontrol tampilan di aplikasi Anda. Yang harus Anda lakukan adalah membuat instance bersama delegasi aplikasi
Sebagai contoh
jika Anda mendeklarasikan a
NSArray object *arrayXYZ
maka Anda dapat mengaksesnya di sembarang pengontrol tampilan olehappDelegate.arrayXYZ
sumber
Jika Anda ingin mengirim data dari satu ke viewController lain, berikut ini caranya:
Katakanlah kita memiliki viewControllers: ViewController dan NewViewController.
di ViewController.h
di ViewController.m
Di NewViewController.h
Di NewViewController.m
Jadi dengan cara ini kita dapat meneruskan data dari satu viewcontroller ke controller tampilan lain ...
sumber
Saya suka gagasan objek Model dan objek tiruan berdasarkan NSProxy untuk melakukan atau membuang data jika apa yang dipilih pengguna dapat dibatalkan.
Sangat mudah untuk menyampaikan data karena ini adalah satu objek atau beberapa objek dan jika Anda memiliki katakanlah pengontrol UINavigationController, Anda dapat menyimpan referensi ke model di dalam dan semua pengontrol tampilan terdorong dapat mengaksesnya langsung dari pengontrol navigasi.
sumber
Saya telah melihat banyak orang yang memperumit masalah ini menggunakan
didSelectRowAtPath
metode ini. Saya menggunakan Data Inti dalam contoh saya.4 baris kode di dalam metode dan Anda selesai.
sumber
Ada banyak jawaban untuk pertanyaan ini yang menawarkan banyak cara berbeda untuk melakukan komunikasi pengontrol tampilan yang memang akan berhasil, tetapi saya tidak melihat di mana pun disebutkan mana yang sebenarnya terbaik untuk digunakan dan mana yang harus dihindari.
Dalam praktiknya, menurut saya hanya beberapa solusi yang disarankan:
prepare(for:sender:)
metodeUIViewController
ketika menggunakan storyboard dan seguesSolusi Saya sarankan untuk TIDAK menggunakan:
Solusi ini, meskipun bekerja dalam jangka pendek, memperkenalkan terlalu banyak dependensi yang akan merusak arsitektur aplikasi dan membuat lebih banyak masalah nanti.
Bagi mereka yang tertarik, saya menulis beberapa artikel yang membahas poin-poin ini lebih dalam dan menyoroti berbagai kelemahan:
sumber