I have an UIImageView with a method to change the image it displays. It works fine, if the method is triggered from a touch event received by the UIImageView itself, but the same method fails to update the UIImageView, if called from another object, which triggered the touch event. I have an NSLog call in the method in question and thus can see, that the method is called in both cases. But only in one case I can see the actual change of the image in the other case the view is not updated.
When it works, I do not need to setNeedsDisplay or setNeedsLayout, but that is what I tried to fix the problem. Setting needsDisplay and needsLayout in the UIImageView as well as its superview. To no avail. I can see, that the image is actually changed, if I rotate the device, which causes a refresh and I see, that the UIImageView indeed changed.
The superview calls the method eventAtLocation: on an OutletCollection using makeObjectsPerformSelector:withObject:
It sure looks like an embarrassing mistake on my part, but I can’t figure it out since hours. I am running out of ideas what to try 🙁
Here’s the code in question:
- (void)eventAtLocation:(NSValue *)location
{
CGPoint loc = [self.superview convertPoint:[location CGPointValue] toView:self];
if ([self pointInside:loc withEvent:nil]) {
if (!self.isAnimating) {
[self autoSwapImage];
}
}
else{
if (self.isAnimating) {
[self cancelAnimation];
}
}
}
- (void)cancelAnimation
{
self.isAnimating = NO;
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
- (void) swapImage
{
currentImage++;
if (currentImage > numberOfImages)
currentImage = 1;
NSLog(@"set image to %i", currentImage);
self.image = [UIImage imageNamed:[NSString stringWithFormat:@"img_%i.jpg", currentImage]];
[self setNeedsDisplay];
}
- (void) autoSwapImage
{
self.isAnimating = YES;
[self swapImage];
[self performSelector:@selector(autoSwapImage) withObject:self afterDelay:0.1];
}
// The following works, but if eventAtLocation: is called form the superview swapImage gets called (-> NSLog output appears), but the view is not updated
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//[self autoSwapImage];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
@end
It looks like you aren’t actually setting the UIImageView’s image, you are just setting self.image. You need to do something like
Also you’ll want to put a check in that [UIImage imageNamed:] actually is returning an image, and that its not nil.