Показывать экран заставки каждый раз, когда приложение становится активным

Я хочу, чтобы экран заставки отображался каждый раз, когда приложение становится активным. Я создал функцию showSplash, которую я вызываю в applicationDidBecomeActive:

-(void)showSplash
{
    UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"Default.png"]];
    [self.window.rootViewController.view addSubview: splashScreen];
    [self.window makeKeyAndVisible];
    NSLog(@"begin splash");
    [UIView animateWithDuration: 4.2
                          delay: 0.5
                        options: UIViewAnimationOptionCurveEaseOut
                     animations: ^{  
                         splashScreen.alpha = 0.0;
                     }
                     completion: ^ (BOOL finished) {
                         [splashScreen removeFromSuperview];
                         NSLog(@"end splash");
                     }
     ];
}  

Вот как я вызываю эту функцию:

- (void)applicationDidBecomeActive:(UIApplication *)application {
[self showSplash];
}

Но экран всплеска не появляется. Пожалуйста, поправьте меня.

Ответы

Ответ 1

после добавления всплеска - доведите его до фронта

изменить

UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"Default.png"]];
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];

к

UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"Default.png"]];
[self.window addSubview: splashScreen];
[self.window bringSubviewToFront: splashScreen]; //!
[self.window makeKeyAndVisible];

Ответ 2

Если вы хотите, чтобы приложение получало новый старт каждый раз, когда вы возвращаетесь к нему, вы также можете отключить фоновое выполнение, как указано в Apple Documentation (последняя раздел "Отказ от выполнения фона" ):

Если вы не хотите, чтобы ваше приложение запускалось в фоновом режиме вообще, вы можете явно отказаться от фона, добавив ключ UIApplicationExitsOnSuspend (со значением ДА) для ваших приложений Info.plist.

Ответ 3

Пожалуйста, убедитесь, что основной вид контроллера корневого окна Windows является самым большим видом в вашем приложении в тот момент, когда вы хотите показать всплеск...

Ответ 4

Проверьте рамку splashScreen (UIImageView). Установите фрейм в рамки вашего корневого контроллера.

Ответ 5

Вы можете попытаться найти контроллер верхнего уровня с рекурсией, подобной этой:

- (UIViewController *)findTopViewController {
   return [self topViewControllerFrom:self.window.rootViewController];
}

- (UIViewController *)topViewControllerFrom:(UIViewController *)vc {
    if (vc.navigationController.visibleViewController != nil) {
        return [self topViewControllerFrom:vc.navigationController.visibleViewController];
    }
    if (vc.tabBarController.selectedViewController != nil) {
        return [self topViewControllerFrom:vc.tabBarController.selectedViewController];
    }
    return vc;
}

Теперь вызов [self findTopViewController] должен надеяться вернуть текущий видимый/верхний VC вашего приложения, и вы можете сделать:

[[self findTopViewController].view addSubview:splashScreen];
...

Ответ 6

вы можете сделать что-то вроде:

#import "AppDelegate.h"

#define kSplashScreen (UIScreen.mainScreen.bounds.size.height == 568) ? @"Default-568h" \
            : (UIScreen.mainScreen.bounds.size.height == 667) ? @"Default-667" \
            : (UIScreen.mainScreen.bounds.size.height == 736) ? @"Default-Portrait" \
            : @"Default"

@interface AppDelegate ()
@property (nonatomic) UIWindow *splashWindow;
@property (nonatomic) UIWindow *keyWindow;
@property (nonatomic, getter=isSplashConfigured) BOOL splashConfigured;
@property (nonatomic, getter=isShowingSplash) BOOL showingSplash;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self animateSplash];
    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [self showOrHideSplash];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [self showOrHideSplash];
}

- (void)showOrHideSplash
{
    [self.splashWindow setHidden:[self isShowingSplash]];
    if ([self isShowingSplash])
    {
        [self.keyWindow makeKeyAndVisible];
    }
    else
    {
        [self.splashWindow makeKeyAndVisible];
        [self animateSplash];
    }
    self.showingSplash = !self.showingSplash;
}


- (void)animateSplash
{
    if ([self isSplashConfigured])
    {
        [self.window.rootViewController.view addSubview:self.splashWindow];
        [self.window makeKeyAndVisible];
    }
    else
    {
        self.keyWindow = [[UIApplication sharedApplication] keyWindow];
        self.splashWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        self.splashWindow.rootViewController = [[UIViewController alloc] init];
        self.splashWindow.rootViewController.view.frame = self.splashWindow.bounds;
        UIImageView *splashImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:kSplashScreen]];
        splashImage.frame = self.splashWindow.bounds;
        [self.splashWindow.rootViewController.view addSubview:splashImage];
        [self.splashWindow makeKeyAndVisible];
        [self.splashWindow setHidden:YES];
        self.splashConfigured = YES;
    }
    NSLog(@"begin splash");
    __weak AppDelegate* weakSelf = self;
    [UIView animateWithDuration:4.2 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations: ^{
        weakSelf.splashWindow.alpha = 1.0;
        weakSelf.splashWindow.alpha = 0.0;
    } completion: ^(BOOL finished) {
        [weakSelf.splashWindow removeFromSuperview];
        NSLog(@"end splash");
    }];
}
@end

Ответ 7

