14

UIViewController 的 parentViewController 属性是只读的,但我正在嵌套自定义视图控制器并想使用此属性。

但是,由于它是只读的,而且我没有找到其他设置此属性的方法,所以我的问题是:如何设置它?

很明显,UINavigationController可以在-pushViewController中以某种方式设置属性,-presentModalViewController也可以,所以一定是可以的。

我知道我可以添加自己的 UIViewController 属性,但我确信 parentViewController 原则上是正确的属性。

4

6 回答 6

11

解决方案是:

   - (void)setParentController:(UIViewController*)parent{
 [self setValue:parent forKey:@"_parentViewController"];
    }

它不会导致链接器出现问题!

PS:不要使用“setParentViewController”作为方法名,因为这个方法存在于私有API中,Apple说:“你的应用程序中包含的非公共API是setParentViewController:。

如果您在源代码中定义了与上述 API 同名的方法,我们建议您更改方法名称,使其不再与 Apple 的私有 API 冲突,以避免您的应用程序被标记为未来提交。

请在下次更新中解决此问题..."

于 2010-05-10T12:44:07.800 回答
10

我意识到这个问题是在 iOS 5 之前提出的,但作为参考,当你想嵌套 UIViewControllers 时,你应该使用 addChildViewController。这也将自动设置 parentViewController 属性。

- (void)addChildViewController:(UIViewController *)childController NS_AVAILABLE_IOS(5_0);

您可以在Apple阅读有关“创建自定义内容视图控制器”的更多信息。

于 2013-02-20T22:02:43.693 回答
2

我尝试了 Alex 的建议,为 UIViewController 制作一个类别,它在模拟器中有效,但在我的手机上无效。这是类别

@interface UIViewController (parentSetter) 
-(void)setParentUIViewController:(UIViewController*)parent;
@end

@implementation UIViewController (parentSetter)
-(void)setParentUIViewController:(UIViewController*)parent
{
 _parentViewController = parent;
}
@end

它可以编译并正常工作,但请注意下划线成员有点不妥。这就是在针对 3.0 SDK 进行编译时导致链接器错误的原因。

我有一个包含 2 个子视图的容器视图,其中一个表就是其中之一。该表需要一个父级,以便它可以与导航栏交互,等等。

我将使用此解决方案:

@interface AdoptedTableViewController : UITableViewController {
    UIViewController* surrogateParent;
}

-(UINavigationController*)navigationController;
@property (nonatomic, assign) IBOutlet UIViewController *surrogateParent;
@end

@implementation AdoptedTableViewController
@synthesize surrogateParent;

-(UINavigationController*)navigationController
{
    if( [super navigationController] )//self.navigationController ) 
    {
        return [super navigationController];
    }
    else
    {
        return surrogateParent.navigationController;
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

我现在所有的表格视图控制器都采用了TableViewControllers。他们需要父母的主要原因是他们可以将视图控制器推送到导航堆栈,以便由导航控制器 getter 透明地处理。

如果 parentViewController 不是只读的,那就太好了,但是在我涉足 _parentViewController 时,我发现 ViewController 层次结构不仅仅是那个属性。我认为在这种关系中可能存在很多耦合和责任,Apple 还没有为大众解决足够的问题。例如,在向上移动导航层次结构时,我注意到一个奇怪的取消选择行为,我无法修复。也许 UINavigation 控制器反映了它们的顶级控制器的类并且行为不同?

简而言之,它确实是只读的,没有干净或简单的解决方法。你只需要围绕它进行架构设计。

于 2010-01-07T09:25:25.993 回答
0

但是,由于它是只读的,而且我没有找到其他设置此属性的方法,所以我的问题是:如何设置它?

如果是这样readonly,您就不能使用点表示法而不会出现编译器错误

但是,您也许可以使用类别向类添加自定义modifyParentViewController方法UIViewController

即使属性是只读的,变量本身也可能是可修改的,如果它不是@protected. 如果是@protected,子类化视图控制器可能允许您选择修改变量。

于 2009-09-07T22:12:07.210 回答
0

parentViewController 用于 NavigationViewControllers 和呈现模式视图控制器,没有方法 pushViewController 或 presentModalViewController 无法设置属性。parentViewController 是只读属性,只能由 UIViewController 类和 UINavigationController 类读取,这些子类将无权设置该属性。

于 2009-09-07T23:44:19.210 回答
0

看起来调用 setParentViewController: 方法有效。

[childViewController setParentViewController:self];

但是,这仍然会产生编译器警告。哪个,IMO,意味着不要这样做(我改为子类)。

于 2010-02-17T09:18:30.653 回答