使用委托和传递数据传回数据故事板

时间:2012-07-18 03:47:42

标签: iphone xcode ios5

我正在解决在我正在使用的应用中使用Storyboard的代理问题。我已经回顾了其他一些搜索,包括Passing data back :Delegate method not called,但无济于事。此时,我删除了我的应用程序中的所有内容,除了我的两个视图的基础知识。第一个视图是一个基本的视图控制器,带有一个按钮,当按下该按钮时,会偏移到模态视图,其中在文本字段中输入一个数据。 “模式”视图上有“保存”按钮,按下该按钮后,将返回第一个视图。当然,我也想将输入的数据发送回第一个视图。听起来很简单?当然,但在某些地方,我无法让它发挥作用。似乎我的委托电话从未发出过。这是代码:

MyDayViewController.h - 这是第一个视图控制器

#import <UIKit/UIKit.h>
#import "AddRatingModalViewController.h"

@interface MyDayViewController : UIViewController <AddRatingDelegate>

@property (strong, nonatomic) IBOutlet UIButton *addRatingBtn;
@property (strong, nonatomic) IBOutlet UIButton *addAccompBtn;
@property (strong, nonatomic) IBOutlet UILabel *ratingLabel;

@end

MyDayViewController.m

#import "MyDayViewController.h"

@implementation MyDayViewController
@synthesize addRatingBtn;
@synthesize addAccompBtn;
@synthesize ratingLabel;

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"ToRatingVC"])
{
    NSLog(@"Setting MyDayVC as a delegate of AddRatingMVC");

    AddRatingModalViewController *addRatingController = segue.destinationViewController;
    addRatingController.delegate = self;
}
}

- (void)theSaveButtonTapped:(AddRatingModalViewController *)controller withRating:(NSNumber*) rating
{
NSLog(@"In theSaveButtonTapped method of MyDayVC");
ratingLabel.text = [[NSString alloc]initWithFormat:@"%@", rating];

[self dismissModalViewControllerAnimated:YES];
}

- (void)viewDidUnload
{
[self setAddRatingBtn:nil];
[self setAddAccompBtn:nil];
[self setRatingLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

@end

AddRatingModalViewController.h - 这是模态视图控制器

#import <UIKit/UIKit.h>

@class AddRatingModalViewController;

@protocol AddRatingDelegate
- (void)theSaveButtonTapped:(AddRatingModalViewController *)controller withRating:(NSNumber*) rating;
@end

@interface AddRatingModalViewController : UIViewController

@property (nonatomic, weak) id <AddRatingDelegate> delegate;
@property (strong, nonatomic) IBOutlet UITextField *addRatingTextField;

- (IBAction)cancelBtnPressed:(id)sender;
- (IBAction)saveBtnPressed:(id)sender;

@end

AddRatingModalViewController.m

#import "AddRatingModalViewController.h"

@implementation AddRatingModalViewController
@synthesize addRatingTextField;
@synthesize delegate;

- (IBAction)cancelBtnPressed:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}

- (IBAction)saveBtnPressed:(id)sender {
NSNumber *ratingARMVC = [NSNumber numberWithInteger:[addRatingTextField.text integerValue]];
NSLog(@"The entered Rating in ARMVC is %@", ratingARMVC);

NSLog(@"Telling the MyDayVC Delegate that Save was tapped on the AddRatingTVC");
[self.delegate theSaveButtonTapped:self withRating:ratingARMVC];

}

- (void)viewDidUnload
{
[self setAddRatingTextField:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

@end

控制台的输出如下:

2012-07-16 16:49:16.384 MyDayDelTest[4695:f803] Setting MyDayVC as a delegate of AddRatingMVC
2012-07-16 16:49:39.274 MyDayDelTest[4695:f803] The entered Rating in ARMVC is 7
2012-07-16 16:49:39.275 MyDayDelTest[4695:f803] Telling the MyDayVC Delegate that Save was tapped on the AddRatingTVC

这应该在Save方法中进行委托调用之前。任何帮助将不胜感激!我应该说当我不使用故事板时测试工作,但我确实需要这个与Storyboard一起工作,因为我的应用程序的其余部分使用它们。提前致谢。

1 个答案:

答案 0 :(得分:0)

@ pina0004发现an answer here。总之,如果推送的VC实际上是UINavigationController的根VC,则segue destinationViewController将不会指向推送的VC,而是(不太直观地)指向作为根的导航控制器。

这已经解决了,但我认为这是过度使用委托模式的一个例子。在这种情况下,推送的VC需要将字符串报告回原始字符串,并且问题使用指向原始的委托指针,谁只是“委托”工作是保存字符串并关闭模态VC。我认为有更好的选择:

  • 传递模型:不是告诉推送的VC推送VC是谁,而是给它一个指向它的模型的指针(在这种情况下,是字符串)。让推送的VC改变模型,然后使用几种技术中的一种让推动者发现模型已经改变。
  • 解雇自己:从命名方法的方式来看,它并不是很明显,但是模态呈现的VC可以解雇自己。推送VC可以在它的viewWillAppear方法中检查模型状态,该方法将在推送的VC即将消失时运行。
  • KVO:原始VC可以要求在特定模型属性更改时得到通知。这将使推动找出模型状态变化,并在需要时解除模态VC。
  • Notification:推送的VC或模型可以发布状态更改通知。推送VC可以订阅并响应。这对于可能对应用程序更感兴趣的状态更改特别有用。
  • Blocks:推送VC可以使用块来移交一些在重要事件发生时应该运行的代码。该块在推送VC的上下文中运行。这是一种非常易读的方法,可以将代码的因果块保持在彼此附近,甚至可以共享相同的变量名称。