在 ViewControllerB 到 ViewControllerA 之间传递数据,委托不会被调用
Posted
技术标签:
【中文标题】在 ViewControllerB 到 ViewControllerA 之间传递数据,委托不会被调用【英文标题】:Passing data between ViewControllerB to ViewControllerA, Delegate not get called 【发布时间】:2014-07-28 09:54:31 【问题描述】:我尝试使用委托但没有成功,委托没有被调用。 这是我的委托代码:
设置委托(ViewControllerB)
@class SearchGardenTable;
@protocol SearchGardenDelegate <NSObject>
- (void)addItemViewController:(SearchGardenTable *)controller didFinishWithGardenID:(NSString *)gardenID gardenName:(NSString*)gardenName andCityName:(NSString*)cityName;
@end
@interface SearchGardenTable : UITableViewController
@property (nonatomic, weak) id <SearchGardenDelegate> delegate;
@end
告诉 VC B VC A 是它的代表:
// in VC A viewDidLoad.
self.searchGarden = [[SearchGardenTable alloc]init];
[self.searchGarden setDelegate:self];
VC A 采用协议
@interface AddKid () <MZFormSheetBackgroundWindowDelegate,SearchGardenDelegate>
@end
@implementation AddKid
设置我想从 VC B 传回 VC A 的参数:
_kidGaedenID = [temp objectAtIndex:indexPath.row];
_kidGardenName = [temp1 objectAtIndex:indexPath.row];
[self.delegate addItemViewController:self didFinishWithGardenID:_kidGaedenID gardenName:_kidGardenName andCityName:_kidCityName];
在VC A实现协议方法:
- (void)addItemViewController:(SearchGardenTable *)controller didFinishWithGardenID:(NSString *)gardenID gardenName:(NSString*)gardenName andCityName:(NSString*)cityName
_kidGardenID = gardenID;
_gardenName.text = gardenName;
_kidCity.text = cityName;
编辑
ViewController B didSelectRowAtIndexPath: code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
NSArray *temp = [_responseDict valueForKey:@"ID"];
NSArray *temp1 = [_responseDict valueForKey:@"name"];
_kidGaedenID = [temp objectAtIndex:indexPath.row];
_kidGardenName = [temp1 objectAtIndex:indexPath.row];
[[self delegate] addItemViewController:self didFinishWithGardenID:_kidGaedenID gardenName:_kidGardenName andCityName:_kidCityName];
[self mz_dismissFormSheetControllerAnimated:YES completionHandler:^(MZFormSheetController *formSheetController)
//dismiss the popup view which i create it VC A with that gitHub package:
https://github.com/m1entus/MZFormSheetController/issues/98
];
编辑 2 呈现 ViewControllerB 的代码:
- (IBAction)chooseGardenAndCityBtn:(id)sender
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"modal"];
MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithViewController:vc];
formSheet.presentedFormSheetSize = CGSizeMake(300, 298);
// formSheet.transitionStyle = MZFormSheetTransitionStyleSlideFromTop;
formSheet.shadowRadius = 2.0;
formSheet.shadowOpacity = 0.3;
formSheet.shouldDismissOnBackgroundViewTap = YES;
formSheet.shouldCenterVertically = YES;
formSheet.movementWhenKeyboardAppears = MZFormSheetWhenKeyboardAppearsCenterVertically;
// formSheet.keyboardMovementStyle = MZFormSheetKeyboardMovementStyleMoveToTop;
// formSheet.keyboardMovementStyle = MZFormSheetKeyboardMovementStyleMoveToTopInset;
// formSheet.landscapeTopInset = 50;
// formSheet.portraitTopInset = 100;
__weak MZFormSheetController *weakFormSheet = formSheet;
// If you want to animate status bar use this code
formSheet.didTapOnBackgroundViewCompletionHandler = ^(CGPoint location)
UINavigationController *navController = (UINavigationController *)weakFormSheet.presentedFSViewController;
if ([navController.topViewController isKindOfClass:[SearchCityTable class]])
SearchCityTable *mzvc = (SearchCityTable *)navController.topViewController;
mzvc.showStatusBar = NO;
[UIView animateWithDuration:0.3 animations:^
if ([weakFormSheet respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)])
[weakFormSheet setNeedsStatusBarAppearanceUpdate];
];
;
formSheet.willPresentCompletionHandler = ^(UIViewController *presentedFSViewController)
// Passing data
UINavigationController *navController = (UINavigationController *)presentedFSViewController;
navController.topViewController.title = @"בחר עיר";
;
formSheet.transitionStyle = MZFormSheetTransitionStyleCustom;
[MZFormSheetController sharedBackgroundWindow].formSheetBackgroundWindowDelegate = self;
[self mz_presentFormSheetController:formSheet animated:YES completionHandler:^(MZFormSheetController *formSheetController)
];
编辑
【问题讨论】:
你指定VC A采用SearchGardenDelegate协议了吗? 是的,我做了.. 看我编辑。 您从哪里向委托方法发送消息?来自您的 VC B 类中的哪个方法? 你在哪里有这个 [self.delegate addItemViewController:self didFinishWithGardenID:_kidGaedenID gardenName:_kidGardenName andCityName:_kidCityName]; didSelectRowAtIndexPath: tableview 方法 【参考方案1】:你在做
self.searchGarden = [[SearchGardenTable alloc]init];
但是您说您在情节提要中有您的视图控制器。这让我觉得 self.searchGarden 在 viewDidLoad: 的角度是与故事板中的不同的对象。
当您准备推送您的 VC B 或执行 TheSegue 之前(如果您正在使用 segue),您应该为 self.searchGarden 分配一个对象。
编辑
根据您的代码,我假设
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"modal"];
是你的VC B,所以你需要做vc.delegate = self; 请记住,您的 vc 必须是 VC B 类型,在您的情况下是 SearchGardenTable
编辑 2
鉴于当前的设置,我现在想到的最快的解决方案是 NSNotification。从您的 VC B 发送通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"userDidTapOnCell" object:nil userInfo:dictionaryOfObjects];
使用从模型中检索到的对象初始化对象字典的位置,例如:
NSDictionary *dictionary = @ @"gardenID": _kidGaedenID, @"gardenName": _kidGardenName ;
与在 VC A 中相比,您将自己作为观察者添加到 viewDidLoad 上的通知中:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gardenInfoDidComeBack:) name:@"userDidTapOnCell" object:nil];
并实现方法:
- (void)gardenInfoDidComeBack:(NSNotification *)notification
NSDictionary *userInfo = notification.userInfo;
// retrieve the kidGardenID and kidGardenName from the dict and use them as you whish.
希望这可以帮助您完成任务。您的导航架构可能不是最好的,但这已经超出了本主题的范围。
【讨论】:
我在 ViewControllerA 中有一个属性 @property (nonatomic, strong) SearchGardenTable *searchGarden; 我可以看到。但是您正在 viewDidLoad 中初始化一个新的 VC B 实例,因此它可能与您显示的不同。值得看看您编写的从 VC A 推送 VC B 的代码 仍然缺少从 VC A 推送 VC B 的代码 再次编辑,现在所有代码都用于显示 VC B 弹出窗口。 @OshriALM 查看我的编辑 2。【参考方案2】:请出示您的 VC B 初始化。
在调用此行之前确保 self.searchGarden 已初始化
self.searchGarden.delegate = self; // in VC A viewDidLoad.
【讨论】:
【参考方案3】:远射,但你试过了吗:
[[self delegate] addItemViewController:self didFinishWithGardenID:_kidGaedenID gardenName:_kidGardenName andCityName:_kidCityName]];
而不是
[self.delegate addItemViewController:self didFinishWithGardenID:_kidGaedenID gardenName:_kidGardenName andCityName:_kidCityName];
【讨论】:
@property (nonatomic, weak) id我从您的查询和疑虑中了解到我发现了一些东西
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
searchVC = (ControllerA *)[storyboard instantiateViewControllerWithIdentifier:@"controllerA"];
searchVC.delegate = self;
[self.navigationController pushViewController:searchVC animated:YES];
希望对你有帮助:)
【讨论】:
我不能使用 segue,因为 ViewController B 是一个弹出窗口,我使用来自 gitHub MZFormSheetController 的这个包来实现。当我点击 ViewControllerB 中的一个单元格时,弹出窗口被关闭。所以我必须在关闭弹出窗口(VC B)之前准备好要传递的数据 是的,在你点击的地方收集你的数据是执行你只需要在你之后调用 [self performSegueWithIdentifier:@"controllerB" sender:self];收集了您的数据。它将调用方法 -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 但是他们之间的故事板中没有segue。正如我所说的VC B是AC A上的一个弹出窗口。我仍然可以使用prepareForSegue?以上是关于在 ViewControllerB 到 ViewControllerA 之间传递数据,委托不会被调用的主要内容,如果未能解决你的问题,请参考以下文章