如何传递prepareForSegue:一个对象

我在mapview中有许多注释(带有rightCalloutAccessory按钮)。该按钮将执行一个从mapviewtableview的segue。我想传递给tableview一个不同的对象(保存数据),这取决于单击了哪个callout按钮。

例如:(完全是瞎编的)

  • 注释1 (Austin) ->传递数据obj 1(与Austin相关)
  • 注释2(达拉斯)->传递数据obj 2(有关达拉斯)
  • annotation3 (Houston) -> pass data obj 3等等…(你会得到 李主意)< / >

我能够检测到哪个调出按钮被单击。

我使用prepareForSegue:将数据对象传递给目标ViewController。由于我不能使这个调用为我需要的数据对象额外的参数,有什么优雅的方法来实现相同的效果(动态数据对象)?

任何建议都将不胜感激。

356205 次浏览

只需在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:方法来激活到一个基于选择或按钮按下的新视图的转换。

例如,假设我有两个视图控制器。第一个包含三个按钮,第二个需要知道在转换之前按下了哪个按钮。你可以在你的代码中使用performSegueWithIdentifier:方法将按钮连接到IBAction,像这样…

// 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];
}
}

编辑:我最初附上的演示应用程序现在已经有6年了,所以我删除了它以避免任何混淆。

有时避免在两个视图控制器之间创建编译时依赖关系是有帮助的。下面是你不用关心目标视图控制器的类型就能做到的方法:

- (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;

你可以在前面的视图控制器中设置这个属性。

我有一个发送方类,像这样

@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;
}
}
我已经在UIViewController上实现了一个类库,简化了这个操作。 基本上,你在NSDictionary中设置你想要传递的参数与执行segue的uiitem关联。

例如,你可以这样做

[self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];

对于手动segue或者创建一个带有segue的按钮并使用

[button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
如果目标视图控制器不符合键的键值编码,什么都不会发生。它也适用于键值(对unwind segue很有用)。 点击这里查看 https://github.com/stefanomondino/SMQuickSegue < / p >

对于斯威夫特使用这个,

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var segueID = segue.identifier


if(segueID! == "yourSegueName"){


var yourVC:YourViewController = segue.destinationViewController as YourViewController


yourVC.objectOnYourVC = setObjectValueHere!


}
}

在Swift 4.2中,我会这样做:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let yourVC = segue.destination as? YourViewController {
yourVC.yourData = self.someData
}
}

当我试图学习如何将数据从一个视图控制器传递到另一个视图控制器时,我遇到了这个问题。我需要一些直观的东西来帮助我学习,所以这个答案是对已有答案的补充。它比原来的问题更一般一点,但它可以适用于工作。

这个基本的例子是这样的:

enter image description here

这个想法是从第一个视图控制器的文本字段传递一个字符串到第二个视图控制器的标签。

第一视图控制器

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
}


}

记得

  • 通过控制单击按钮并将其拖到第二个视图控制器来创建segue。
  • 连接UITextFieldUILabel的outlet。
  • 将第一个和第二个视图控制器设置为IB中适当的Swift文件。

如何通过segue发送数据(swift) (YouTube教程)

另请参阅

视图控制器:向前传递数据和向后传递数据(更完整的答案)

我的解决方案是类似的。

// 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
}
}

我使用这个解决方案,这样我就可以在同一个函数中保持对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%确定perform和prepare函数总是在同一个线程上执行。

用这个函数。

 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


}