Как пройти prepareForSegue: объект
У меня много аннотаций в mapview (с кнопками rightCalloutAccessory
). Кнопка будет выполнять отступ от этого mapview
до tableview
. Я хочу передать tableview
другому объекту (который хранит данные) в зависимости от того, какая кнопка вызова была нажата.
Например: (полностью составлено)
- annotation1 (Austin) → передать данные obj 1 (относится к Austin)
- annotation2 (Даллас) → передавать данные obj 2 (относится к Далласу)
- annotation3 (Хьюстон) → передавать данные obj 3 и т.д. (вы получаете
идея)
Я могу определить, какая кнопка выноски была нажата.
Я использую prepareForSegue
: для передачи данных obj в пункт назначения ViewController
. Поскольку я не могу сделать этот вызов, возьму дополнительный аргумент для данных obj, которые мне нужны, какие изящные способы добиться того же эффекта (динамические данные obj)?
Приветствуется любой совет.
Ответы
Ответ 1
Просто возьмите ссылку на контроллер целевого представления в prepareForSegue:
и передайте любые объекты, которые вам нужны. Вот пример...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}
ПЕРЕСМОТР: вы также можете использовать метод performSegueWithIdentifier:sender:
для активации перехода к новому представлению на основе выбора или нажатия кнопки.
Например, рассмотрим, что у меня есть два контроллера представления. Первый содержит три кнопки, а второй должен знать, какая из этих кнопок была нажата до перехода. Вы можете подключить кнопки до IBAction
в своем коде, который использует метод performSegueWithIdentifier:
, например этот...
// When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:@"MySegue" sender:sender];
}
// This will get called too before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"MySegue"]) {
// Get destination view
SecondView *vc = [segue destinationViewController];
// Get button tag number (or do whatever you need to do here, based on your object
NSInteger tagIndex = [(UIButton *)sender tag];
// Pass the information to your destination view
[vc setSelectedButton:tagIndex];
}
}
EDIT: демо-приложение, которое я первоначально приложил, теперь составляет шесть лет, поэтому я удалил его, чтобы избежать путаницы.
Ответ 2
Иногда полезно избегать создания зависимости во время компиляции между двумя контроллерами представления. Вот как вы можете сделать это, не заботясь о типе контроллера представления назначения:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector:@selector(setMyData:)]) {
[segue.destinationViewController performSelector:@selector(setMyData:)
withObject:myData];
}
}
Таким образом, пока ваш конечный контроллер представления объявляет открытое свойство, например:
@property (nonatomic, strong) MyData *myData;
Вы можете установить это свойство в предыдущем контроллере представления, как я описал выше.
Ответ 3
В Swift 4.2 я бы сделал что-то подобное:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let yourVC = segue.destination as? YourViewController {
yourVC.yourData = self.someData
}
}
Ответ 4
У меня есть класс отправителя, вроде этого
@class MyEntry;
@interface MySenderEntry : NSObject
@property (strong, nonatomic) MyEntry *entry;
@end
@implementation MySenderEntry
@end
Я использую этот класс отправителя для передачи объектов в prepareForSeque:sender:
-(void)didSelectItemAtIndexPath:(NSIndexPath*)indexPath
{
MySenderEntry *sender = [MySenderEntry new];
sender.entry = [_entries objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:SEGUE_IDENTIFIER_SHOW_ENTRY sender:sender];
}
-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_SHOW_ENTRY]) {
NSAssert([sender isKindOfClass:[MySenderEntry class]], @"MySenderEntry");
MySenderEntry *senderEntry = (MySenderEntry*)sender;
MyEntry *entry = senderEntry.entry;
NSParameterAssert(entry);
[segue destinationViewController].delegate = self;
[segue destinationViewController].entry = entry;
return;
}
if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_HISTORY]) {
// ...
return;
}
if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_FAVORITE]) {
// ...
return;
}
}
Ответ 5
Я столкнулся с этим вопросом, когда пытался узнать, как передавать данные с одного контроллера просмотра на другой. Мне нужно что-то визуальное, чтобы помочь мне учиться, поэтому этот ответ является дополнением к другим, уже здесь. Это немного более общий, чем исходный вопрос, но он может быть адаптирован для работы.
Этот базовый пример работает следующим образом:
![введите описание изображения здесь]()
Идея состоит в том, чтобы передать строку из текстового поля в First View Controller на метку во втором контроллере представления.
Контроллер первого взгляда
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
// This function is called before the segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// get a reference to the second view controller
let secondViewController = segue.destinationViewController as! SecondViewController
// set a variable in the second view controller with the String to pass
secondViewController.receivedString = textField.text!
}
}
Второй контроллер просмотра
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
// This variable will hold the data being passed from the First View Controller
var receivedString = ""
override func viewDidLoad() {
super.viewDidLoad()
// Used the text from the First View Controller to set the label
label.text = receivedString
}
}
Не забывайте
- Сделайте шаг control нажатием на кнопку и перетащите ее во второй контроллер просмотра.
- Подключите выходы для
UITextField
и UILabel
.
- Установите первый и второй контроллеры просмотра в соответствующие файлы Swift в IB.
Источник
Как отправить данные через segue (swift) (учебник YouTube)
См. также
Просмотр контроллеров: передача данных вперед и передача данных назад (более полный ответ)
Ответ 6
Я реализовал библиотеку с категорией на UIViewController, которая упрощает эту операцию.
В принципе, вы устанавливаете параметры, которые хотите передать в NSDictionary, связанные с элементом пользовательского интерфейса, который выполняет сеанс. Он также работает с ручными сегментами.
Например, вы можете сделать
[self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
для ручного переключения или создать кнопку с шагом и использовать
[button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
Если контроллер точки доступа не соответствует кодированию ключевого значения для ключа, ничего не происходит. Он также работает с ключевыми значениями (полезно для разматывания секций).
Проверьте это здесь
https://github.com/stefanomondino/SMQuickSegue
Ответ 7
Для Swift используйте это,
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var segueID = segue.identifier
if(segueID! == "yourSegueName"){
var yourVC:YourViewController = segue.destinationViewController as YourViewController
yourVC.objectOnYourVC = setObjectValueHere!
}
}
Ответ 8
Мое решение похоже.
// In destination class:
var AddressString:String = String()
// In segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "seguetobiddetailpagefromleadbidder")
{
let secondViewController = segue.destinationViewController as! BidDetailPage
secondViewController.AddressString = pr.address as String
}
}
Ответ 9
Просто используйте эту функцию.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let index = CategorytableView.indexPathForSelectedRow
let indexNumber = index?.row
let VC = segue.destination as! DestinationViewController
VC.value = self.data
}
Ответ 10
Я использовал это решение, чтобы я мог поддерживать вызов segue и обмена данными в рамках одной и той же функции:
private var segueCompletion : ((UIStoryboardSegue, Any?) -> Void)?
func performSegue(withIdentifier identifier: String, sender: Any?, completion: @escaping (UIStoryboardSegue, Any?) -> Void) {
self.segueCompletion = completion;
self.performSegue(withIdentifier: identifier, sender: sender);
self.segueCompletion = nil
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
self.segueCompletion?(segue, sender)
}
Пример использования:
func showData(id : Int){
someService.loadSomeData(id: id) {
data in
self.performSegue(withIdentifier: "showData", sender: self) {
storyboard, sender in
let dataView = storyboard.destination as! DataView
dataView.data = data
}
}
}
Это, похоже, работает для меня, однако я не уверен на 100%, что функции выполнения и подготовки всегда выполняются в одном потоке.