Этот вопрос, кажется, очень популярен здесь на stackoverflow, поэтому я подумал, что постараюсь дать лучший ответ, чтобы помочь людям, начинающим в мире iOS, как я.
Я надеюсь, что этот ответ достаточно ясен для понимания людьми, и я ничего не пропустил.
Передача данных вперед
Передача данных в контроллер представления от другого контроллера представления. Вы должны использовать этот метод, если хотите передать объект / значение из одного контроллера представления в другой контроллер представления, который вы, возможно, помещаете в стек навигации.
Для этого примера мы будем иметь ViewControllerA
иViewControllerB
Чтобы передать BOOL
значение из ViewControllerA
в, ViewControllerB
мы бы сделали следующее.
в ViewControllerB.h
создать свойство дляBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
в ViewControllerA
вы должны сказать ему о ViewControllerB
так использовать
#import "ViewControllerB.h"
Тогда где вы хотите загрузить вид, например. didSelectRowAtIndex
или некоторые из них, IBAction
вам нужно установить свойство ViewControllerB
перед тем, как поместить его в стек навигации.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.isSomethingEnabled = YES;
[self pushViewController:viewControllerB animated:YES];
Это позволит установить isSomethingEnabled
в ViewControllerB
к BOOL
значению YES
.
Передача данных вперед с использованием сегментов
Если вы используете раскадровки, вы, скорее всего, используете сегменты, и вам потребуется эта процедура для передачи данных. Это похоже на вышеприведенное, но вместо передачи данных перед тем, как нажать контроллер представления, вы используете метод, называемый
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
Таким образом, чтобы передать BOOL
от ViewControllerA
к ViewControllerB
мы бы сделали следующее:
в ViewControllerB.h
создать свойство дляBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
в ViewControllerA
вы должны сказать ему о ViewControllerB
так использовать
#import "ViewControllerB.h"
Создайте переход от ViewControllerA
к ViewControllerB
на раскадровке и дайте ему идентификатор, в этом примере мы назовем его"showDetailSegue"
Затем нам нужно добавить метод к тому, ViewControllerA
который вызывается, когда выполняется любой переход, поэтому нам нужно определить, какой вызов вызывался, а затем что-то сделать. В нашем примере мы проверим, "showDetailSegue"
и если это будет выполнено, мы передадим наше BOOL
значениеViewControllerB
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
controller.isSomethingEnabled = YES;
}
}
Если ваши представления встроены в контроллер навигации, вам нужно немного изменить описанный выше метод на следующий
-(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;
}
}
Это позволит установить isSomethingEnabled
в ViewControllerB
к BOOL
значению YES
.
Передача данных назад
Для того, чтобы передать данные обратно из ViewControllerB
к ViewControllerA
Вам необходимо использовать протоколы и делегат или блоки , последние может быть использован в качестве слабосвязанного механизма обратных вызовов.
Для этого мы сделаем ViewControllerA
делегата ViewControllerB
. Это позволяет ViewControllerB
отправить сообщение обратно, чтобы ViewControllerA
мы могли отправить данные обратно.
Чтобы ViewControllerA
быть его делегатом, ViewControllerB
он должен соответствовать ViewControllerB
протоколу, который мы должны указать. Это говорит, ViewControllerA
какие методы он должен реализовать.
В ViewControllerB.h
, ниже #import
, но выше @interface
вы указываете протокол.
@class ViewControllerB;
@protocol ViewControllerBDelegate <NSObject>
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
@end
следующий еще в ViewControllerB.h
вам нужно настроить delegate
свойство и синтезировать вViewControllerB.m
@property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
В ViewControllerB
мы вызываем сообщение о том, delegate
когда мы выскакиваем контроллер представления.
NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
Вот и все ViewControllerB
. Теперь ViewControllerA.h
, скажи, ViewControllerA
чтобы импортировать ViewControllerB
и соответствовать его протоколу.
#import "ViewControllerB.h"
@interface ViewControllerA : UIViewController <ViewControllerBDelegate>
В ViewControllerA.m
реализации следующий метод из нашего протокола
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
{
NSLog(@"This was returned from ViewControllerB %@",item);
}
Прежде чем viewControllerB
перейти к стеку навигации, мы должны сказать, ViewControllerB
что ViewControllerA
это его делегат, иначе мы получим ошибку.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.delegate = self
[[self navigationController] pushViewController:viewControllerB animated:YES];
Ссылки
- Использование делегирования для связи с другими контроллерами представления в Руководстве по программированию контроллера представления
- Шаблон делегата
NSNotification Center
Это еще один способ передачи данных.
// 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];
Передача данных обратно из одного класса в другой (классом может быть любой контроллер, менеджер сети / сеанса, подкласс UIView или любой другой класс)
Блоки являются анонимными функциями.
В этом примере данные передаются с контроллера B на контроллер A
определить блок
@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h
Добавьте обработчик блока (слушатель),
где вам нужно значение (например, вам нужен ответ API в ControllerA или вам нужны данные ContorllerB на A)
// in ContollerA.m
- (void)viewDidLoad {
[super viewDidLoad];
__unsafe_unretained typeof(self) weakSelf = self;
self.selectedVoucherBlock = ^(NSString *voucher) {
weakSelf->someLabel.text = voucher;
};
}
Перейти к контроллеру B
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];
vc.sourceVC = self;
[self.navigationController pushViewController:vc animated:NO];
пожарный блок
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
NSString *voucher = vouchersArray[indexPath.row];
if (sourceVC.selectVoucherBlock) {
sourceVC.selectVoucherBlock(voucher);
}
[self.navigationController popToViewController:sourceVC animated:YES];
}
Еще один рабочий пример для блоков
@class ViewControllerB;
выше определение @protocol? Без этого я получаю ошибку «Ожидаемый тип» на ViewControllerB в строке:- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
в@protocol
объявленииNavigationController
вы должны использовать[self.navigationController pushViewController:viewController animated:YES];
вместо этого[self pushViewController:viewControllerB animated:YES];
стриж
Существует множество объяснений здесь и вокруг StackOverflow, но если вы новичок, просто пытающийся получить что-то базовое для работы, попробуйте посмотреть это руководство на YouTube (именно это помогло мне наконец понять, как это сделать).
Передача данных на следующий View Controller
Ниже приведен пример, основанный на видео. Идея состоит в том, чтобы передать строку из текстового поля в первом контроллере представления метке во втором контроллере представления.
Создайте макет раскадровки в Интерфейсном Разработчике. Чтобы начать, просто Controlнажмите на кнопку и перетащите на контроллер второго вида.
Контроллер первого вида
Код для первого контроллера представления
Контроллер второго вида
И код для второго контроллера представления
Не забывай
UITextField
иUILabel
.Передача данных обратно в предыдущий View Controller
Чтобы передать данные из второго контроллера представления в первый контроллер представления, вы используете протокол и делегат . Это видео представляет собой очень четкое описание этого процесса:
Ниже приведен пример, основанный на видео (с некоторыми изменениями).
Создайте макет раскадровки в Интерфейсном Разработчике. Опять же, чтобы перейти к следующему этапу, вы просто Controlперетаскиваете кнопку на контроллер второго вида. Установите идентификатор segue в
showSecondViewController
. Кроме того, не забудьте подключить розетки и действия, используя имена в следующем коде.Контроллер первого вида
Код для первого контроллера представления
Обратите внимание на использование нашего пользовательского
DataEnteredDelegate
протокола.Контроллер второго вида и протокол
Код для второго контроллера вида
Обратите внимание, что за
protocol
пределами класса View Controller.Вот и все. Запустив приложение сейчас, вы сможете отправить данные обратно со второго контроллера представления на первый.
источник
secondViewController.delegate = self
означает «Я согласен быть начальником». Посмотрите этот ответ для другого примера и большего объяснения.M в MVC - это «Модель», а в парадигме MVC роль классов моделей заключается в управлении данными программы. Модель является противоположностью представления - представление знает, как отображать данные, но ничего не знает о том, что делать с данными, в то время как модель знает все о том, как работать с данными, но ничего о том, как их отображать. Модели могут быть сложными, но это не обязательно - модель для вашего приложения может быть такой же простой, как массив строк или словарей.
Роль контроллера - посредник между представлением и моделью. Следовательно, им нужна ссылка на один или несколько объектов вида и один или несколько объектов модели. Допустим, ваша модель представляет собой массив словарей, каждый из которых представляет одну строку в вашей таблице. Корневое представление для вашего приложения отображает эту таблицу, и оно может отвечать за загрузку массива из файла. Когда пользователь решает добавить новую строку в таблицу, он нажимает какую-то кнопку, и ваш контроллер создает новый (изменяемый) словарь и добавляет его в массив. Чтобы заполнить строку, контроллер создает контроллер подробного представления и дает ему новый словарь. Контроллер подробного представления заполняет словарь и возвращает. Словарь уже является частью модели, поэтому больше ничего не должно произойти.
источник
Существуют различные способы получения данных в другой класс в iOS. Например -
NSUserDefaults
- для доступа к нему позжеНо для простого сценария передачи значения другому классу, распределение которого выполняется в текущем классе, наиболее распространенным и предпочтительным методом будет прямая установка значений после распределения. Это делается следующим образом:-
Мы можем понять это, используя два контроллера - Controller1 и Controller2
Предположим, в классе Controller1 вы хотите создать объект Controller2 и передать его с передачей значения String. Это можно сделать так:
В реализации класса Controller2 будет эта функция, так как
Вы также можете напрямую установить свойства класса Controller2 следующим образом:
Для передачи нескольких значений вы можете использовать несколько параметров, таких как: -
Или, если вам нужно передать более 3 параметров, связанных с общей функцией, вы можете сохранить значения в классе Model и передать этот modelObject следующему классу.
Короче говоря, если вы хотите -
Надеюсь это поможет
источник
После дальнейших исследований выяснилось, что протоколы и делегаты - верный / предпочтительный способ Apple сделать это.
Я закончил тем, что использовал этот пример
Обмен данными между контроллерами представления и другими объектами @ iPhone Dev SDK
Работал нормально и позволял мне передавать строку и массив вперед и назад между моими представлениями.
Спасибо за вашу помощь
источник
Я нахожу самый простой и самый элегантный вариант с прохождением блоков. Давайте назовем контроллер представления, который ожидает возвращенные данные, как «A» и возвращающий контроллер представления как «B». В этом примере мы хотим получить 2 значения: первое из Type1 и второе из Type2.
Предполагая, что мы используем Storyboard, первый контроллер устанавливает блок обратного вызова, например, во время подготовки к следующему этапу:
и контроллер представления "B" должен объявить свойство обратного вызова, BViewController.h:
Затем в файле реализации BViewController.m после того, как мы получили желаемые значения для возврата нашего обратного вызова, необходимо вызвать:
Следует помнить одну вещь: использование блока часто требует управления сильными и слабыми ссылками, как описано здесь.
источник
Во многих из приведенных ответов содержится некоторая полезная информация, но ни один из них не дает полного ответа на этот вопрос.
Вопрос касается передачи информации между контроллерами представления. В приведенном конкретном примере запрашивается передача информации между представлениями, но с учетом самооценки новизны iOS первоначальный плакат, скорее всего, подразумевал между viewControllers, а не между представлениями (без какого-либо участия ViewControllers). Кажется, что все ответы сосредоточены на двух контроллерах представления, но что, если приложение развивается, чтобы задействовать более двух контроллеров представления в обмене информацией?
Оригинальный постер также спрашивал о Singletons и использовании AppDelegate . На эти вопросы нужно ответить.
Чтобы помочь кому-то еще, смотрящему на этот вопрос, кто хочет получить полный ответ, я постараюсь предоставить его.
Сценарии применения
Вместо того, чтобы иметь весьма гипотетическое, абстрактное обсуждение, это помогает иметь в виду конкретные приложения. Чтобы помочь определить ситуацию с двумя представлениями контроллера и ситуацией с более чем двумя представлениями, я собираюсь определить два конкретных сценария применения.
Сценарий первый: максимум два контроллера представления когда-либо должны обмениваться информацией. Смотрите диаграмму один.
В приложении есть два контроллера вида. Существует ViewControllerA (форма ввода данных) и View Controller B (список продуктов). Элементы, выбранные в списке продуктов, должны соответствовать элементам, отображаемым в текстовом поле в форме ввода данных. В этом сценарии ViewControllerA и ViewControllerB должны взаимодействовать напрямую друг с другом, а не с другими контроллерами представления.
Сценарий второй : более двух контроллеров представления должны совместно использовать одну и ту же информацию. Смотрите схему два.
В приложении есть четыре контроллера вида. Это приложение на основе вкладок для управления домашним инвентарем. Три контроллера представления представляют по-разному фильтрованные представления тех же данных:
Каждый раз, когда отдельный элемент создается или редактируется, он также должен синхронизироваться с другими контроллерами представления. Например, если мы добавляем лодку в ViewControllerD, но она еще не застрахована, тогда лодка должна появиться, когда пользователь перейдет к ViewControllerA (предметы роскоши), а также ViewControllerC (вся домашняя инвентаризация), но не когда пользователь перейдет к ViewControllerB (не застрахованные предметы). Нам нужно заботиться не только о добавлении новых элементов, но и об удалении элементов (которые могут быть разрешены с любого из четырех контроллеров представления) или редактировании существующих элементов (что можно разрешить из «Формы добавления нового элемента», с целью повторного использования того же самого). для редактирования).
Поскольку все контроллеры представления должны совместно использовать одни и те же данные, все четыре контроллера представления должны оставаться синхронизированными, и, следовательно, должна быть какая-то связь со всеми другими контроллерами представления, всякий раз, когда какой-либо один контроллер представления изменяет базовые данные. Должно быть совершенно очевидно, что мы не хотим, чтобы каждый контроллер представления взаимодействовал напрямую друг с другом в этом сценарии. В случае, если это не очевидно, рассмотрим, было ли у нас 20 различных контроллеров представления (а не только 4). Насколько сложно и подвержено ошибкам уведомлять каждый из 19 контроллеров представления каждый раз, когда один контроллер представления вносит изменения?
Решения: делегаты, шаблон наблюдателя и синглтоны
В первом сценарии у нас есть несколько жизнеспособных решений, так как другие ответы дали
Во втором сценарии у нас есть другие жизнеспособные решения:
Синглтон является экземпляром класса, этот экземпляр является единственным случаем существования в течение всего срока службы. Синглтон получил свое название от того факта, что это единственный экземпляр. Обычно разработчики, которые используют синглтоны, имеют специальные методы класса для доступа к ним.
Теперь, когда мы понимаем, что такое синглтон, давайте обсудим, как синглтон вписывается в схему наблюдателя. Шаблон наблюдателя используется для того, чтобы один объект реагировал на изменения другого объекта. Во втором сценарии у нас есть четыре разных контроллера представления, которые все хотят знать об изменениях в базовых данных. «Базовые данные» должны принадлежать одному экземпляру, одиночке. «Знать об изменениях» достигается путем наблюдения изменений, внесенных в синглтон.
У приложения домашней инвентаризации будет один экземпляр класса, который предназначен для управления списком предметов инвентаря. Менеджер будет управлять коллекцией предметов домашнего обихода. Ниже приведено определение класса для менеджера данных:
Когда коллекция предметов домашнего инвентаря изменяется, контроллеры представления должны быть осведомлены об этом изменении. Приведенное выше определение класса не дает понять, как это будет происходить. Нам нужно следовать схеме наблюдателя. Контроллеры представления должны формально соблюдать sharedManager. Есть два способа наблюдать за другим объектом:
Во втором сценарии у нас нет ни одного свойства HouseholdInventoryManager, которое можно было бы наблюдать с помощью KVO. Поскольку у нас нет единственного свойства, которое легко наблюдать, шаблон наблюдателя в этом случае должен быть реализован с использованием NSNotificationCenter. Каждый из четырех контроллеров представления подписывается на уведомления, а sharedManager отправляет уведомления в центр уведомлений, когда это необходимо. Менеджеру инвентаря не нужно ничего знать о контроллерах представления или экземплярах каких-либо других классов, которые могут быть заинтересованы в знании, когда изменяется коллекция предметов инвентаря; NSNotificationCenter заботится об этих деталях реализации. Контроллеры представления просто подписываются на уведомления, а менеджер данных просто публикует уведомления.
Многие начинающие программисты пользуются тем, что в жизни приложения всегда есть ровно один делегат приложения, который доступен во всем мире. Начинающие программисты используют этот факт для помещения объектов и функций в appDelegate для удобства доступа из любой точки приложения. Тот факт, что AppDelegate является синглтоном, не означает, что он должен заменить все остальные синглтоны. Это плохая практика, поскольку она ложится слишком большим бременем на один класс, нарушая хорошие объектно-ориентированные практики. Каждый класс должен иметь четкую роль, которую легко объяснить, часто просто по названию класса.
Каждый раз, когда ваш Application Delegate начинает раздуваться, начинайте удалять функциональность в одиночку. Например, основной стек данных не следует оставлять в AppDelegate, вместо этого его следует поместить в его собственный класс, класс coreDataManager.
Ссылки
источник
В OP не упоминались контроллеры представлений, но в ответах так много ответов, что я хотел бы рассказать о том, что некоторые из новых функций LLVM позволяют упростить эту задачу при передаче данных из одного контроллера представления в другой, а затем получить некоторые результаты обратно.
Сегменты раскадровки, блоки ARC и LLVM делают это проще, чем когда-либо для меня. Некоторые ответы вышеупомянутых раскадровок и сегментов уже были, но все еще полагались на делегирование. Определение делегатов, безусловно, работает, но некоторым людям может быть легче передавать указатели или блоки кода.
С UINavigators и segues, есть простые способы передачи информации на подчиненный контроллер и получения информации обратно. ARC упрощает передачу указателей на объекты, производные от NSObjects, поэтому, если вы хотите, чтобы вспомогательный контроллер добавил / изменил / изменил некоторые данные для вас, передайте ему указатель на изменяемый экземпляр. Блоки облегчают прохождение действий, поэтому, если вы хотите, чтобы подчиненный контроллер вызывал действие на контроллере более высокого уровня, передайте ему блок. Вы определяете блок для принятия любого количества аргументов, которые имеют смысл для вас. Вы также можете спроектировать API для использования нескольких блоков, если это подходит лучше.
Вот два тривиальных примера клея Segue. Первый простой показывает один параметр, переданный для ввода, второй для вывода.
Этот второй пример показывает передачу блока обратного вызова для второго аргумента. Мне нравится использовать блоки, потому что они держат соответствующие детали близко друг к другу в источнике - источнике более высокого уровня.
источник
Передача данных из ViewController 2 (назначение) в viewController 1 (Source) является более интересной вещью. Предполагая, что вы используете storyBoard, это все, что я узнал:
Это уже обсуждалось здесь.
Я обнаружил, что есть больше способов:
-Использование блокировки обратных вызовов:
использовать его в
prepareForSegue
методе в VC1-Использование раскадровки Unwind (Выход)
Реализуйте метод с аргументом UIStoryboardSegue в VC 1, как этот:
В storyBoard подключите кнопку «Возврат» к зеленой кнопке «Выход» (раскрутить) видеомагнитофона. Теперь у вас есть переход, который «возвращается», поэтому вы можете использовать свойство destinationViewController в prepareForSegue в VC2 и изменить любое свойство VC1, прежде чем оно вернется.
Еще один вариант использования раскадровки Undwind (Exit) - вы можете использовать метод, который вы написали в VC1
А в prepareForSegue из VC1 вы можете изменить любое свойство, которым хотите поделиться.
В обоих вариантах раскрутки вы можете установить свойство тега кнопки и проверить его в prepareForSegue.
Надеюсь, я добавил что-то к обсуждению.
:) ура.
источник
Существует несколько способов обмена данными.
Вы всегда можете поделиться данными, используя
NSUserDefaults
. Установите значение, которым вы хотите поделиться в отношении ключа по вашему выбору, и получите значение,NSUserDefault
связанное с этим ключом, в следующем контроллере представления.Вы можете просто создать недвижимость в
viewcontrollerA
. Создайте объектviewcontrollerA
вviewcontrollerB
и назначьте желаемое значение этому свойству.Вы также можете создавать собственные делегаты для этого.
источник
Если вы хотите передать данные с одного контроллера на другой, попробуйте этот код
FirstViewController.h
SecondViewController.h
FirstViewController.m
источник
Это очень старый ответ, и это анти-шаблон, пожалуйста, используйте делегатов. Не используйте этот подход!
1. Создайте экземпляр первого View Controller во втором View Controller и установите его свойство
@property (nonatomic,assign)
.2. Назначьте
SecondviewController
экземпляр этого контроллера представления.2. Когда вы закончите операцию выбора, скопируйте массив в первый View Controller. Когда вы выгрузите SecondView, FirstView будет содержать данные массива.
Надеюсь это поможет.
источник
Я долго искал это решение, Atlast нашел его. Прежде всего объявите все объекты в вашем файле SecondViewController.h как
Теперь в вашем файле реализации выделите память для таких объектов, как это
Теперь вы выделили память
Array
и объект. Теперь вы можете заполнить эту память, прежде чем нажать этуViewController
Перейдите к вашему SecondViewController.h и напишите два метода
в файле реализации вы можете реализовать функцию
ожидая, что вы
CustomObject
должны иметь функцию установки с ним.Теперь ваша основная работа выполнена. перейти к месту, где вы хотите нажать
SecondViewController
и выполните следующие действияБерегите орфографические ошибки.
источник
Это не способ сделать это, вы должны использовать делегаты, я предполагаю, что у нас есть два контроллера представления ViewController1 и ViewController2, и этот элемент проверки находится в первом, и когда его состояние изменяется, вы хотите сделать что-то в ViewController2, чтобы Чтобы добиться этого надлежащим образом, вы должны сделать следующее:
Добавьте новый файл в ваш проект (протокол Objective-C) Файл -> Новый, теперь назовите его ViewController1Delegate или как хотите, и напишите их между директивами @interface и @end
Теперь перейдите к ViewController2.h и добавьте
затем измените его определение на
Теперь перейдите к ViewController2.m и внутри реализации добавьте:
Теперь перейдите к ViewController1.h и добавьте следующее свойство:
Теперь, если вы создаете ViewController1 внутри ViewController2 после некоторого события, то вы должны сделать это следующим образом, используя файлы NIB:
Теперь все готово, когда вы обнаруживаете событие проверки, измененное в ViewController1, все что вам нужно сделать, это ниже
Пожалуйста, скажите мне, если есть что-то, что не ясно, если я не правильно понял ваш вопрос.
источник
Если вы хотите отправить данные из одного в другой viewController, вот способ:
Скажем, у нас есть viewControllers: viewControllerA и viewControllerB
Теперь в viewControllerB.h
В viewControllerB.m
В viewControllerA.m
Так вот как вы можете передавать данные из viewControllerA в viewControllerB без установки какого-либо делегата. ;)
источник
Я знаю, что это непростая тема, но для тех, кто хочет ответить на этот вопрос с уклоном SWIFT и хочет получить простой пример, здесь мой метод перехода для передачи данных, если вы используете переход, чтобы обойти.
Это похоже на выше, но без кнопок, ярлыков и тому подобное. Просто передавая данные из одного представления в другое.
Настройте раскадровку
Есть три части.
Это очень простой макет представления с переходом между ними.
Вот настройки для отправителя
Вот настройка для приемника.
Наконец, установка для перехода.
Контроллеры представления
Мы придерживаемся этого простого, поэтому никаких кнопок, а не действий, мы просто перемещаем данные от отправителя к получателю при загрузке приложения, а затем выводим переданное значение на консоль.
Эта страница принимает изначально загруженное значение и передает его.
Эта страница просто отправляет значение переменной в консоль при загрузке. К этому моменту наш любимый фильм должен быть в этой переменной.
Вот как вы можете справиться с этим, если хотите использовать переход, и у вас нет страниц под контроллером навигации.
После запуска он должен автоматически переключиться на представление получателя и передать значение от отправителя получателю, отображая значение в консоли.
источник
В моем случае я использовал одноэлементный класс, который может работать как глобальный объект, предоставляя доступ к данным практически из любой точки приложения. Первое, что нужно сделать - создать класс синглтона. Пожалуйста, обратитесь к странице « Как должен выглядеть мой синглтон Objective-C? » И что я сделал для того, чтобы сделать объект глобально доступным, просто импортировал его
appName_Prefix.pch
, чтобы применить оператор импорта во всех классах. Чтобы получить доступ к этому объекту и использовать его, я просто реализовал метод класса для возврата общего экземпляра, который содержит свои собственные переменныеисточник
Существует несколько вариантов передачи данных между контроллерами представления.
Я собираюсь переписать его логику в Swift с последней iOS Framework
Шаг 1. Объявите переменную в ViewControllerB
Шаг 2. Печать переменной в методе ViewControllerB 'ViewDidLoad
Шаг 3. В ViewControllerA передать данные во время проталкивания через контроллер навигации
Итак, вот полный код для:
ViewControllerA
ViewControllerB
Шаг 1. Создайте Segue из ViewControllerA в ViewControllerB и задайте Identifier = showDetailSegue в раскадровке, как показано ниже
Шаг 2. В ViewControllerB объявляем жизнеспособное имя isSomethingEnabled и напечатайте ее значение.
Шаг 3. В ViewControllerA передайте значение isSomethingEnabled при передаче Segue
Итак, вот полный код для:
ViewControllerA
ViewControllerB
Шаг 1. Объявите протокол ViewControllerBDelegate в файле ViewControllerB, но вне класса
Шаг 2. Объявление экземпляра делегированной переменной в ViewControllerB
Шаг 3. Отправка данных для делегата внутри метода viewDidLoad ViewControllerB
Шаг 4. Подтвердите ViewControllerBDelegate в ViewControllerA
Шаг 5. Подтвердите, что вы реализуете делегат в ViewControllerA
Шаг 6. Реализация метода делегата для получения данных в ViewControllerA
Итак, вот полный код для:
ViewControllerA
ViewControllerB
Шаг 1. Установка и публикация данных в наблюдателе уведомлений в ViewControllerB
Шаг 2. Добавьте наблюдателя уведомлений в ViewControllerA
Шаг 3. Получите значение данных уведомления в ViewControllerA
Итак, вот полный код для:
ViewControllerA
ViewControllerB
Шаг 1. Объявление блока в ViewControllerB
var authorizationCompletionBlock: ((Bool) -> ())? = {_ in}
Шаг 2. Установите данные в блоке в ViewControllerB
Шаг 3. Получить данные блока в ViewControllerA
Итак, вот полный код для:
ViewControllerA
ViewControllerB
Вы можете найти полный образец приложения на моем GitHub. Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы по этому вопросу.
источник
Передача данных между FirstViewController в SecondViewController, как показано ниже
Например:
FirstViewController Строковое значение как
так что мы можем передать это значение во второй класс, используя шаг ниже
1> Нам нужно создать строковый объект в файле SecondViewController.h
2> Необходимо объявить свойство, как показано ниже в декларации в файле .h
3> Нужно синтезировать это значение в файле FirstViewController.m ниже объявления заголовка
и в FirstViewController.h:
4> В FirstViewController, из какого метода мы переходим ко второму виду, пожалуйста, напишите ниже код в этом методе.
источник
В настоящее время я участвую в решении этой проблемы с открытым исходным кодом через проект MCViewFactory, который можно найти здесь:
https://github.com/YetiHQ/manticore-iosviewfactory
Идея состоит в том, чтобы подражать парадигме намерений Android, используя глобальную фабрику для управления видом, который вы просматриваете, и используя «намерения» для переключения и передачи данных между представлениями. Вся документация находится на странице github, но вот некоторые основные моменты:
Вы настраиваете все свои представления в файлах .XIB и регистрируете их в делегате приложения при инициализации фабрики.
Теперь, в вашем VC, в любое время, когда вы хотите перейти к новому VC и передать данные, вы создаете новое намерение и добавляете данные в его словарь (saveInstanceState). Затем просто установите текущее намерение фабрики:
Все ваши представления, которые соответствуют этому, должны быть подклассами MCViewController, которые позволяют вам переопределить новый метод onResume:, позволяющий вам получить доступ к данным, которые вы передали.
Надеюсь, что некоторые из вас найдут это решение полезным / интересным.
источник
Создайте свойство на next
view controller .h
и определите getter и setter.Добавьте это
property
в NextVC.h на nextVCДобавить
@synthesize indexNumber;
в NextVC.mИ последнее
источник
Есть множество способов сделать это, и важно выбрать правильный. Вероятно, одно из самых важных архитектурных решений заключается в том, каким образом код модели будет доступен или доступен во всем приложении.
Я написал пост в блоге об этом некоторое время назад: совместное использование кода модели . Вот краткое резюме:
Общие данные
Одним из подходов является разделение указателей на объекты модели между контроллерами представления.
Так как подготовка к переходу является наиболее распространенным, вот пример:
Независимый доступ
Другой подход заключается в одновременной обработке экрана, заполненного данными, и вместо того, чтобы связывать контроллеры представления друг с другом, соединять каждый контроллер представления с единым источником данных, к которому они могут получить доступ независимо.
Наиболее распространенный способ, которым я видел это, - одноэлементный экземпляр. Так что, если ваш объект-одиночка был,
DataAccess
вы могли бы сделать следующее в методе viewDidLoad UIViewController:Есть дополнительные инструменты, которые также помогают передавать данные:
Основные данные
Приятно, что в Core Data есть обратные отношения. Поэтому, если вы хотите просто дать NotesViewController объект notes, вы можете это сделать, потому что он будет иметь обратную связь с чем-то другим, таким как блокнот. Если вам нужны данные на ноутбуке в NotesViewController, вы можете вернуться к графу объектов, выполнив следующие действия:
Подробнее об этом читайте в моем блоге: разделение кода модели
источник
NewsViewController
NewsDetailViewController.h
NewsDetailViewController.m
источник
Делегирование - единственное решение для выполнения таких операций при использовании файлов .xib, однако все ответы, описанные выше, предназначены
storyboard
для файлов .xibs, которые необходимо использовать для делегирования. это единственное решение, которое вы можете.Другое решение - использовать шаблон класса singleton, инициализировать его один раз и использовать во всем приложении.
источник
если вы хотите передать данные из ViewControlerOne во ViewController, попробуйте следующее.
сделать это в ViewControlerOne.h
сделать это в ViewControllerTwo.h
Синтезировать str2 в ViewControllerTwo.m
сделать это в ViewControlerOne.m
на кнопках событие нажатия сделать это ..
сделать это в ViewControllerTwo.m
источник
Вы можете сохранить данные в приложении делегат для доступа к ним через контроллеры представления в вашем приложении. Все, что вам нужно сделать, это создать общий экземпляр делегата приложения
Например
если вы объявите,
NSArray object *arrayXYZ
то вы можете получить к нему доступ в любом контроллере представленияappDelegate.arrayXYZ
источник
Если вы хотите отправить данные из одного в другой viewController, вот способ:
Скажем, у нас есть viewControllers: ViewController и NewViewController.
в ViewController.h
в ViewController.m
В NewViewController.h
В NewViewController.m
Таким образом, мы можем передать данные из одного контроллера представления в другой контроллер представления ...
источник
Мне нравится идея объектов Model и объектов Mock на основе NSProxy для фиксации или отбрасывания данных, если то, что выбирает пользователь, может быть отменено.
Данные легко передавать, так как это один объект или пара объектов, и, если у вас есть, скажем, контроллер UINavigationController, вы можете сохранить ссылку на модель внутри, и все контроллеры push-представления могут получить к ней доступ непосредственно из контроллера навигации.
источник
Я видел много людей, которые усложняли это, используя
didSelectRowAtPath
метод. Я использую Core Data в моем примере.4 строки кода внутри метода, и все готово.
источник
Есть много ответов на эти вопросы, предлагающих много разных способов установить связь с контроллером представления, которые действительно будут работать, но я нигде не вижу упоминания, какой из них лучше всего использовать, а какой избегать.
На практике, на мой взгляд, рекомендуется всего несколько решений:
prepare(for:sender:)
методUIViewController
при использовании раскадровки и seguesРешения, которые я рекомендую НЕ использовать:
Эти решения, хотя и работают в краткосрочной перспективе, вводят слишком много зависимостей, которые искажают архитектуру приложения и впоследствии создают больше проблем.
Для тех, кто заинтересован, я написал несколько статей, в которых более подробно рассматриваются эти вопросы и выделены различные недостатки:
источник