0

In my iOS app when a button is pressed an event is initiated and at the bottom of the screen appears a status message informing the user about a successful or failed operation.

The status message appear and disappear with the following code.

this one show the message

- (void) showMessage:(NSString*)text
{
        CGRect frame = [[self view] frame];

        if(statusView == nil)
        {
            messageViewWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, frame.size.height-29,
                                                       frame.size.width, 0)];


            statusView = [[StatusMessageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 0)
                                                             Text:text
                                                 andShowIndicator:NO];
            [messageViewWindow addSubview:statusView];
            [messageViewWindow makeKeyAndVisible];
        }

        UILabel *label = [statusView getTextLabel]; 
        UIImageView *imageView = [statusView getBackImageView];

        CGSize stringSize = [text sizeWithFont:[Constants getLabelFont]];
        int xCoordinate = (messageViewWindow.frame.size.width - stringSize.width)/2;

        [UIView beginAnimations:nil context:nil];
        messageViewWindow.frame = CGRectMake(0, frame.size.height-59, frame.size.width, 30);
        statusView.frame = CGRectMake(0, 0, frame.size.width, 30);
        label.frame = CGRectMake(xCoordinate,5,stringSize.width,20);
        imageView.frame = CGRectMake(0, 0, frame.size.width, 30);
        [UIView commitAnimations];  

        [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(hideMessage) userInfo:nil repeats:NO];

}

and this one hides the message

- (void) hideMessage
{
    UILabel *label = [statusView getTextLabel]; 
    UIImageView *imageView = [statusView getBackImageView];

    CGRect labelFrame = label.frame;

    [UIView beginAnimations:nil context:nil];
    messageViewWindow.frame = CGRectMake(0, [UIScreen mainScreen].applicationFrame.size.height-29, [UIScreen mainScreen].applicationFrame.size.width, 0);
    statusView.frame = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, 0);  
    label.frame = CGRectMake(labelFrame.origin.x, 0, labelFrame.origin.y, 0);
    imageView.frame = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, 0);
    [UIView commitAnimations];
}

strange thing is that the message is shown and after two seconds dissapears, however the main window lost functionality, like the copy and paste ability.

Do you see something wrong in my methods? Is there any certain way, calling the "animations" code?

cateof
  • 6,608
  • 25
  • 79
  • 153
  • Why is that strange? You are setting the timer to hide it two seconds after you are showing it. – Martol1ni Oct 13 '12 at 14:57
  • @Martol1ni the status messages appears for 2 seconds and after that is being removed. This works well. After the removal the UIView has problems. – cateof Oct 13 '12 at 14:59

2 Answers2

0

Since you are writing [messageViewWindow makeKeyAndVisible];, you have to write [self.view.window makeKeyAndVisible] in hideMessage to let the self.view.window handle all the userinteraction again.

Martol1ni
  • 4,684
  • 2
  • 29
  • 39
0
  • This is because you use a UIWindow to display your view, which is not a good idea (it is not recommended to create UIWindows by yourself, as explained in the "Overview" paragraph of the documentation.
  • Moreover, you make your window the keywindow but don't restore the standard window at the end when you hide it, thus your problems with the events later.
  • And last, you use obsolete APIs for the animations, which is deprecated since iOS4 is out (and I guess you don't code for iOS3 or earlier), you should really use the new APIs that have been introducted 3 iOS versions ago now. Besides, it will avoid the overhead to create an NSTimer for that.

So you code can become:

- (void) showMessage:(NSString*)text
{
    CGSize sz = self.view.window.frame.size;
    CGRect hiddenFrame = CGRectMake(0, sz.height-29, sz.width, 0);

    if(statusView == nil)
    {
        statusView = [[StatusMessageView alloc] initWithFrame:hiddenFrame
                                                         text:text
                                             andShowIndicator:NO];
        [self.window addSubview:statusView];
    }

    UILabel *label = [statusView getTextLabel]; 
    UIImageView *imageView = [statusView getBackImageView];

    CGSize stringSize = [text sizeWithFont:[Constants getLabelFont]];
    int xCoordinate = (sz.width - stringSize.width)/2;
    label.frame = CGRectMake(xCoordinate,5,stringSize.width,20);
    imageView.frame = CGRectMake(0, 0, frame.size.width, 30);

    [UIView animateWithDuration:1.f animations:^{
        statusView.frame = CGRectMake(0, sz.height-59, frame.size.width, 30);
    } completion:^{
        // When show animation is done, schedule the start of the hide animation with a delay of 2 seconds
        [UIView animateWithDuration:1.f delay:2.f options:0 animation:^{
            statusView.frame = hiddenFrame;
        } completion:nil];
    }];
}
AliSoftware
  • 32,623
  • 6
  • 82
  • 77
  • Small nit-pick: although their use is discouraged, `beginAnimations` and `commitAnimations` are not deprecated (at least as of iOS 6). From the docs "Use of this method is discouraged in iOS 4.0 and later. You should use the block-based animation methods to specify your animations instead." – idz Oct 13 '12 at 15:53