将数据传回前一个视图控制器
我正在尝试将数据传回给以前的viewController。
有谁知道如何将数据从ViewController B传递给ViewController A? 所以我想要一个string从'BIDAddTypeOfDealViewController'到BIDDCCreateViewController。 用户编辑viewController B,我想在编辑的数据返回ViewController A,然后我使用它。
我正在使用此答案的“传回数据”部分。 我的不同之处:第3点和第6点刚刚提到,当视图popup,所以我把这个代码在viewWillDisappear。 我认为这是正确的? 同样在第六点,我没有用笔尖初始化,因为这是旧的。 我正在使用故事板。 而且我没有添加最后一行,因为我不相信我会推它。 按下我的故事板上的一个button已经把我推进了。
我认为这个问题可能出现在BIDDCCreateViewController,我有方法,但我不能运行它。 运行一个方法,它应该去[自我方法]。 我无法做到这一点。 那么这正是我所猜测的。
它编译和运行良好,没有任何logging,所以我不知道它是否工作。
更新:我无法获得'sendDataToA'方法执行。
#import <UIKit/UIKit.h> #import "BIDAddTypeOfDealViewController.h" @interface BIDDCCreateViewController : UIViewController @property (strong, nonatomic) NSString *placeId; - (IBAction)gotoBViewController:(id)sender; @end #import "BIDDCCreateViewController.h" #import "BIDAddTypeOfDealViewController.h" @implementation BIDDCCreateViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NSLog(@"SUCCESSFULLY PASSED PLACE ID: %@", self.placeId); } -(void)sendDataToA:(NSString *)myStringData { NSLog(@"Inside sendDataToA"); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Your string Data Showing" message:myStringData delegate:self cancelButtonTitle:@"Ok " otherButtonTitles:nil]; [alert show]; } - (IBAction)gotoBViewController:(id)sender { NSLog(@"pressed"); BIDAddTypeOfDealViewController *bidAddType = [[BIDAddTypeOfDealViewController alloc]init]; bidAddType.delegate = self; } @end @protocol senddataProtocol <NSObject> -(void)sendDataToA:(NSString *)myStringData; @end #import <UIKit/UIKit.h> @interface BIDAddTypeOfDealViewController : UIViewController <UITextFieldDelegate>//Using this delegate for data a user inputs @property(nonatomic,assign)id delegate; //other textfield outlets not relevant - (IBAction)chooseDiscountDeal:(id)sender; @end #import "BIDAddTypeOfDealViewController.h" @interface BIDAddTypeOfDealViewController () @end @implementation BIDAddTypeOfDealViewController @synthesize delegate; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; } -(void)viewWillDisappear:(BOOL)animated { [delegate sendDataToA:@"Apple"]; } @end
您可以使用委托。 因此,在您的ViewController B中,您需要创build一个协议,将数据发送回您的ViewController A.您的ViewController A将成为ViewController B的代理。
如果您是客观C的新手,请查看什么是代表 。
在ViewControllerB.h中创build协议:
#import <UIKit/UIKit.h> @protocol senddataProtocol <NSObject> -(void)sendDataToA:(NSArray *)array; //I am thinking my data is NSArray, you can use another object for store your information. @end @interface ViewControllerB : UIViewController @property(nonatomic,assign)id delegate;
ViewControllerB.m
@synthesize delegate; -(void)viewWillDisappear:(BOOL)animated { [delegate sendDataToA:yourdata]; }
在你的ViewControllerA中:当你去ViewControllerB
ViewControllerA *acontollerobject=[[ViewControllerA alloc] initWithNibName:@"ViewControllerA" bundle:nil]; acontollerobject.delegate=self; // protocol listener [self.navigationController pushViewController:acontollerobject animated:YES];
并定义你的function:
-(void)sendDataToA:(NSArray *)array { // data will come here inside of ViewControllerA }
编辑:
你可以看看这个例子:你如何将数据传递回前一个viewcontroller: 教程链接
比协议/委托更简单的方法是创build一个闭包:
在我的情况下发送一个string。 在ViewControllerA中:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let viewControllerB = segue.destination as? ViewControllerB { viewControllerB.callback = { message in //Do what you want in here! } } }
在ViewControllerB中:
var callback : ((String) -> Void)? @IBAction func done(sender: AnyObject) { callback?("Hi") self.dismiss(animated: true, completion: nil) }
Swift:使用委托模式发回数据
我的完整答案涵盖了双向传递数据在这里 。 我的答案解释委托模式在这里 。
要将数据从第二个视图控制器传回第一个视图控制器,可以使用协议和委托。 这个video虽然是一个非常清晰的过程:
- YouTube教程: iOS Swift基础教程:协议和代表 。 但也读这篇文章 ,以确保你没有进入一个强有力的参考周期。
以下是基于video的示例(进行一些修改)。
在Interface Builder中创build故事板布局。 再次,为了使segue,你只需控制从button拖动到第二个视图控制器。 将segue标识符设置为showSecondViewController
。 此外,不要忘记使用以下代码中的名称来连接sockets和操作。
第一视图控制器
第一个视图控制器的代码是
import UIKit class FirstViewController: UIViewController, DataEnteredDelegate { @IBOutlet weak var label: UILabel! override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "showSecondViewController" { let secondViewController = segue.destinationViewController as! SecondViewController secondViewController.delegate = self } } func userDidEnterInformation(info: String) { label.text = info } }
请注意使用我们自定义的DataEnteredDelegate
协议。
第二个视图控制器和协议
第二个视图控制器的代码是
import UIKit // protocol used for sending data back protocol DataEnteredDelegate: class { func userDidEnterInformation(info: String) } class SecondViewController: UIViewController { // making this a weak variable so that it won't create a strong reference cycle weak var delegate: DataEnteredDelegate? = nil @IBOutlet weak var textField: UITextField! @IBAction func sendTextBackButton(sender: UIButton) { // call this method on whichever class implements our delegate protocol delegate?.userDidEnterInformation(textField.text!) // go back to the previous view controller self.navigationController?.popViewControllerAnimated(true) } }
请注意, protocol
不在View Controller类中。
而已。 现在运行应用程序,您应该能够从第二个视图控制器发回数据到第一个。
编辑:使用@ Erhan的解决scheme上面。 不是这个。 这不是一个好的解决scheme。
这将有所帮助。 写在你的ViewControllerB。
// Get array of current navigation stack NSArray *arrayViewControllers = [self.navigationController viewControllers]; // Get previous viewController object from it YOUR_VIEW_CONTROLLER_NAME *objViewController = (YOUR_VIEW_CONTROLLER_NAME *)[arrayViewControllers objectAtIndex:arrayViewControllers.count-2]; // For safety this check is needed. whether it the class that you want or not. if ([objViewController isKindOfClass:[YOUR_VIEW_CONTROLLER_NAME class]]) { // Access properties of YOUR_VIEW_CONTROLLER_NAME here objViewController.yourProperty = YOUR_VALUE; }
正如Erhan Demirci所回答的,您可以使用代表。 当您想要将数据传递给单个视图控制器时,代表会很有帮助。
NSNotificationCenter
是在视图控制器/对象之间传输数据的另一种方便的方法。 这对于在应用程序内广播数据非常有帮助。
在这里阅读文档。
自定义委托是移动数据的最佳select,但您也可以尝试这一点。
你可以使用NSUserDefaults将数据移动到任何你想要的地方。
Swift 3代码
UserDefaults.standard.set(<Value>, forKey: <Key>) // To set data UserDefaults.standard.object(forKey: <Key>) // To get data
您也可以使用NSNotification移动数据。
NotificationCenter.default.post(name: Notification.Name(rawValue: "refresh"), object: myDict) NotificationCenter.default.addObserver(self, selector: #selector(refreshList(_:)), name: NSNotification.Name(rawValue: "refresh"), object: nil)
这是我该怎么做的。
@interface ViewControllerA:UIViewController @property(strong, nonatomic) ViewControllerB * recieverB; @end @implementation ViewControllerA //implement class - (void)prepareForSegue:(UIStoryboardSegue *) sender:(id)sender { segue.destinationViewController.recieverA = self; } -(void)viewDidLoad { //stop strong refrence cycle self.viewControllerB = nil; } @end
B类
@interface ViewControllerB:UIViewController @property(strong, nonatomic, getter = parentClass) ViewControllerB * recieverA; @end @implementation ViewControllerB //implement class - (void)viewWillDisappear:(BOOL)animated { parentClass.recieverB = self; //now class A will have an instance on class b } @end
我没有把#import