4

假设我有 2 个控制器,BarViewController 和 FooViewController。

FooViewController 有一个名为 imageView 的 UIImageView 的出口:

@property (nonatomic, weak) UIImageView *imageView;

BarViewController 有一个 UIButton 按钮的出口。BarViewController 有一个从这个按钮到 FooViewController 的 segue,称为 BarToFooSegue(在故事板中完成)。

当我运行以下代码并在 FooViewController.imageView.image 上调用 NSLog 时,结果为 nil,并且我的图像不会显示。为什么会这样?

// code in BarViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    if([segue.identifier isEqualToString:@"BarToFooSegue"]){
        NSURL *photoUrl = @"http://www.randurl.com/someImage"; // assume valid url
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

        [segue.destinationViewController setImageView:imageView];
    }
}

我尝试将 FooViewController.imageView 设置为强而不是弱,但问题仍然存在:

@property (nonatomic, strong) UIImageView *imageView;

运行我的调试器,我注意到 FooViewController 中的 imageView 在 prepareForSegue: 中正确更新:但随后又被重新更新为一些新分配的 imageView,其中 @property image 设置为 nil。我不确定控制流的哪一部分导致了这种情况,因为它发生在用汇编语言编写的行中。

我通过向 FooViewController 添加 UIImage 属性使我的代码正常工作:

@property (nonatomic, strong) UIImage *myImage;

并在 BarViewController 中更改 prepareForSegue: 以传递图像而不是 imageView:

// code in BarViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    if([segue.identifier isEqualToString:@"BarToFooSegue"]){
        NSURL *photoUrl = @"http://www.randurl.com/someImage"; // assume valid url
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]];

        [segue.destinationViewController setMyImage:image];
}

并修改 viewWillAppear: 在 FooViewController:

- (void)viewWillAppear:(BOOL)animated{
    [self.imageView setImage:self.myImage];
}
4

4 回答 4

6

在设置图像之前调用[segue.destinationViewController view];,这将导致加载视图层次结构,然后设置您的插座。

于 2012-09-17T05:18:44.847 回答
2

prepareForSegue出口尚未定义 - 他们是零。您正在向 nil 发送消息,这非常好,因此不会给您错误,但在这种情况下,它可能会导致意外行为。您可以通过创建一个临时 UIImage 属性来解决它,并在 viewDidLoad 或 viewWillAppear 中将您的图像视图设置为该图像。

于 2012-09-17T04:30:30.487 回答
1

如果您必须直接设置 imageView.image,我同意@ikuragames 的回答。但通常情况下,我将 ViewController 的视图层次结构保密。

我认为将 UIImage 属性添加到 Foo 并不难看。我认为它实际上比@ikuragames 正确的解决方案更漂亮。

于 2012-09-17T05:36:31.500 回答
-1
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    if([segue.identifier isEqualToString:@"BarToFooSegue"]){
        NSURL *photoUrl = @"http://www.randurl.com/someImage"; 
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]];

   
        FooViewController *vc = [segue destinationViewController];
        vc.myImage = image;   
 }
}
于 2012-09-17T04:36:39.920 回答