私は(rightCalloutAccessory
ボタンを使って)mapviewにたくさんのアノテーションを持っています。ボタンはこのmapview
からtableview
へのセグエスを実行します。どのコールアウトボタンがクリックされたかに応じてtableview
に異なるオブジェクト(データを保持する)を渡したいです。
例えば:(完全に構成されている)
どの吹き出しボタンがクリックされたかを検出できます。
prepareForSegue
:を使用して、データobjを宛先のViewController
に渡します。この呼び出しで、必要なデータオブジェクトに対して余分な引数を取ることはできません。同じ効果を得るための優れた方法は何ですか(動的データオブジェクト)。
どんなチップでも評価されるでしょう。
prepareForSegue:
メソッドでターゲットのView Controllerへの参照を取得し、必要なオブジェクトをそこに渡します。これは一例です...
- (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:
メソッドを使用して、選択またはボタンを押すことに基づいて新しいビューへのトランジションをアクティブにすることもできます。
たとえば、View Controllerが2つあるとします。最初のボタンは3つのボタンを含み、2番目のボタンはトランジションの前にどのボタンが押されたかを知る必要があります。このように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歳ですので、混乱を避けるために削除しました。
場合によっては、2つのView Controller間にコンパイル時の依存関係を作成しないようにすると便利です。移動先のView Controllerの種類を気にせずにそれを実行する方法は次のとおりです。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector:@selector(setMyData:)]) {
[segue.destinationViewController performSelector:@selector(setMyData:)
withObject:myData];
}
}
送信先のView Controllerがパブリックプロパティを宣言している限り、以下のようになります。
@property (nonatomic, strong) MyData *myData;
上記のように、前のView Controllerでこのプロパティを設定できます。
Swift 4.2では、次のようにします。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let yourVC = segue.destination as? YourViewController {
yourVC.yourData = self.someData
}
}
私はこのように送信者クラスを持っています
@class MyEntry;
@interface MySenderEntry : NSObject
@property (strong, nonatomic) MyEntry *entry;
@end
@implementation MySenderEntry
@end
私はオブジェクトをprepareForSeque:sender:
に渡すためにこのsender classを使います
-(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;
}
}
あるView Controllerから別のView Controllerにデータを渡す方法を学ぼうとしていたときに、この質問に出会いました。私は私が学ぶのを助けるために何か視覚的なものが必要なので、この答えはすでにここにいる他の人への補足です。それは元の質問よりももう少し一般的ですが、動作するように調整することができます。
この基本的な例は次のように機能します。
これは、First View ControllerのテキストフィールドからSecond 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
}
}
UITextField
とUILabel
のアウトレットを接続します。どのようにsegue(Swift)を通してデータを送信する (YouTubeチュートリアル)
View Controllers:データの受け渡しとデータの受け渡し (より完全な答え)
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!
}
}
この操作を簡単にするために、UIViewControllerにカテゴリを持つライブラリを実装しました。基本的には、セグエを実行しているUIアイテムに関連付けられたNSDictionaryに、渡したいパラメータを設定します。これは手動のセグエでも動作します。
たとえば、
[self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
手動セグエ用、またはセグエ付きのボタンを作成して使用する
[button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
変換先View Controllerがキーに対応したキー値コーディングに準拠していない場合は、何も起こりません。これはKey-Valueでも機能します(くつろいだセグエに役立ちます)。ここからチェックしてください https://github.com/stefanomondino/SMQuickSegue
私の解決策は似ています。
// 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
}
}
この機能を使うだけです。
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
}
私は、この機能を使用して、セグエの呼び出しとデータ通信を同じ機能内で維持できるようにしました。
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
}
}
}
これは私にはうまくいくようですが、perform関数とprepare関数が常に同じスレッドで実行されるとは限りません。