Acoop
Acoop

Reputation: 2666

Redrawing UIViewController and its subviews

I have a UIViewController with many subviews like UILabels, UIImages and a UIWebview. With a defined action by the user, the subviews of the UIViewController animate to different sizes and different locations inside of the UIViewController's view. Is it possible that this can be undone with a different defined action by the user? I want to make all the subviews revert back to their previous locations and sizes that they were before the animation was run. I thought of two possible solutions:

  1. Get the properties of the subviews with the view.subviews() method before the animation is run, and then set the subviews after the animation to the properties in this array, or,
  2. Call a method on the UIViewController to tell it to redraw all the subviews according to the properties set in the storyboard file.

Are these the right way of accomplishing what I would like to do? And if so, how would I go about doing this? (I don't know how to programmatically implement either of my ideas.)

Any help is greatly appreciated. Thanks.

Upvotes: 0

Views: 419

Answers (2)

arturdev
arturdev

Reputation: 11039

Here is the solution.

@interface ViewController ()
@property (strong, nonatomic) NSMutableArray *frames;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    //Saving initial frames of all subviews
    self.frames = [NSMutableArray new];
    NSArray *allViews = [self allViewsOfView:self.view];
    for (UIView *view in allViews) {
        CGRect frame = view.frame;
        NSValue *frameValue = [NSValue valueWithCGRect:frame];
        [self.frames addObject:frameValue];
    }
}

- (NSMutableArray *)allViewsOfView:(UIView *)view
{
    NSMutableArray *result = [NSMutableArray new];
    [result addObject:view];
    for (UIView *subView in view.subviews) {
        [result addObjectsFromArray:[self allViewsOfView:subView]];
    }

    return result;
}

- (void)resetFrames
{
    NSArray *allViews = [self allViewsOfView:self.view];
    for (UIView *view in allViews) {
        NSValue *frameValue = [self.frames objectAtIndex:[allViews indexOfObject:view]];
        CGRect frame = [frameValue CGRectValue];
        view.frame = frame;
    }
}

@end

Call [self resetFrame]; whenever you want to revert view's frames back to their initial values.

Upvotes: 1

coolbeet
coolbeet

Reputation: 1665

You could cache all your subview's frame before changing it and running the animation, in this way you can even cache more than one action. A stack structure will be perfect for this, but there is no way to achieve this in interface builder, you have to reference outlets from IB to code to get their frame.

Upvotes: 0

Related Questions