【问题标题】:How to communicate an UIView from a XIB child to an UIView from a parent XIB?如何将 XIB 子代的 UIView 与父 XIB 的 UIView 通信?
【发布时间】:2011-04-27 22:32:32
【问题描述】:

我想知道是否可以在从 XIB 文件加载的 UIView 内点击某处(或执行其他操作)并触发来自父 XIB 的 UIView 的操作(例如更改父项中 UIButton 的标题界面视图)。这是NewsController类接口的代码片段:

#import <UIKit/UIKit.h>
#import "NewsPage.h"
@interface NewsController : UIViewController {
    // Some objects
    UIButton *loadButton;
    UIView *newsView;
    NewsPage *newsPage;
}
@property (nonatomic, retain) IBOutlet UIButton *loadButton;
@property (nonatomic, retain) IBOutlet UIView *newsView;
@property (nonatomic, retain) NewsPage *newsPage;
@end

这是 NewsPage 类实现的片段,我在其中加载子 XIB:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Some code
    newsPage = [[NewsPage alloc] initWithNibName:@"NewsPage" bundle:nil];
    [newsView addSubview:newsPage.view];
    // Some other code
}

这是 NewsPage 类接口中的一段代码:

#import <UIKit/UIKit.h>
#import "NewsController.h"
@interface NewsPage : UIViewController {
    NewsController *newsController;
}
@property (nonatomic, retain) IBOutlet NewsController *newsController;
@end

这是类实现的一个片段

- (void)tapAction:(UIGestureRecognizer *)gestureRecognizer {
    // Some code
    NewsController *newsController = [[NewsController alloc] initWithNibName:@"News" bundle:nil];
    NSLog(@"Current button title is: %@\n", newsController.loadButton.titleLabel.text);        
    newsController.loadButton.titleLabel.text = @"New text goes here!";
    NSLog(@"Current button title is: %@\n", newsController.loadButton.titleLabel.text);
    // Some other code
}

使用此代码(在 IB 中进行一些接线之后)我在调试器中看到了正确的标题,但模拟器没有更新标题更改。我的猜测是子 UIViews 与父 UIViews 平行,即使我做了这样的事情:

[newsController.loadButton removeFromSuperview]

父 UIView 层次结构没有变化,因为子 UIView“不在”父 UIView 的内部。我希望有人可以帮助解决这个问题,因为这非常令人沮丧。提前,非常感谢您。

【问题讨论】:

  • xib 是否正确连接到所有者对象?听起来 titleLabel 不存在于视图的层次结构中。所以不会显示。
  • @Toro:是的,所有者对象已正确连接,但我不知道父 UIView 中加载的 XIB 对象是否属于父对象的层次结构,如果是,为什么不更新从子 UIView 到父 UIView 所做的任何更改。

标签: iphone objective-c xcode ios interface-builder


【解决方案1】:

我看到的一个问题是,您正在访问 NewsController 中的一些元素,这些元素可能尚未从 NIB 中解压缩,因为它们在需要视图时会延迟完成。在引用这些项目之前,尝试访问控制器的 .view 成员,这应该强制加载。这是每个人似乎都会遇到的问题,直到延迟加载的想法被理解。

NewsController *newsController = [[NewsController alloc] initWithNibName:@"News" bundle:nil];
newController.view; //hopefully this doens't get optimized out. If so, change it a bit.
NSLog(@"Current button title is: %@\n", newsController.loadButton.titleLabel.text);   

【讨论】:

  • 感谢@DavidNeiss 的回答。我按照你说的尝试,但没有任何改变。我什至尝试使用for (UIView *view in [newsController.view subviews]) { if (view.tag == 99) { NSLog(@"Enter tag #99 with hidden property %d\n", newsController.loadButton.hidden); [view removeFromSuperview]; } NSLog(@"UIView in newsController #%d\n", view.tag); } 循环,似乎代码可以工作,但它还没有在模拟器中更新。
  • 您是否正在使用 - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated 过渡到 newsController 模态视图?
  • 不,因为 newsController 不是模态视图,而是“主视图”。 NewsPage XIB 加载在 NewsController 的 UIView 中,在其中我点击并触发 tapAction:gestureRecognizer。
  • 好的,抱歉,我正在努力解决这个问题。所以 NewController 是第一个视图控制器,然后 NewPage 是从那里以某种方式呈现的?按钮按下?那么当 NewPage 中发生某些事情时,您想影响 NewsController 中的视图吗?如果是这样,您可以通过 "*parentViewController" ivar 从当前 VC 中向上移动视图控制器链。
  • NewsPage 不是以模态方式呈现的,而是在 NewsController XIB 的 UIView 内,按下的按钮在该 UIView 内,但是是的,就像你说的那样,“当 NewPage 中发生某些事情时,你想影响一个视图在新闻控制器中”。我用有关 NewsPage 类的更多信息更新了 OP。
【解决方案2】:

本质上,当父母想知道孩子会告诉它的事情时,您在孩子上设置一个委托作为父母,然后在孩子代码中首先检查该委托是否存在,然后确保它响应您将发送的选择器。然后你给它发消息。

通过使用@protocol's 来实现这一点的好方法

这是一个包含一些基本信息的链接

http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 2017-10-28
    • 2016-02-29
    • 2011-10-11
    • 2018-10-07
    相关资源
    最近更新 更多