I have many annotations in a mapview (with rightCalloutAccessory
buttons). The button will perform a segue from this mapview
to a tableview
. I want to pass the tableview
a different object (that holds data) depending on which callout button was clicked.
我在mapview中有许多注释(带有rightCalloutAccessory按钮)。这个按钮将从这个mapview执行一个segue到一个tableview。我希望根据单击的callout按钮向tableview传递一个不同的对象(它保存数据)。
For example: (totally made up)
例如:(完全化妆)
I am able to detect which callout button was clicked.
我可以检测哪个callout按钮被单击。
I'm using prepareForSegue
: to pass the data obj to the destination ViewController
. Since I cannot make this call take an extra argument for the data obj I require, what are some elegant ways to achieve the same effect (dynamic data obj)?
我正在使用prepareForSegue:将数据obj传递给目标视图控制器。由于我不能对我需要的数据obj进行额外的参数调用,那么有什么优雅的方法可以达到相同的效果(动态数据obj)?
Any tip would be appreciated.
如有任何提示,我们将不胜感激。
658
Simply grab a reference to the target view controller in prepareForSegue:
method and pass any objects you need to there. Here's an example...
只需在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];
}
}
REVISION: You can also use performSegueWithIdentifier:sender:
method to activate the transition to a new view based on a selection or button press.
修订:您还可以使用performSegueWithIdentifier:sender:方法根据选择或按下按钮激活到新视图的转换。
For instance, consider I had two view controllers. The first contains three buttons and the second needs to know which of those buttons has been pressed before the transition. You could wire the buttons up to an IBAction
in your code which uses performSegueWithIdentifier:
method, like this...
例如,假设我有两个视图控制器。第一个包含三个按钮,第二个需要知道在转换之前按了哪些按钮。您可以将这些按钮连接到代码中的IBAction,它使用performSegueWithIdentifier: method,如下所示…
// 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: The demo application I originally attached is now six years old, so I've removed it to avoid any confusion.
编辑:我最初附加的演示应用程序现在已经有6年的历史了,所以我删除了它以避免任何混淆。
81
The accepted answer is not the best way of doing this, because it creates an unnecessary compile-time dependency between two view controllers. Here's how you can do it without caring about the type of the destination view controller:
公认的答案不是最好的方法,因为它在两个视图控制器之间创建了不必要的编译时依赖。以下是如何在不考虑目标视图控制器类型的情况下完成的:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector:@selector(setMyData:)]) {
[segue.destinationViewController performSelector:@selector(setMyData:)
withObject:myData];
}
}
So as long as your destination view controller declares a public property, e.g.:
因此,只要您的目标视图控制器声明公共属性,例如:
@property (nonatomic, strong) MyData *myData;
you can set this property in the previous view controller as I described above.
如前所述,可以在前面的视图控制器中设置此属性。
19
In Swift I would do something like that:
在《Swift》中,我会这样做:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let yourVC = segue.destinationViewController as? YourViewController {
yourVC.yourData = self.someData
}
}
16
I have a sender class, like this
我有一个sender类,像这样
@class MyEntry;
@interface MySenderEntry : NSObject
@property (strong, nonatomic) MyEntry *entry;
@end
@implementation MySenderEntry
@end
I use this sender class for passing objects to prepareForSeque:sender:
我使用这个sender类将对象传递给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;
}
}
11
I came across this question when I was trying to learn how to pass data from one View Controller to another. I need something visual to help me learn though, so this answer is a supplement to the others already here. It is a little more general than the original question but it can be adapted to work.
我在学习如何将数据从一个视图控制器传递到另一个视图控制器时遇到了这个问题。我需要一些视觉上的东西来帮助我学习,所以这个答案是对其他已经存在的答案的补充。它比最初的问题更一般一些,但是它可以用于工作。
This basic example works like this:
这个基本示例如下所示:
The idea is to pass a string from the text field in the First View Controller to the label in the Second View Controller.
其思想是将字符串从第一个视图控制器中的文本字段传递给第二个视图控制器中的标签。
First View Controllerimport 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!
}
}
Second View Controller
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
}
}
Remember to
UITextField
and the UILabel
.How to send data through segue (swift) (YouTube tutorial)
如何通过segue (swift)发送数据(YouTube教程)
See alsoView Controllers: Passing data forward and passing data back (fuller answer)
视图控制器:向前传递数据并返回数据(更完整的答案)
4
I've implemented a library with a category on UIViewController that simplifies this operation. Basically, you set the parameters you want to pass over in a NSDictionary associated to the UI item that is performing the segue. It works with manual segues too.
我在UIViewController中实现了一个类的库,它简化了这个操作。基本上,您设置了要在与执行segue的UI项相关的NSDictionary中传递的参数。它也适用于手动segue。
For example, you can do
例如,你可以这样做
[self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
for a manual segue or create a button with a segue and use
用于手动segue或使用segue创建按钮
[button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
If destination view controller is not key-value coding compliant for a key, nothing happens. It works with key-values too (useful for unwind segues). Check it out here https://github.com/stefanomondino/SMQuickSegue
如果目标视图控制器不符合键值编码,则不会发生任何事情。它也适用于键值(对展开segue很有用)。在这里查看https://github.com/stefanomondino/SMQuickSegue
4
For Swift use this,
斯威夫特用这个,
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var segueID = segue.identifier
if(segueID! == "yourSegueName"){
var yourVC:YourViewCOntroller= segue.destinationViewController as YourViewController
yourVC.objectOnYourVC= setObjectValueHere!
}
}
2
My solution is similar.
我的解决方案是相似的。
// 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
}
}
0
I used this solution so that I could keep the invocation of the segue and the data communication within the same function:
我使用了这个解决方案,这样我就可以在同一个函数中调用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)
}
A use case would be something like:
一个用例应该是这样的:
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
}
}
}
This seems to work for me, however, I'm not 100% sure that the perform and prepare functions are always executed on the same thread.
但是,这似乎对我来说是有效的,但是,我不能百分之百地确定执行和准备函数总是在同一个线程上执行。
0
Just use this function.
使用这个函数。
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
}