使用后退按钮将数据传递到ViewController

时间:2012-11-23 18:56:12

标签: objective-c ios xcode

我在ViewA中有多个按钮。单击按钮时,会将其重定向到ViewB。在ViewB中,用户进行一些交互,然后在完成后单击后退按钮。如何运行方法并将参数从ViewB传递到ViewA,然后继续在ViewA中工作?

强烈要求使用后退按钮,但我很想知道是否还有其他方法。

我的想法是从堆栈中获取ViewA,当我完成ViewB时,只需调用它并重定向,但我无法弄清楚如何做到这一点。

谢谢。

5 个答案:

答案 0 :(得分:4)

您想在ViewB中定义委托并在ViewA中实现它。在适当的时间(例如,当点击后退按钮时)ViewB调用委托方法,将值作为参数传递。

这样的事情:

ViewB.h

// Define a delegate protocol allowing 
@protocol ViewBDelegate

// Method of delegate called when user taps the 'back' button
-(void) backButtonSelected:(id) object;

@end


@interface ViewB : UIViewController

// property to hold a reference to the delegate
@property (weak)id<ViewBDelegate> delegate;

-(IBAction)backButtonSelected:(id)sender;

@end

ViewB.m:

@implementation ViewB

...

-(IBAction)backButtonSelected:(id)sender{
    NSObject *someObjectOrValue = nil;

    // Invoke the delegates backButtonSelected method, 
    // passing the value/object of interest
    [self.delegate backButtonSelected:someObjectOrValue];
}

@end

ViewA.h:

#import "ViewB.h"


//  The identifier in pointy brackets (e.g., <>) defines the protocol(s)
// ViewA implements
@interface ViewA : UIViewController <ViewBDelegate>

...

-(IBAction)someButtonSelected:(id)sender;

@end

ViewA.m:

- (IBAction)someButtonSelected:id     @implementation ViewA

...

// Called when user taps some button on ViewA (assumes it is "hooked up" 
// in the storyboard or IB
-(IBAction)someButtonSelected:(id)sender{

    // Create/get reference to ViewB.  May be an alloc/init, getting from storyboard, etc.
    ViewB *viewB = // ViewB initialization code

    // Set `ViewB`'s delegate property to this instance of `ViewA`
    viewB.delegate = self;
    ...
}

// The delegate method (defined in ViewB.h) this class implements
-(void)backButtonSelected:(id)object{
    // Use the object pass as appropriate
}

@end

答案 1 :(得分:2)

在iOS6中,您现在可以使用Unwind Segues。在Storyboard中,您可能已经注意到可以用于此的新的“退出”按钮。

展开Segues将允许您从viewControllerB转换回viewControllerA并通过prepareForSegue方法提供信息。

目前文档相当有限,但有一个有用的WWDC2012视频如何执行此操作(会话236)

答案 2 :(得分:1)

如果您不想实现协议,那么其他方式是,您可以在类型为id的ViewB中创建属性,如此

  

@property(nonatomic,unsafe_unretained)id * parentView;

按此方式推送ViewB时将其设置为ViewA

  

ViewB.parentView = ViewA;       //推ViewB

然后您可以直接使用此属性调用ViewA的方法。

答案 3 :(得分:0)

您可以在ViewControllerA中定义协议,示例名称为ViewControllerADelegate,在ViewControllerB中创建属性委托,在ViewControllerB中实现ViewControllerA中定义的协议。

当您在viewControllerB中工作时,您可以通知您对ViewControllerAelegate中定义的viewControllerA调用方法的所有更改,当您离开viewControllerB时,您将更新viewControllerA。

答案 4 :(得分:0)

如果您的ViewA正在创​​建ViewB,您可以在ViewB.h上创建协议并将ViewA设置为ViewB的委托。因此,无论何时在ViewB中更改内容,都可以直接通知ViewA。

根据您的型号,您可以拥有一个类,其中包含您在ViewB中修改的任何设置。当您创建ViewB时,您可以正常传递引用,并且因为它是一个对象,所以实例将被共享,因此当您返回ViewA时,所有更改都已应用。

viewB.settings = self.settings; // or whatever model object you have

另一种选择是创建一个自定义后退按钮(你将失去尖尖的外观),让它调用你的自定义方法通知你的ViewA然后做[self.navigationController popViewControllerAnimated:YES];