美文网首页Kevin的IOS开发专题我爱编程
【IOS开发基础系列】启动页专题

【IOS开发基础系列】启动页专题

作者: Kevin_Junbaozi | 来源:发表于2018-04-07 18:15 被阅读20次

    总述:

            两种方式,一种是使用系统自带的,按规则定义启动图片名称即可,显示为1秒,要想延长时间,用[nsthread sleepForTimeInterval:5.0],另一种就是自定义uiivew,加到window中去。

    1 系统自带方式

    1.1 添加图片

        1,准备图片资源,放入工程中,即可,默认时间为1s

          iOS设备现在有三种不同的分辨率:iPhone 320x480、iPhone 4 640x960、iPad 768x1024。以前程序的启动画面(图片)只要准备一个 Default.png 就可以了,但是现在变得复杂多了。下面就是 CocoaChina 会员做得总结。

          如果一个程序,既支持iPhone又支持iPad,那么它需要包含下面几个图片:

    Default-Portrait.png iPad专用竖向启动画面 768x1024或者768x1004

    Default-Landscape.png iPad专用横向启动画面 1024x768或者1024x748

    Default-PortraitUpsideDown.png iPad专用竖向启动画面(Home按钮在屏幕上面),可省略 768x1024或者768x1004

    Default-LandscapeLeft.png iPad专用横向启动画面,可省略 1024x768或者1024x748

    Default-LandscapeRight.png iPad专用横向启动画面,可省略 1024x768或者1024x748

    Default.png iPhone默认启动图片,如果没有提供上面几个iPad专用启动图片,则在iPad上运行时也使用Default.png(不推荐) 320x480或者320x460

    Default@2x.png iPhone4启动图片640x960或者640x920

          为了在iPad上使用上述的启动画面,你还需要在info.plist中加入key: UISupportedInterfaceOrientations。同时,加入值UIInterfaceOrientationPortrait, UIInterfacOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight。

    1.2 延迟时间

    2,如果想想设启动画面的显示时间,

    在XXXAppDelegate.m的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions方法中插入以下一行代码:

    // Insert delay of 5 seconds befor the splash screen disappers.

      [NSThread sleepForTimeInterval:5.0];  // 其实这一行代码也可以不加,因为默认情况下欢迎界面的时间只有一秒,加这一句是为了延长欢迎界面的展示时间到5秒,时间大家可以自己定义。

    1.3 启动时显示状态栏

            在-info.plist 文件中加入选项 "Status bar is initially hidden", 值为YES

            在 AppDelegate.m 文件中的 - (BOOL)application: (UIApplication*)application  didFinishLaunchingWithOptions: (NSDictionary *)launchOptions 方法内加入代码:   

    [[UIApplication sharedApplication] setStatusBarHidden: NO];

    【注意】

            如果你的程序同时使用了导航栏作为根视图控制器 UINavigationController,则应该将语句 [[UIApplication sharedApplication] setStatusBarHidden:NO] 放在 [self.window makeKeyAndVisible]; 之前,否则会出现状态栏与导航栏重叠的情况。可能是因为调用 makeKeyAndVisible 时会去判断当前程序是否显示状态栏,以此来布导航栏的位置。

    2 自定义方法

    3,在XXXAppDelegate.m的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary*)launchOptions中通过使用uiview或uiimageview等控件自定义启动画面。

    3 App图标添加

    参考链接:

    http://www.cnblogs.com/xuzhong/p/3775975.html

        The app icon set named "AppIcon" did not have anyapplicable content.

        Solution:

        1.DeleteApp Icon segment in Images.xcassets.

        2.Createa new App Icon segment in Images.xcassets. (It will add all iOS device iconsize needness)

        3.Modifythe icon size to mach the icon size.

        4.Dropinto the icon set.

        5.Rebuild.

    4 引导页开发

    4.1 UIScrollview+UIImageView方案

            我们在第一次打开App的时候,通常不是直接进入App主界面,而是会有一个能左右滑动、介绍App功能的界面。我是用NSUserDefaults + UIScrollview实现。

            新建一个类,继承UIView,假设名为Guide。在initWithFrame方法里:

      CGFloat screenHeight = [UIScreenmainScreen].bounds.size.height;

      UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame: frame];

      scrollView.backgroundColor = [UIColor whiteColor];

     scrollView.showsHorizontalScrollIndicator = NO;

     scrollView.showsVerticalScrollIndicator = NO;

      scrollView.contentSize = CGSizeMake(320*4, screenHeight);

      scrollView.pagingEnabled = YES;

      for (int i=0; i<4; i++) {

            UIImageView* imageView = [[UIImageView alloc initWithFrame: CGRectMake(i*320, 0, 320, screenHeight)];

      imageView.contentMode = UIViewContentModeScaleAspectFill;

      NSString *filePath = [[NSBundle mainBundle] pathForResource: [NSString stringWithFormat: @"FileName" ofType: @"FileType"];

      imageView.image = [UIImage imageWithContentsOfFile: filePath];

      [scrollView addSubview: imageView];

      if (i == 3) {

        UIButton* start = [UIButton buttonWithType: UIButtonTypeCustom];

        start.frame = CGRectMake(0, 0, 100, 44);

        start.layer.cornerRadius =5;

        start.layer.borderWidth =0.5;

        [start setCenter: CGPointMake(1120, iPhone5?450:400)];

        [start setTitleColor: [UIColor grayColor] forState: UIControlStateNormal];

        [start addTarget: self action: @selector(closeView) forControlEvents: UIControlEventTouchUpInside];

        [start setTitle: @"Start" forState: UIControlStateNormal];

        [scrollView addSubview: start];

      }

            这样,就有了一个有4张图片的引导页。怎么去判断是不是第一次登陆呢,需要用到NSUserDefaults类。在didFinishLaunchingWithOptions:函数中可以这样判断:

    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];

    if([userDefaults objectForKey: @"FirstLoad"] == nil) {

        [userDefaults setBool: NO forKey: @"FirstLoad"];

        //显示引导页

    }

    4.2 UIScrollview+UIPageControl

    ios用户引导页

    http://blog.csdn.net/wanglj7525/article/details/43408809

    http://www.open-open.com/lib/view/open1411201907593.html

    http://blog.csdn.net/yesjava/article/details/7894663

    @interface WelcomeViewController ()

    @end

    @implementation WelcomeViewController

    - (void)viewDidLoad {

        [super viewDidLoad];

        [self setupScrollView];

        [self setupPageControl];

    }

    //创建程序第一次加载要显示的视图

    - (void)setupScrollView

    {

        CGRect r = [[UIScreen mainScreen] applicationFrame];

        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame: [UIScreen mainScreen].bounds];

        scrollView.delegate =self;

        [self.view addSubview: scrollView];

        //关闭水平方向上的滚动条

        scrollView.showsHorizontalScrollIndicator =NO;

        //是否可以整屏滑动

        scrollView.pagingEnabled =YES;

        scrollView.tag =200;

        scrollView.contentSize = CGSizeMake(r.size.width *3, [UIScreen mainScreen].bounds.size.height);

        for (int i = 0; i < 3; i++) {

            UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(r.size.width * i, 0, r.size.width, [UIScreen mainScreen].bounds.size.height)];

            imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource: [NSString stringWithFormat: @"t%d_full", i +1] ofType: @"jpg"]];

            [scrollView addSubview: imageView];

        }

        UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom];

        button.backgroundColor = [UIColor darkGrayColor];

        [button setTitle: @"开始体验" forState: UIControlStateNormal];

        button.frame = CGRectMake(r.size.width*2 + r.size.width/2-50,[UIScreen mainScreen].bounds.size.height - 80, 100, 30);

        [button addTarget: self action: @selector(showDocList) forControlEvents: UIControlEventTouchUpInside];

        [button setImage: [UIImage imageNamed: @"start.png"] forState: UIControlStateNormal];

        button.imageEdgeInsets = UIEdgeInsetsMake(0, 80, 0, 0);

        button.titleEdgeInsets = UIEdgeInsetsMake(0, -40, 0, 20);

        [scrollView addSubview: button];

    }

    //跳转到主页面

    - (void) showDocList{

        ScrollerViewController *mainList=[self.storyboard instantiateViewControllerWithIdentifier: @"mainNavigation"];

        [self presentViewController: mainList animated: NO completion: nil];

    }

    - (void)setupPageControl

    {

        UIPageControl *pageControl = [[UIPageControl alloc] initWithFrame: CGRectMake(0, [UIScreen mainScreen].bounds.size.height -40, [UIScreen mainScreen].bounds.size.width, 20)];

        pageControl.tag =100;

        //设置表示的页数

        pageControl.numberOfPages =3;

        //设置选中的页数

        pageControl.currentPage =0;

        //设置未选中点的颜色

        pageControl.pageIndicatorTintColor = [UIColor whiteColor];

        //设置选中点的颜色

        pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];

        //添加响应事件

        [pageControl addTarget: self action: @selector(handlePageControl:) forControlEvents: UIControlEventValueChanged];

        [self.view addSubview: pageControl];

    }

    - (void) scrollViewDidEndDecelerating: (UIScrollView *)scrollView

    {

        UIPageControl *pagControl = (UIPageControl *)[self.view viewWithTag: 100];

        pagControl.currentPage = scrollView.contentOffset.x / [UIScreen mainScreen].bounds.size.width;

    }

    - (void) handlePageControl: (UIPageControl *)pageControl

    {

        //切换pageControl .对应切换scrollView不同的界面

        UIScrollView *scrollView = (UIScrollView *)[self.view viewWithTag: 200];

        // [scrollView setContentOffset: CGPointMake(320 * pageControl.currentPage,0) animated: YES];

    }

    4.3 第三方库MYBlurIntroductionView方案

    4.3.1 设计思路

            新建一个LaunchVC,然后在RootVC中以模态窗口的方式弹出此VC。引导页采用本地缓存方式,支持从服务端动态加载然后更新显示。

    4.3.2 LaunchVC弹出逻辑

            LaunchVC弹出逻辑(注意只加载一次):

    if (![HJUtility hasLoadLaunchView]) {

        _launchVC = [[HJLaunchViewController alloc] init];

        [self.navigationController presentViewController: _launchVC animated:NO completion: nil];

    }

    4.3.3 LaunchVC初始化逻辑

    LaunchVC初始化逻辑:

    - (void)viewDidLoad {

        [super viewDidLoad];

        [self initSubViews];

    }

    -(void) initSubViews

    {

        if (!_introductView) {

            [self initIntroductView];

        }

    }

    -(void)initIntroductView

    {

        NSArray *launchImgFileArr = [HJUtility getLaunchImgFilePathArr];

        if ([launchImgFileArr count] <= 0) {

            return;

        }

        //动态加载引导页图片

        NSMutableArray *panelMArr = [[NSMutableArray alloc] init];

        for (NSString *imgFile in launchImgFileArr) {

            //Create Stock Panel With Image

            HJLaunchView *launchView = [[HJLaunchView alloc] initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) withbackImg: [UIImage imageWithContentsOfFile: imgFile]];

            [panelMArr addObject: launchView];

        }

        //Create the introduction view and set its delegate

        MYBlurIntroductionView *introductionView = [[MYBlurIntroductionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

        introductionView.delegate = self;

        _introductView= introductionView;

        //Build the introduction with desired panels

        [introductionView buildIntroductionWithPanels: panelMArr];

        //Add the introduction to your view

        [self.view addSubview: introductionView];

    }

    4.3.4 本地缓存引导图片逻辑

    + (BOOL) hasLoadLaunchView

    {

        BOOL loaded = [[[NSUserDefaults standardUserDefaults] valueForKey: kHasLoadLaunchView] boolValue];

        returnloaded;

    }

    //刷新本地缓存的引导页图片数据

    + (void) loadLaunchImgData

    {

        // 获取Documents目录路径

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSString *docDir = [paths objectAtIndex:0];

        NSString*launchDir = [docDir stringByAppendingString: @"/LaunchImg"];

        NSFileManager *fm= [NSFileManager defaultManager];

        if(![fm fileExistsAtPath: launchDir]){

            NSError *error = nil;

            //下面是对该文件进行制定路径的保存

            [fm createDirectoryAtPath: launchDir withIntermediateDirectories: YES attributes: nil error: nil];

            NSString *sourcePath = [[NSBundle mainBundle] pathForResource: @"1" ofType: @"jpg"];

            NSString *toPath = [launchDir stringByAppendingString: @"/1.jpg"];

            [fm copyItemAtPath: sourcePath toPath: toPath error: &error];

            if(error) {

                return;

            }

            sourcePath = [[NSBundle mainBundle] pathForResource: @"2" ofType: @"jpg"];

            toPath = [launchDir stringByAppendingString: @"/2.jpg"];

            [fm copyItemAtPath: sourcePath toPath: toPath error: &error];

            if(error) {

                return;

            }

            sourcePath = [[NSBundle mainBundle] pathForResource: @"3" ofType: @"jpg"];

            toPath = [launchDir stringByAppendingString: @"/3.jpg"];

            [fm copyItemAtPath: sourcePath toPath: toPath error: &error];

            if(error) {

                return;

            }

            sourcePath = [[NSBundle mainBundle] pathForResource: @"4" ofType: @"jpg"];

            toPath = [launchDir stringByAppendingString: @"/4.jpg"];

            [fm copyItemAtPath: sourcePath toPath: toPath error: &error];

            if(error) {

                return;

            }

            [[NSUserDefaults standardUserDefaults] setValue: [NSNumber numberWithBool: NO] forKey: kHasLoadLaunchView];

        }

        else

        {

            [[NSUserDefaults standardUserDefaults] setValue: [NSNumber numberWithBool: YES] forKey: kHasLoadLaunchView];

        }

    }

    + (NSArray*) getLaunchImgFilePathArr

    {

        NSArray*paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSString*docDir = [paths objectAtIndex: 0];

        NSString*launchDir = [docDir stringByAppendingString: @"/LaunchImg"];

        NSFileManager* fm = [NSFileManager defaultManager];

        //取得一个目录下得所有文件名

        NSArray*files = [fm subpathsAtPath: launchDir];

        if([files count] > 0) {

            NSMutableArray *filePathArr = [[NSMutableArray alloc] init];

            for (NSString *fp in files) {

                [filePathArr addObject: [launchDir stringByAppendingString: [NSString stringWithFormat: @"/%@", fp]]];

            }

            return filePathArr;

        }

        else

            return nil;

    }

    4.4 广告倒数页设计

            除了功能引导页,广告倒数页的加入也很有讲究,主要思路是:

            单独定义一层UIWindow,Level在功能引导页之下,在AppDelegate.window之上,在Alert之下。广告页自定义View也需要先加入到VC中,然后将该VC指定为UIWindow的rootVC,在AppDelegate.window加载完之后在初始化该window,并makeKeyAndVisible。

    5 半透明遮罩

    5.1 法一

            我最后采取的方法,是present一个窗口化的ViewController。但是这个窗口默认的背景色是磨砂不透明的,因此还需要把它的背景色设为透明。这样看起来就像是全屏遮罩一样,但是由于系统不认为新的View是全屏的,所以上一个View也不会被unload。

    YLSLockScreenViewController *lockScreenController = [[YLSLockScreenViewController alloc] init];

    lockScreenController.modalPresentationStyle = UIModalPresentationFormSheet;// 窗口

    [self.mainViewController presentViewController: lockScreenController animated:YES completion:^(void){

       lockScreenController.view.superview.backgroundColor = [UIColorclearColor];//背景色透明

    }];

            代码比较简单,需要注意的是,设置背景色透明的那行代码,需要写在completion block里,而且设置的不是controller.view.backgroundColor,而是controller.view.superview.backgroundColor。

    iOS7实现全屏模态半透明页面的效果

    http://www.open-open.com/lib/view/open1392707807819.html

    5.2 法二(good)

    backgroundView = [[UIView alloc] init];

    backgroundView.frame= CGRectMake(0, 0,kWidth,kHeight);

    backgroundView.backgroundColor= [UIColor colorWithRed: (40/255.0f) green: (40/255.0f) blue:(40/255.0f) alpha: 1.0f];

    backgroundView.alpha= 0.4;

    [self.view.window addSubview: backgroundView];

            建立一个view设置背景颜色  调整 alpha值

    iOS模糊半透明效果实现

    http://my.oschina.net/kevinvane/blog/129707

    6 开发技巧

    6.1 开发问题收集

    6.1.1 20秒启动超时闪退问题failedto scene-create after

            IOS APP,如果启动时间超过了20s,操作系统就会自动将app关闭,导致app启动不起来。因此App启动过程中,应该尽量少在主线程中做耗时操作,如果一定需要,例如需要做一些串行请求,就要注意设置超时时间,而且应该尽量短。

    7 参考链接

    IOS启动页面制作

    http://my.oschina.net/xiahuawuyu/blog/169113

    ios用户引导页

    http://blog.csdn.net/wanglj7525/article/details/43408809

    IOS用户引导界面示例

    http://www.open-open.com/lib/view/open1411201907593.html

    ios页面跳转

    http://blog.csdn.net/yesjava/article/details/7894663

    iOS开发UIScrollView制作APP引导页

    http://jingyan.baidu.com/article/4dc40848a341dfc8d846f152.html

    iOS引导页实现(一)

    http://blog.csdn.net/lwjok2007/article/details/46516047

    iOS启动时如何添加引导页面 小demo

    http://blog.csdn.net/yudandan10/article/details/42009511

    IOS闪屏制作——程序启动动画

    http://my.oschina.net/amoyai/blog/94988

    ios实现引导页面效果

    http://blog.csdn.net/leechee_1986/article/details/24850547

    半透明遮罩是如何实现的(如图)

    http://www.cocoachina.com/bbs/read.php?tid=94649

    What does this crash report tell me about why my app failsto start?

    http://stackoverflow.com/questions/28003151/what-does-this-crash-report-tell-me-about-why-my-app-fails-to-start/28003188#28003188

    Crash on launch because app is taking too long - deadlock -keychain

    http://stackoverflow.com/questions/26482765/crash-on-launch-because-app-is-taking-too-long-deadlock-keychain

    iOS app works on xCode but crash running from device.

    https://pompidev.net/2014/11/16/ios-app-works-on-xcode-but-crash-running-from-device/

    iOS严重问题解释(crash)

    http://blog.csdn.net/mtc1256/article/details/52595160

    App rejection - Crash report says: failed to scene-create intime (badf00d) What is wrong?

    http://stackoverflow.com/questions/26827809/app-rejection-crash-report-says-failed-to-scene-create-in-time-badf00d-what

    iOS应用启动速度

    http://blog.csdn.net/fg313071405/article/details/8312772

    相关文章

      网友评论

        本文标题:【IOS开发基础系列】启动页专题

        本文链接:https://www.haomeiwen.com/subject/hqupcftx.html