每次应用程序启动时显示启动画面

14

我希望每次应用程序启动时都显示启动画面。我已经创建了一个名为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];
}

但是没有启动画面出现。请指正我。


2
你能看到你的日志消息被打印出来了吗? - Phillip Mills
@PhillipMills:是的。它们被打印出来,但是闪屏从未显示。 - Nitish
self.window.rootViewController 是什么类型?另外,如果窗口在当前视图控制器上,makeKeyAndVisible 只会将其带到前面。如果您想要 rootViewController 的主窗口,则需要使用 [self.window.rootViewController.view.window makeKeyAndVisible] - Marcus Adams
我尝试了你的代码,它运行良好。你有检查过你的 "Default.png" 问题吗? - William Hu
2
@BlakeMerryman:我完全知道这一点。不过还是谢谢你。这是我正在开发的一个产品,而不是AppStore应用程序。 - Nitish
显示剩余6条评论
15个回答

7
如果你希望每次回到应用程序时都有一个全新的开始,你也可以禁用后台执行,如Apple文档所述(最后一节标题为“退出后台执行”):
如果您不希望应用程序在后台运行,可以通过向应用程序的Info.plist文件中添加UIApplicationExitsOnSuspend键(值为YES)来显式地选择退出后台。

3
那是一个很好的观点。谢谢。但我只想让闪屏每次都出现。应用程序的其余部分保持在后台离开时的状态。 - Nitish

5
在添加启动画面视图后,将其置于最前面。
更改。
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"Default.png"]];
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];

to

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

2
你可以做以下操作:

你可以像这样做:

#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

2
您可以尝试使用递归来“寻找”顶部视图控制器,方法如下:

- (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];
...

尝试在applicationDidBecomeActive上设置断点,然后当它中断时,在控制台中运行此命令:po [self findTopViewController],你会得到一个视图控制器还是nil - Aviel Gross
是的,这返回了 nil。但即使我在 didFinishLaunchingWithOptions 中获得我的 rootViewController - UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"ProjectsController"]; rootController = rootViewController; 它仍然不起作用。 - Nitish
在调用 [storyboard instantiateViewControllerWithIdentifier...] 后,您是否会像 self.window.rootViewController = rootViewController 这样调用某些内容? - Aviel Gross
@Nitish 你试过像这样设置启动屏幕图片视图的框架吗?splashScreen.frame=rootViewController.bounds? - dev gr
@AvielGross :正在执行以下操作:UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"ProjectsController"]; rootController = rootViewController; - Nitish
显示剩余2条评论

2

这是一个有些繁琐的解决方案,但它可以正常工作。想法是在所有控制器之上添加一个新的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];
    }];
}

2
请查看以下解决方案。
将启动画面代码拆分为两个方法:showSplashhideSplash
在方法applicationWillResignActive中调用showSplash。在该方法中,创建并添加imageViewrootViewController;将其alpha设置为0.0f,然后将其动画到alpha 1.0f。这是为了确保用户在应用程序进入后台时不会看到imageView。
现在在applicationDidBecomeActive中调用hideSplash。在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];
}

我希望这能对您有所帮助!:-)

2

添加

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");
                     }
     ];
}

2
实现此目标的最好方法是将图像添加到 AppDelegate 的 window 中。 在下面的代码中,statusView 是一个视图,其中包含一些图像。因此将其作为 subView 添加到你的 AppDelegate 的 window 中即可。
[[[[UIApplication sharedApplication] delegate] window] addSubview:statusView];

现在,每当您想让它显示一段时间时,您会显示此视图,但同时将其置于前台。
-(void)showStatusView{

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

AppDelegatedidBecomeActive方法上调用上述方法。

另外,在应用程序即将变为非活动状态时立即显示启动画面。这样,iOS会拍摄屏幕快照,在应用程序即将变为活动状态时显示该快照片段。

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

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

当应用程序激活后,您可以显示实际的启动画面一段时间,然后进入正常的应用状态。


2

根视图控制器并不总是呈现的视图控制器。这可能会导致您的启动屏幕被其他许多视图控制器遮盖。尝试使用以下代码(Swift语法):

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

将您的闪屏视图添加到顶部视图控制器。

2

首先在didFinishLaunchingWithOptions函数中创建您的启动屏幕或图像。

AppDelegate.m

然后按照以下方式编写您的代码-

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接