Это немного громоздкое решение, но оно отлично работает. Идея заключается в добавлении нового UIWindow поверх всех контроллеров

- (void)showSplash {
    id <UIApplicationDelegate> appDelegate = [[UIApplication sharedApplication] delegate];
    UIWindow *window = [[UIWindow alloc] initWithFrame:[appDelegate window].frame];
    UIViewController *splashController = [UIViewController new];
    UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Default.png"]];
    splashController.view = imgView;
    window.rootViewController = splashController;
    window.windowLevel = UIWindowLevelAlert;
    window.hidden = NO;
    [window makeKeyAndVisible];
    [UIView animateWithDuration:4.2 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations:^{
        window.alpha = 0.0;
    } completion:^(BOOL finished) {
        window.hidden = YES;
        window.rootViewController = nil;
        [[appDelegate window] makeKeyAndVisible];
        [[appDelegate window] setNeedsDisplay];
    }];
}

Ответ 8

Ниже приведено решение этой проблемы.

Разделите код заставки на два метода; showSplash и hideSplash.

Вызвать showSplash в методе applicationWillResignActive. В методе создайте и добавьте imageView в rootViewController; установите альфа на 0.0f, а затем оживите его до альфа 1.0f. Это делается для того, чтобы пользователь не видел imageView, когда приложение будет фоном.

Теперь вызовите hideSplash в applicationDidBecomeActive. В hideSplash удалите imageView с анимацией. См. Код ниже;

-(void)showSplash
{
    _splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"Default"]];
    [self.window.rootViewController.view addSubview:_splashScreen];
    _splashScreen.alpha = 0.0f;
    [UIView animateWithDuration:0.3f animations:^{
        _splashScreen.alpha = 1.0f;
    }];
}
- (void)hideSplash
{
    [UIView animateWithDuration: 4.2
                          delay: 0.5
                        options: UIViewAnimationOptionCurveEaseOut
                     animations: ^{
                         _splashScreen.alpha = 0.0;
                     }
                     completion: ^ (BOOL finished) {
                         [_splashScreen removeFromSuperview];
                         NSLog(@"end splash");
                     }
     ];
}
- (void)applicationWillResignActive:(UIApplication *)application {
    [self showSplash];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
    [self hideSplash];
}

Надеюсь, это поможет!: -)

Ответ 9

Добавить

splashScreen.frame = self.window.rootViewController.view.frame;

ниже

UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"alertBg.png"]];

Пример

-(void)showSplash
{
    UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"Default.png"]];
    splashScreen.frame = self.window.rootViewController.view.frame;
    [self.window.rootViewController.view addSubview: splashScreen];
    [self.window makeKeyAndVisible];
    NSLog(@"begin splash");
    [UIView animateWithDuration: 4.2
                          delay: 0.5
                        options: UIViewAnimationOptionCurveEaseOut
                     animations: ^{
                         splashScreen.alpha = 0.0;
                     }
                     completion: ^ (BOOL finished) {
                         [splashScreen removeFromSuperview];
                         NSLog(@"end splash");
                     }
     ];
}

Ответ 10

Лучший способ добиться этого - добавить изображение в AppDelegate window. В приведенном ниже коде statusView это одно из представлений, состоящее из некоторого изображения. Поэтому добавьте его в AppDelegate window как subView

[[[[UIApplication sharedApplication] delegate] window] addSubview:statusView];

Теперь, когда вы хотите, чтобы он отображался в течение некоторого времени, вы показываете это представление, но в то же время переносите его на передний план.

-(void)showStatusView{

    [UIView animateWithDuration:0.5 animations:^{
        [[[[UIApplication sharedApplication] delegate] window] bringSubviewToFront:statusView];
        statusView.alpha = 1;
    }];
}

Лучше Вызовите описанный выше метод AppDelegate's didBecomeActive.

Также покажите заставку, как только приложение будет отменено. Таким образом, iOS возьмет снимок экрана, который будет отображаться в течение нескольких секунд, когда приложение вот-вот станет активным.

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [self showStatusView];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [self showStatusView];
}

Как только приложение будет активным, вы можете показать фактический экран заставки на некоторое время, а затем ваше обычное состояние приложения.

Ответ 11

Сначала создайте экран запуска или изображение в функции didFinishLaunchingWithOptions.

AppDelegate.m

После этого напишите свой код следующим образом:

enter image description here

Ответ 12

Контроллер корневого представления не всегда является представленным контроллером представления. Это может привести к тому, что ваш экран заставки будет скрыт под кучей других контроллеров. Попробуйте использовать что-то вроде (swift syntex):

func getTopViewController() -> UIViewController?{
    if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController{
        while ((topController.presentedViewController) != nil) {
            topController = topController.presentedViewController!
        }
        return topController
    }
    return nil
}

И добавьте ваш всплеск в контроллер верхнего уровня

Ответ 13

запускайте приложение обычно каждый раз, вызывайте свой метод в приложении ApplicationBecomeActive и добавляйте изображение на Appdelegate.window и удаляете его через некоторое время по таймеру.

[self.window addSubview: splashScreen];

Ответ 14

Вы должны использовать следующую строку:

[self.window addSubview: splashScreen];

вместо

[self.window.rootViewController.view addSubview: splashScreen];