开发者

UIView animation is delayed

开发者 https://www.devze.com 2023-04-10 16:00 出处:网络
An app i am developing is pulling in custom ads.I\'m retrieving ads fine, and the network side of things are working correctly.The problem I\'m having is when the AdC开发者_JAVA技巧ontroller receives

An app i am developing is pulling in custom ads. I'm retrieving ads fine, and the network side of things are working correctly. The problem I'm having is when the AdC开发者_JAVA技巧ontroller receives an ad it parses the JSON object then requests the image.

// Request the ad information
NSDictionary* resp = [_server request:coords_dict isJSONObject:NO responseType:JSONResponse];
// If there is a response...
if (resp) {
    // Store the ad id into Instance Variable
    _ad_id = [resp objectForKey:@"ad_id"];
    // Get image data
    NSData* img = [NSData dataWithContentsOfURL:[NSURL URLWithString:[resp objectForKey:@"ad_img_url"]]];
    // Make UIImage
    UIImage* ad = [UIImage imageWithData:img];
    // Send ad to delegate method
    [[self delegate]adController:self returnedAd:ad];
}

All this works as expected, and AdController pulls in the image just fine...

-(void)adController:(id)controller returnedAd:(UIImage *)ad{
    adImage.image = ad;
    [UIView animateWithDuration:0.2 animations:^{
        adImage.frame = CGRectMake(0, 372, 320, 44);
    }];
    NSLog(@"Returned Ad (delegate)");
}

The When the delegate method is called, it logs the message to the console, but it takes up to 5-6 seconds for the UIImageView* adImage to animate in. Because of the way the app is handling the request of the ads, the animation needs to be instant.

The animation for hiding the ad is immediate.

-(void)touchesBegan{
    [UIView animateWithDuration:0.2 animations:^{
        adImage.frame = CGRectMake(0, 417, 320, 44);
    }];
}


If the ad-loading happens in a background thread (the easiest way to check is [NSThread isMainThread]), then you cannot update the UI state in the same thread! Most of UIKit is not thread-safe; certainly UIViews currently be displayed are not. What's probably happening is that the main thread does not "notice" the change happening in the background thread, so it's not flushed to screen until something else happens.

-(void)someLoadingMethod
{
  ...
  if (resp)
  {
    ...
    [self performSelectorInMainThread:@selector(loadedAd:) withObject:ad waitUntilDone:NO];
  }
}

-(void)loadedAd:(UIImage*)ad
{
  assert([NSThread isMainThread]);
  [[self delegate] adController:self returnedAd:ad];
}
0

精彩评论

暂无评论...
验证码 换一张
取 消