How to set imageView image on prepareForSegue iOS?

2019-06-04 16:56发布

I tried to push to a ViewController using prepareForSegue. When I'm pushing, I want to set an image on ImageView in pushed view controller. Here what I tried,

ViewController

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    UIButton *btn = sender;
    if (btn.tag == 50) {
        if (jpegData) {
            [self saveTempImage:jpegData];
        }
        if ([segue.identifier isEqualToString:@"HomeView"]) {
            HomeViewController *vc = [segue destinationViewController];
            vc.backImageView.image = capturedImage;
            vc.isBackImage = true;
        }
    }
}

I have an ImageView in HomeViewController. I tried to set it's image using this vc.backImageView.image = capturedImage;. capturedImage is not null. But the image is not set in ImageView.

How can I fix this?

Thanks in Advance!

2条回答
小情绪 Triste *
2楼-- · 2019-06-04 17:27

Your outlates are not yet set there, I believe backImageView is null at this point. Have backImage property and when backImageView is ready (added to view hierarchy, viewDidLoad is good place for that) then set its image property.

查看更多
SAY GOODBYE
3楼-- · 2019-06-04 17:40

1) You should make the backImageView property (and all the other outlets of HomeViewController) private, because for this view, HomeViewController is exclusively responsible and no other class should be able to manipulate this view. This is current established convention in iOS development. You can do this by adding class extension above the @implementation keyword in HomeViewController .m file.

@interface HomeViewControler ()

@property (nonatomic, strong) IBOutlet UIImageView *backImageView;
//...other private properties ...

@end


@implementation MyViewControler

Right after that, you need to move view outlet properties from the .h interface file to the .m interface extension to have the declared privately.

2) You should create a private property called capturedImage in the extension too.

@interface HomeViewControler ()

@property (nonatomic, strong) IBOutlet UIImageView *backImageView;
@property (nonatomic, strong) UIImage *capturedImage;

@end

3) Declare a public method in h. file called configureWithImage

-(void)configureWithImage:(UIImage *)paramImage;

and implement it i m. file like this

-(void)configureWithImage:(UIImage *)paramImage
{
    self.capturedImage = paramImage;
}

4) Next you need to make sure the passed image is used in the imageview, for that HomeViewController's viewDidLoad makes a lot of sense.

-(void)viewDidLoad
{
    [super viewDidLoad];

    self.backImageView.image = self.capturedImage;
    //...other code...
}  

5) Last step, in prepareForSegue you configure your view controller with the image

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UIButton *btn = sender;
    if (btn.tag == 50) 
{
    //...other code...
    if ([segue.identifier isEqualToString:@"HomeView"]) 
    {
        HomeViewController *vc = [segue destinationViewController];
        [vc configureWithImage:capturedImage];

        //...other code...
    }
}

The "morale of the story" is that by having a proper public interface that is the sole entry point for configuration (the config method) you decouple the two entities. It means the source view controller merely passes the image without having to know ANYTHING about what happens in the destination VC. The image is then processed by the responsible destination view controller.

Should you change your mind and do some layout/view content changes in the HomeViewController (possible filter and process the image for visual effects) later in time, the source view controller will not be affected at all because wheat happens in HomeViewController is nobody else's concern, and you will keep the public configuration method intact. That means the change will not require to maintain code in prepareForSegue, only in the destination VC.

查看更多
登录 后发表回答