You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从ViewControllerB获取ViewControllerA的引用以修改其属性

解决从ViewControllerB修改ViewControllerA属性的问题

首先先修正你启动ViewControllerB代码里的语法错误:initWithRootViewController: 参数应该是实例 myVC,而不是类名 CustomVC,修正后的代码:

- (void) launchSecondVC {
    UIStoryboard *storyBoard = self.storyboard;
  
    CustomVC * myVC = [storyBoard instantiateViewControllerWithIdentifier:@"myvc"];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:myVC];
    [self presentViewController:nav animated:YES completion:nil];
}

下面提供几种可靠的方法来实现你的需求:

方法一:直接传递ViewControllerA的引用(简单直接)

  1. 在 CustomVC(即ViewControllerB)的头文件中添加弱引用属性:
// CustomVC.h
#import "FirstCustomVC.h"

@interface CustomVC : UIViewController
@property (nonatomic, weak) FirstCustomVC *sourceVC;
@end
  1. 在启动ViewControllerB时,把当前ViewControllerA的实例赋值给这个属性:
- (void) launchSecondVC {
    UIStoryboard *storyBoard = self.storyboard;
  
    CustomVC * myVC = [storyBoard instantiateViewControllerWithIdentifier:@"myvc"];
    // 传递引用
    myVC.sourceVC = self;
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:myVC];
    [self presentViewController:nav animated:YES completion:nil];
}
  1. 在ViewControllerB中完成操作后,直接通过引用修改属性并关闭:
// 关闭并启用ViewControllerA的按钮
self.sourceVC.myButton.enabled = YES;
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];

方法二:使用代理模式(解耦更规范)

这种方式更符合iOS开发的设计规范,降低VC之间的耦合度:

  1. 在 CustomVC.h 中定义代理协议:
// CustomVC.h
@protocol CustomVCDelegate <NSObject>
// 定义操作完成后的回调方法
- (void)customVCDidFinishOperation;
@end

@interface CustomVC : UIViewController
@property (nonatomic, weak) id<CustomVCDelegate> delegate;
@end
  1. 在 FirstCustomVC 中遵守协议并实现回调方法:
// FirstCustomVC.h
#import "CustomVC.h"

@interface FirstCustomVC : UIViewController <CustomVCDelegate>
// ... 你的其他属性,比如myButton
@end

// FirstCustomVC.m
@implementation FirstCustomVC
// ... 其他代码
- (void)customVCDidFinishOperation {
    self.myButton.enabled = YES;
}

- (void)launchSecondVC {
    UIStoryboard *storyBoard = self.storyboard;
  
    CustomVC * myVC = [storyBoard instantiateViewControllerWithIdentifier:@"myvc"];
    myVC.delegate = self;
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:myVC];
    [self presentViewController:nav animated:YES completion:nil];
}
@end
  1. 在ViewControllerB中完成操作后,调用代理方法并关闭:
// CustomVC.m
- (void)finishOperation {
    if ([self.delegate respondsToSelector:@selector(customVCDidFinishOperation)]) {
        [self.delegate customVCDidFinishOperation];
    }
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

方法三:使用通知中心(适合跨多层VC的场景)

如果VC层级复杂,代理或直接引用不太方便,可以用通知实现:

  1. 在 FirstCustomVC 中注册通知并实现响应方法:
// FirstCustomVC.m
- (void)viewDidLoad {
    [super viewDidLoad];
    // 注册通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(enableMyButton)
                                                 name:@"CustomVCDidFinishOperation"
                                               object:nil];
}

- (void)enableMyButton {
    self.myButton.enabled = YES;
}

- (void)dealloc {
    // 移除通知观察者,避免野指针
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
  1. 在ViewControllerB中完成操作后发送通知并关闭:
// CustomVC.m
- (void)finishOperation {
    // 发送通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CustomVCDidFinishOperation" object:nil];
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

补充:修复你原代码中获取ViewControllerA的方式(不推荐,耦合度高)

如果你一定要通过层级获取,需要先拿到导航控制器的presentingViewController,再强制类型转换:

// 在CustomVC中
FirstCustomVC *vcA = (FirstCustomVC *)self.navigationController.presentingViewController;
if ([vcA isKindOfClass:[FirstCustomVC class]]) {
    vcA.myButton.enabled = YES;
}
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];

这种方式不推荐,因为一旦VC层级变化,代码就会失效,维护性差。

内容的提问来源于stack exchange,提问作者user6631314

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:10:18