使用 prepareForSegue 方法时,IBOutlet 属性不会更新

时间:2023-03-25
本文介绍了使用 prepareForSegue 方法时,IBOutlet 属性不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我在将值传递给 destinationViewController 的 IBOutlet 属性时遇到问题,但它在普通属性上工作正常,请参阅下面的代码

I am having problem passing value to a IBOutlet property of destinationViewController but it works fine on ordinary property see code below

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"NewsCellToDetail"]) {        
    testViewController *viewController = segue.destinationViewController;
    viewController.titleLabel.text = @"test"; // set the IBOutlet label text to something
    NSLog(@"%@",viewController.titleLabel.text); // this will output to nil
    viewController.textTest = @"testing2"; // set the property to something
    NSLog(@"%@", viewController.textTest) // this will output the string testing2
}

这是头文件testviewcontroller.h的代码

This is the code for the header file testviewcontroller.h

#import <UIKit/UIKit.h>
@interface NewsDetailViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *titleLabel;
@property (strong, nonatomic) NSString *textTest;
@end

我已经合成了这两个属性.

I already synthesize both the property.

感谢您的帮助.

推荐答案

我最近也遇到了同样的问题.但是当我一步步调试它时,我找到了一个可能的原因.(对不起,我也是Objective C的新手,所以我下面的解释可能不是那么准确和专业......我之前的背景主要是Web开发.)

I just got the same problem recently. But when I debug it step by step, I find a possible reason. (I'm sorry I'm also new to Objective C, so my following explanation may be not that accurate and professional ... My previous background is mainly web development.)

如果你在你调用的那行之后设置一个断点

If you set a breakpoint just after the line you call

testViewController *viewController = segue.destinationViewController;

当你构建并运行项目时,你会发现destinationViewController中的UITextField属性并没有在断点处分配和启动(内存为0x0).同时 NSString 属性已经分配和初始化(所以你可以设置它的值).

when you build and run the project, you will find that the UITextField property in the destinationViewController is not allocated and initiated (memory is 0x0) at the breakpoint. Meanwhile the NSString property is already allocated and initialised (so you can set its value).

我认为 UITextfield 可能是一个子视图,因此它仅在其父视图(目标视图)启动时才启动.但是 NSString 是一个不与任何视图关联的属性,因此它是由声明它的视图控制器分配和初始化的.

I think probably UITextfield is a child view, so it only initiates when its parent view (the destination view) is initiated. But NSString is a property that is not associated with any view, so it is allocated and initiated with the view controller which declares it.

当我对此进行进一步测试时,我发现了一件非常有趣的事情:第二个视图是在 期间加载的- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender运行.我做了如下测试代码:

When I do a further test of this, I find a very interesting thing: the second view is loaded during the - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender runs. I do a test code like below:

在第一个视图控制器.m文件中:

In the first view controller .m file:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    NSLog(@"1. %@, %@",[segue identifier],segue.destinationViewController);

    Scene2Controller *scene2ViewController = [segue destinationViewController];
    [txtScene2 resignFirstResponder];

    NSLog(@"2. scene2ViewController: %@", scene2ViewController);
    NSLog(@"3. txtScene1: %@; passValue: %@", [scene2ViewController txtScene1], scene2ViewController.passValue);
    NSLog(@"4. View2: %@; passValue: %@", [scene2ViewController view], scene2ViewController.passValue);
    NSLog(@"5. txtScene1: %@; passValue: %@", [scene2ViewController txtScene1], scene2ViewController.passValue);

    //txtScene1 is the UITextfield property I declared in the second view controller
    //txtScene2 is the UITextfield property I declared in the first view controller
    //passValue is the NSString property I declared in the second view controller 

}

在第二个视图控制器.m文件中:

In the second view controller .m file:

- (void)viewDidLoad
{
    NSLog(@"6. txtScene1: %@; passValue: %@", txtScene1,passValue);


    [super viewDidLoad];

}

注意到我在 NSLog 消息之前添加了序列号.我发现最终的日志结果序列是 1,2,3,6,4,5 而不是 1,2,3,4,5,6.并且在日志3中,txtScene1结果为null(未启动),但是在日志4(第二个视图加载完毕)之后,在日志5中,txtScene1结果为NOT null并且已经启动.这表明在 segue 执行期间加载了第二个视图.所以我猜想在 segue 过渡期间,第二个视图控制器对象的启动顺序是:第二个视图控制器 -> NSString 属性(以及其他类似的属性,如 NSInteger 等) -> 第二个视图 -> UITextfield 属性(和其他子视图属性).

Noticed that I add sequential numbers before NSLog messages. I found the final log result sequence was 1,2,3,6,4,5 rather than 1,2,3,4,5,6. And in log 3, the txtScene1 result was null (not initiated), but after log 4 (the second view was loaded), in log 5, the txtScene1 was NOT null and has been initiated. This suggested that the second view was loaded during the segue performs. So I guess that during the segue transition, the initiation sequence of the second view controller objects would be: second view controller -> NSString property (and other similar properties, like NSInteger, etc.) -> second view -> UITextfield property (and other subview properties).

所以我在第一个视图控制器 .m 文件中更改了我的代码,如下所示:

So I changed my codes in the first view controller .m file as below:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    Scene2Controller *scene2ViewController = [segue destinationViewController];
    [txtScene2 resignFirstResponder];

    if ([scene2ViewController view]) {
        if ([txtScene2.text isEqualToString:@""]) {
            scene2ViewController.txtScene1.text = @"No Value";
        } else {
            scene2ViewController.txtScene1.text = txtScene2.text;
        }
    }

}

然后这段代码可以正常工作,并且值会直接传递给第二个视图中的 UITextfield 属性.

This code then works fine and the value is passed directly to the UITextfield property in the second view.

希望上面的解释清楚,对你有帮助.

Hope above explanation is clear and helpful for you.

这篇关于使用 prepareForSegue 方法时,IBOutlet 属性不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:我们可以邀请人们使用我们的应用程序或通过 iOS 5 中的 Facebook 从应用程序发送好友请求吗? 下一篇:如何在 HTTP post 中向 PHP 服务器发送多个参数

相关文章