1

アプリケーションの下部に特定の時間にステータスバーを表示する必要があります。これはアプリケーションのメインビューの下部に簡単に配置できますが、View Controllerをこの上に(モーダルかどうかに関係なく)押すと、このステータスバーが非表示になります。

このようなステータスバーを追加して、アプリケーション自体の範囲外にする方法はありますか?理想的には、これをiPhoneの進行中の通話ステータスバーのように機能させたいと思います-このバーが表示されると、アプリが押し下げられ、呼び出しが[[UIScreen mainScreen] applicationFrame]正しいサイズを返します(つまり、このステータスの存在を説明します)アプリで利用可能な高さを計算するときのバー)。

4

1 に答える 1

1

これもやりたかったのでView Controller Containmentをやってみました。私はまだ試している途中なので、これを強く推奨するつもりはありませんが、iOS5 を使用している場合は、自分で試してみたいものかもしれません。ただし、画面の下部に表示または非表示になるステータス バーが表示されるようです。

これは、別のビュー コントローラーを開くビュー コントローラーですが、表示するステータス テキストがある場合は、画面の下部からポップアップし、それを取り除くまでそこにとどまります。これまでに少しテストしただけですが、これはpushViewController/popViewControllerを処理しているように見えますが、モーダル ビューではない可能性があります。

私のヘッダーは次のようになります。

//  StatusBarViewController.h
//
//  Created by Robert Ryan on 7/8/12.

#import <UIKit/UIKit.h>

@interface StatusBarViewController : UIViewController

@property (strong, nonatomic) UIViewController *appController;

- (void)setStatus:(NSString *)text;

@end

私の実装ファイル (これは ARC) は次のようになります。

//  StatusBarViewController.m
//
//  Created by Robert Ryan on 7/8/12.

#import "StatusBarViewController.h"

@interface StatusBarViewController ()
{
    BOOL _statusHidden;
    UIView *_appView;
    UILabel *_statusLabel;
}
@end

@implementation StatusBarViewController

@synthesize appController = _appController;

- (void)dealloc
{
    _appView = nil;
    _statusLabel = nil;

    [self setAppController:nil]; // usually I don't like setters in dealloc, but this does some special stuff
}

- (void)createControlsWithStatusHidden
{
    // create default app view that takes up whole screen

    CGRect frame = self.view.frame;
    frame.origin = CGPointMake(0.0, 0.0);
    _appView = [[UIView alloc] initWithFrame:frame];
    _appView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    _appView.clipsToBounds = YES;
    [self.view addSubview:_appView];

    // create status label that is just off screen below the app view

    _statusLabel = [[UILabel alloc] init];
    _statusLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:12.0];
    _statusLabel.backgroundColor = [UIColor darkGrayColor];
    _statusLabel.textColor = [UIColor whiteColor];
    CGSize size = [@"Hey!" sizeWithFont:_statusLabel.font]; // test size of box with random text
    _statusLabel.frame = CGRectMake(0.0, frame.size.height, frame.size.width, size.height);
    _statusLabel.textAlignment = UITextAlignmentCenter;
    _statusLabel.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
    [self.view addSubview:_statusLabel];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self createControlsWithStatusHidden];
    _statusHidden = YES;

    // I'm instantiating from storyboard. If you're using NIBs, just create your controller controller using initWithNib and then set our appController accordingly.

    self.appController = [self.storyboard instantiateViewControllerWithIdentifier:@"MainNavigator"];
}

- (void)setAppController:(UIViewController *)controller
{
    if (controller)
    {
        controller.view.frame = CGRectMake(0.0, 0.0, _appView.frame.size.width, _appView.frame.size.height);
        [self addChildViewController:controller];
        [controller didMoveToParentViewController:self];

        if (self.appController)
        {
            // if we have both a new controller and and old one, then let's transition, cleaning up the old one upon completion

            [self transitionFromViewController:self.appController
                              toViewController:controller
                                      duration:0.5 
                                       options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionCurveEaseInOut
                                    animations:nil
                                    completion:^(BOOL finished){
                                        if (self.appController)
                                        {
                                            [self.appController willMoveToParentViewController:nil];
                                            [self.appController removeFromParentViewController];
                                        }
                                    }];
        }
        else 
        {
            // if we have no previous controller (i.e. this is our first rodeo), then just add it to the view

            [_appView addSubview:controller.view];
        }
    }
    else
    {
        // no new controller, so we're just removing any old on if it was there

        if (self.appController)
        {
            // if there was an old controller, remove it's view, and remove it from the view controller hierarchy

            [self.appController.view removeFromSuperview];
            [self.appController willMoveToParentViewController:nil];
            [self.appController removeFromParentViewController];
        }
    }

    _appController = controller;
}

- (void)hideStatusWithCompletion:(void (^)(BOOL finished))completion
{
    [UIView animateWithDuration:0.25 
                     animations:^{
                         CGRect labelFrame = _statusLabel.frame;
                         labelFrame.origin.y += labelFrame.size.height;
                         _statusLabel.frame = labelFrame;

                         CGRect appFrame = _appView.frame;
                         appFrame.size.height += labelFrame.size.height;
                         _appView.frame = appFrame;
                     }
                     completion:completion];
}

- (void)unhideStatusWithCompletion:(void (^)(BOOL finished))completion
{
    [UIView animateWithDuration:0.25 
                     animations:^{
                         CGRect labelFrame = _statusLabel.frame;
                         labelFrame.origin.y -= labelFrame.size.height;
                         _statusLabel.frame = labelFrame;

                         CGRect appFrame = _appView.frame;
                         appFrame.size.height -= labelFrame.size.height;
                         _appView.frame = appFrame;
                     }
                     completion:completion];
}

- (void)setStatus:(NSString *)text
{
    BOOL hasText = (text && [text length] > 0);

    if (hasText)
    {
        if (!_statusHidden)
        {
            // if we have text, but status is already shown, then hide it and unhide it with new value

            [self hideStatusWithCompletion:^(BOOL finished){
                _statusLabel.text = text;
                [self unhideStatusWithCompletion:nil];
            }];
        }
        else
        {
            // if we have text, but no status is currently shown, then just unhide it
            _statusLabel.text = text;
            [self unhideStatusWithCompletion:nil];
        }
        _statusHidden = NO;
    }
    else
    {
        if (!_statusHidden)
        {
            // if we don't have text, but status bar is shown, then just hide it

            [self hideStatusWithCompletion:^(BOOL finished){
                _statusLabel.text = text;
            }];
            _statusHidden = YES;
        }
    }
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

次に、ステータス メッセージを更新するビュー コントローラーは、次のようなメソッドを使用します。

- (void)setStatus:(NSString *)text
{
    UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController;

    if ([controller isKindOfClass:[StatusBarViewController class]])
    {
        [(StatusBarViewController *)controller setStatus:text];
    }
}
于 2012-07-08T21:58:50.507 に答える