Search code examples
objective-cuiviewobjective-c-blocksquartz-graphics

transitionWithView gets called repeatedly after ViewController is dismissed


This is in a ModalViewController using StoryBoard and ARC

When I dismiss the view I see this line... NSLog(@"%d %@",[imgArray count],fileName); ... being printed over and over again.

How do I kill the functions transitionWithView/animateWithDuration when the view is dismissed?

Missing something quite crucial!

.h

#import <UIKit/UIKit.h>

@interface InfoVC : UIViewController

@property (weak, nonatomic) IBOutlet UIImageView *imageview;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollview;

@end

.m

#import "InfoVC.h"
#import <QuartzCore/QuartzCore.h>

@interface InfoVC ()

@end

@implementation InfoVC {
    int randomInt;
    NSArray *imgs;
    NSMutableArray *imgArray;
    NSTimer *myTimer;
    NSTimer *myTimer2;
    NSString *currentImg;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    imgs = [NSArray arrayWithObjects:
                      @"01.jpg",
                      @"02.jpg",
                      @"03.jpg",
                      nil];
    imgArray = [imgs mutableCopy];
    [self initialImage];
}


- (void)initialImage
{
    _imageview.contentMode = UIViewContentModeLeft;

    int rnd = [imgArray count];
    randomInt = (arc4random()%rnd);
    currentImg = [imgArray objectAtIndex:randomInt];    
    UIImage *image = [UIImage imageNamed:currentImg];

    [_imageview setImage:image];
    _imageview.bounds = CGRectMake(0, 0, image.size.width, image.size.height);

    _scrollview.contentSize = image.size;
    _scrollview.contentOffset = CGPointMake(-150.0, 0.0);

    [imgArray removeObjectAtIndex: randomInt];

    [self animate];
}

- (void)randomImage
{        
    if ([imgArray count]==0) {
        imgArray = [imgs mutableCopy];
    }

    int rnd = [imgArray count];
    randomInt = (arc4random()%rnd);
    NSString *fileName = [imgArray objectAtIndex:randomInt];

    NSLog(@"%d %@",[imgArray count],fileName);

    [imgArray removeObjectAtIndex: randomInt];

    UIImage * toImage = [UIImage imageNamed:fileName];


    void (^completion)(void) = ^{
        [self animate];
    };

    [UIView transitionWithView:self.view
                      duration:1.75f
                       options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction
                    animations:^
                    {
                        _imageview.image = toImage;
                    }
                    completion:^(BOOL finished)
                    {
                        completion();
                    }
    ];

}

- (void)animate{

    CGPoint offset = _scrollview.contentOffset;

    float flt = 150.0;

    if (_scrollview.contentOffset.x == flt)
    {
        offset.x = 0.0 ;
    }
    else
    {
        offset.x = flt ;
    }

    void (^completion2)(void) = ^{
        [self randomImage];
    };

    [UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseIn
                     animations:^{
                         _scrollview.contentOffset = offset; 
                     }completion:^(BOOL completed){
                         completion2();
                     }
     ];


}

- (void)viewDidUnload
{
    [super viewDidUnload];

    [_scrollview.layer removeAllAnimations];
    [_imageview.layer removeAllAnimations];
}


- (IBAction)dismissInfo:(id)sender
{
    [_scrollview.layer removeAllAnimations];
    [_imageview.layer removeAllAnimations];

    [self dismissModalViewControllerAnimated:YES];
}

Solution

  • I tried using a gazillion things retro fitting transitionWithView with CABasicAnimation, using NSTimer etc.

    In the end I just did:

    [_imageview removeFromSuperview];
    

    when dismissing the view and all was great.

    But from other posts on here it appears there is a bug hen when applying an alpha transition to a UIScrollview - the reference to the view is lost when it's transparent.