Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS How to refresh ScrollView when its model change?

I am new to iOS programming and have limited knowledge of iOS and Objective-C, so please give me some help.

I am working on a flickr photo app, which basically require photo data from flickr API and present one in scrollView.

But I meet some problem in my iPad version, presented with UISplitViewController. Let me give a simple intro of my app.

MASTER VIEW: a list of UITableViewController embedded in UINavigationViewController, basically it just use some Flickr API to get some data, present something like this:

navigationController - >

tableViewControllerA (photos organized by countries) - >

tableViewControllerB (photo list in that country) When photo is selected in TableViewControllerB, in my code I pass the photo URL (from flickr API) to my detail view controller which is a scrollView, and here is my code in scrollView's ViewController.

IBOutlet UIScrollView *scrollView;
IBOutlet UIImageView *imageView;
NSURL *photoURL;


- (void) viewDidLoad
{
    [super viewDidLoad];

    dispatch_queue_t downloadQueue = dispatch_queue_create("flickr donwloader", NULL);
dispatch_async(downloadQueue, ^{
    // load image
    self.imageView.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:self.photoURL]];

    dispatch_async(dispatch_get_main_queue(), ^{

        // configure scrollView and imageView
        CGSize photoSize = self.imageView.image.size;

        self.scrollView.delegate = self;
        [self.scrollView setZoomScale:1.00];
        [self.scrollView setMinimumZoomScale:0.5];
        [self.scrollView setMaximumZoomScale:1.00];
        self.scrollView.contentSize = photoSize;

        self.imageView.frame = CGRectMake(0, 0, photoSize.width, photoSize.height);

        CGPoint scrollCenter = self.scrollView.center;
        self.imageView.center = scrollCenter;
    });
});
dispatch_release(downloadQueue);

and in master view when a picture is selected, I set the detailView (scrollView)'s property photoURL, so I override the setter method of photoURL

-(void) setPhotoURL:(NSURL *)photoURL
{
    // do something to refresh my scrollView, below are something I already tried
    self.imageView.image =  [UIImage imageWithData: [NSData dataWithContentsOfURL:self.photoURL]];
    [self.scrollView setNeedsDisplay];
    [self.view setNeedsDisplay];
    [self.imageView setNeedsDisplay];
}

my purpose is just when my model (photoURL) give, my scrollView should give me the corresponding imageView, but when my app run and I select a photo, the scrollView did't "update", I already learned how to update UITableView (self.tableView reloadData), but I really don't know how to do this, please help!

PS:

1 Please forgive my poor English -_- I already tried to explain as clear as possible.

2 I don't have enough reputation to update image to let you guys fully understand what My app is, hope you can understand by just what I said


UPDATE: I use KVO mechanism instead of overriding the setter method of photoURL, but [self.scrollView setNeedsDisplay] still doesn't work.

I use debugger to track the progress, the KVO works, but nothing happen after [self.xxx setNeedsDisplay], I m totally confused and do not know what to do.

enter image description here

like image 566
ifournight Avatar asked Mar 23 '12 13:03

ifournight


2 Answers

I have Swift version and don't know whether it'll work for you or not, but it worked for me.

  1. Just Write your code in viewDidLayoutSubviews() like below

    override func viewDidLayoutSubviews() {
    self.scroller.contentSize = CGSize(width: self.view.frame.width, 
    height: self.websiteLabel.frame.maxY + 20)
    }
    
  2. And call this method in viewDidAppear() like...

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    viewDidLayoutSubviews()       
    }
    

Hope this will Help you guys..

like image 99
Amit Kumar Avatar answered Sep 22 '22 21:09

Amit Kumar


You should actually be using KVO, not overriding the setters:

-(void) viewDidLoad
{
    ...
    [self addObserver:self forKeyPath:@"photoURL" options:0 context:NULL];
    ...
}

-(void) observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context
{
    if ([keyPath isEqualToString:@"photoURL"])
    {
        self.imageView.image =  [UIImage imageWithData: [NSData dataWithContentsOfURL:self.photoURL]];
        [self.scrollView setNeedsDisplay];
        [self.view setNeedsDisplay];
        [self.imageView setNeedsDisplay];
    }
}

And remember to @synthesize your properties!

like image 35
Richard J. Ross III Avatar answered Sep 22 '22 21:09

Richard J. Ross III