【问题标题】:Accessing and manipulating parent view controllers views from a container view IOS从容器视图 IOS 访问和操作父视图控制器视图
【发布时间】:2014-02-05 00:32:41
【问题描述】:

我正在制作一个应用程序,其中有一个容器视图,它是我的视图控制器屏幕的一半。从容器视图控制器的类中,我试图访问和操作位于容器视图之外的视图。 (下图)

我正在尝试从容器视图类访问并将项目添加到滚动视图,如下所示:

parent = (GFProfileViewController*)[self parentViewController];
UIScrollView  *scroll = (UIScrollView *)[parent.view viewWithTag:222];
parent.titleHolders.contentSize = CGSizeMake(320 * 4,60);
UILabel *testLabel = [[UILabel alloc] init];
[testLabel setFrame:CGRectMake(0, 0, 100, 40)];
[testLabel setText:@"My Test label"];
[parent.titleHolders addSubview:testLabel];
scroll.backgroundColor = [UIColor blueColor];

怎么也行不通。我什至尝试从父母的“带有标签的视图”方法访问视图。

都不行。

我知道代码很好,因为当我将它移到父 vc 时,一切都按预期工作。不过,我需要能够从容器中操作视图。有人可以帮忙吗?

【问题讨论】:

  • 我不确定为什么这段代码不能在子视图控制器中工作......但是良好的编程习惯要求一个视图控制器应该控制另一个视图控制器的视图......把这个代码在父视图控制器中并给父视图一个公共方法,子视图可以调用(并向其发送参数)以完成这项工作。
  • @nhgrif,你不是说“......良好的编程习惯规定一个视图控制器应该控制另一个视图控制器的视图......”
  • @DuncanC 是的,绝对是。谢谢指正。
  • @nhgrif 我有点明白,但因为我使用的是容器视图和页面视图控制器,所以我别无选择
  • @ngrif 让我大笑起来。 Ibam 将找出邓肯的答案。我可能只需要稍微改变一下我的结构。我同意(因为我是新手)我想要一个简单的答案,但我最好从一开始就正确地做事

标签: ios objective-c viewcontroller parentviewcontroller uicontainerview


【解决方案1】:

正如 nhgrif 所说,不要那样做。

您应该将另一个视图控制器的视图视为私有视图。

再次,正如 nhgrif 所说,在父视图控制器中创建一个公共方法,该方法获取所需的信息并自行显示。

如果视图控制器刚刚被初始化,那么父视图控制器的视图层次结构可能还不存在。在这种情况下,您需要设置属性以保存要显示的值,然后在 viewWillAppear 方法中显示它们。

使用故事板和 iOS >= 6,您可以使用嵌入 segue 设置子视图控制器,然后在您的 prepareForSegue 方法中,您可以将父视图控制器设置为子视图控制器的委托。这是让孩子与父母交流的一种干净的方式。 (如果您需要更详细的解释,我有一个 sample app on github 演示了这种技术。)

【讨论】:

  • 赞成告诉我我写了两次的答案。委托关系也不错。
  • 有趣...我可以使用故事板实现这一点吗??
  • 是的...你看过他的示例应用程序中的代码了吗?邓肯,也许可以通过发布一些最相关的代码 sn-ps 来改进答案。
  • 重读我回答的最后一段。我链接到的示例应用程序甚至显示了一个使用故事板的工作示例。
  • 抱歉从我的 iphone 上看,我现在要去看看
【解决方案2】:

就编程道德、正确性、良好实践等而言,我认为其他人已经涵盖了这些内容。你想做的肯定不是干净的方法,但我经常发现自己在走这样的捷径,但你真的需要知道你在做什么,如果它以后不会回来咬你。好处是只需要一行代码即可实现,而且开销非常低。问题是这种方法高度依赖于视图结构,所以如果你改变它,它就不再起作用了。

话虽如此。您尝试的方法不起作用,因为未在任何任意视图上设置“parentViewController”属性。它应该只在视图控制器的主视图上定义,您可以从“viewController.view”访问。

我会根据您的评论假设您的视图结构类似于:

UIView
    UIView
        UIScrollView
    Container

所以基本上从 Container 开始,您需要上一层然后下到 UIScrollView,如下所示:

UIScrollView = [((UIView*)[self.superview.subviews objectAtIndex:0]).subviews objectAtIndex:0];

我不确定您是否可以从上方视图按标签进行搜索,因为您要搜索的内容是嵌套在里面的某个地方,比下一层更远。假设您实际上可以做到这一点,这也应该有效并且更加防故障。

UIView *upperView = self;
while([upperView superview]){
    upperView = [upperView superview];
}
UIScrollView *scroll = [upperView viewWithTag:222];

【讨论】:

  • 它们都在同一个 vc 中。滚动视图在另一个视图中,但这有关系吗?我还能从 superview 访问吗?为什么我没有工作??
  • 我不知道这是否真的有效,但我当然不能赞成一个促进可怕编程实践的答案。请参阅我的 cmets 和 Duncan C 的回答,了解为什么这很糟糕。
猜你喜欢
  • 2012-10-28
  • 2012-10-26
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 2013-02-04
  • 2015-07-14
  • 2014-02-10
相关资源
最近更新 更多