Stefan
Stefan

Reputation: 1110

UIView animation makes flashscrollindicators behave weirdly

I have a UIViewController.

Its view contains a UITableView as a subview. On viewDidAppear, the UIViewController calls the UITableView's -(void)flashScrollIndicators.

The UIViewController also observes a notification "SomethingHappened". When this happens, the UIViewController adds another small subview (a 30px high semi-transparent bar displaying a label "something happened") to its view. Meanwhile the contentInset of the UITableView is set to 30px at the top and the contentOffset is set to -30px.

All this happens in a UIView Animation that nicely pushes the bar on the view and moves the tableview content down a little, without losing the ability to scroll the content behind the semi-transparent bar later on.

- (void)viewDidLoad
{
    [super viewDidLoad];    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addMessageView:) name:@"SomethingHappened" object:nil];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];    
    [self.tableView flashScrollIndicators];
}

- (void)addMessageView {

    self.statusMessageView = [[FFStatusMessageView alloc] initWithFrame:CGRectMake(0, -kMessageViewHeight, self.view.frame.size.width, kMessageViewHeight)];
    self.statusMessageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;


    void (^animations)(void) = ^{
        [self.view addSubview:self.statusMessageView];
        self.statusMessageView.frame = CGRectMake(0, 0, self.view.frame.size.width, kMessageViewHeight);
        self.tableView.contentInset = UIEdgeInsetsMake(kMessageViewHeight, 0,0,0);
        if (self.tableView.contentOffset.y == 0) self.tableView.contentOffset = CGPointMake(0, -kMessageViewHeight);
    };

    [UIView animateWithDuration:0.4 animations:animations];
}

The result looks very nice. Here is the problem: "SomethingHappened" typically is posted/observed at roughly the same time the tableview flashes its scroll indicators. This makes the scroll indicator flash behave really odd - it slides in from the left and over the whole content before it lands on the right edge where it should be.

Should I delay one of the animations (indicator flash or bar placement)? How can I know whe it is safe to start the seconds one?

Upvotes: 0

Views: 641

Answers (1)

Stefan
Stefan

Reputation: 1110

I'm using a workaround now. I added two BOOL ivars (_animatingTableView and _waitingToFlashIndicators) to know the state of the animations.

- (void)viewDidLoad
{
    [super viewDidLoad];    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addMessageView:) name:@"SomethingHappened" object:nil];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];    
    if (! _animatingTableView) {
        [self.tableView flashScrollIndicators];
    } else {
        _waitingToFlashIndicators = YES;
    }
}

- (void)addMessageView {

    _animatingTableView = YES;
    self.statusMessageView = [[FFStatusMessageView alloc] initWithFrame:CGRectMake(0, -kMessageViewHeight, self.view.frame.size.width, kMessageViewHeight)];
    self.statusMessageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;

    void (^animations)(void) = ^{
        [self.view addSubview:self.statusMessageView];
        self.statusMessageView.frame = CGRectMake(0, 0, self.view.frame.size.width, kMessageViewHeight);
        self.tableView.contentInset = UIEdgeInsetsMake(kMessageViewHeight, 0,0,0);
        if (self.tableView.contentOffset.y == 0) self.tableView.contentOffset = CGPointMake(0, -kMessageViewHeight);
    };

    void (^completion)(BOOL) = ^(BOOL finished){
        _animatingTableView = NO;
        if (_waitingToFlashIndicators) {
            [self.tableView flashScrollIndicators];
            _waitingToFlashIndicators = NO;
        }
    };

    [UIView animateWithDuration:0.4 animations:animations completion:completion];
}

Upvotes: 0

Related Questions