4

BarViewController と FooViewController の 2 つのコントローラーがあるとします。

FooViewController には、imageView と呼ばれる UIImageView へのアウトレットがあります。

@property (nonatomic, weak) UIImageView *imageView;

BarViewController には、UIButton ボタンへのアウトレットがあります。BarViewController には、このボタンから FooViewController へのセグエがあり、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: 内で正しく更新されていることに気付きますが、数行後に、@property イメージが nil に設定された新しく割り当てられた imageView に再更新されます。アセンブリ言語で記述された行で発生したため、制御フローのどの部分がこれを引き起こしているのかわかりません。

UIImage プロパティを FooViewController に追加することで、コードが機能するようになりました。

@property (nonatomic, strong) UIImage *myImage;

そして、prepareForSegue: を BarViewController で変更して、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

InprepareForSegueアウトレットはまだ定義されていません。つまり、nil です。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 に答える