zoukankan      html  css  js  c++  java
  • iOS7 界面适配-NavigationBar StateBar

     

    转 blog.csdn.net/ibcker/article/details/12115437

    最近项目有个棘手的问题--适配IOS7....

    由于IOS7把整个内容区都上移了20,所以很多不是全屏的应用都不能很好的兼容,换用苹果文档的一句话就是说:如果你们原来的app就是全屏模式运行的,那你们几乎不用改,如果不是,那·····

     

    改之前很有必要去阅读下苹果官方的《ios7过渡指南》http://t.cn/zRv5lQT  ,当然,也有人翻译了一份··如果那什么可以看中文的·· http://t.cn/zHDbDCz (吐槽下“实现方法是在Info.plist中加入键UIViewControllerBasedStatusBarAppearance,并设置值为YES。”这句话好像翻译反了··)

    来说说问题,由于主要问题界面给默认全屏了···也就是说原来statusbar的20像素没了,所以如果想比较快速的适配ios7,比较好的做法是:


    step 1 写个UIViewController的Category让UIViewController默认的wantsFullScreenLayout返回YES,同时edgesForExtendedLayout默认返回All,目的是让所有版本都统一全屏


    .h代码如下

     

        #import <UIKit/UIKit.h>  
          
        #ifndef __IPHONE_7_0  
        typedef NS_OPTIONS(NSUInteger, UIRectEdge) {  
            UIRectEdgeNone   = 0,  
            UIRectEdgeTop    = 1 << 0,  
            UIRectEdgeLeft   = 1 << 1,  
            UIRectEdgeBottom = 1 << 2,  
            UIRectEdgeRight  = 1 << 3,  
            UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight  
        };  
        #endif  
          
        @interface UIViewController (UIRectEdge)  
          
        //#ifndef __IPHONE_7_0  
        - (BOOL)automaticallyAdjustsScrollViewInsets;  
        - (void)setAutomaticallyAdjustsScrollViewInsets:(BOOL)b;  
        - (UIRectEdge)edgesForExtendedLayout;  
        - (void)setEdgesForExtendedLayout:(UIRectEdge)rect;  
        //#endif  
        @end  
     

    .m

     
        #import "UIViewController+UIRectEdge.h"  
          
        #import <objc/runtime.h>  
          
        @implementation UIViewController (UIRectEdge)  
          
        static const charchar *kWantsFullScreenLayoutKey;  
          
        - (BOOL)wantsFullScreenLayout  
        {  
            id v=objc_getAssociatedObject(self,&kWantsFullScreenLayoutKey);  
            if (v!=nil) {  
                return [v boolValue];  
            }else{  
                return YES;  
            }  
        }  
          
        - (void)setWantsFullScreenLayout:(BOOL)b  
        {  
            objc_setAssociatedObject(self, &kWantsFullScreenLayoutKey, @(b), OBJC_ASSOCIATION_ASSIGN);  
        }  
          
        static const charchar *kAutomaticallyAdjustsScrollViewInsetsKey;  
          
        - (BOOL)automaticallyAdjustsScrollViewInsets  
        {  
            id v=objc_getAssociatedObject(self,&kAutomaticallyAdjustsScrollViewInsetsKey);  
            if (v!=nil) {  
                return [v boolValue];  
            }else{  
                return NO;  
            }  
        }  
          
        - (void)setAutomaticallyAdjustsScrollViewInsets:(BOOL)b  
        {  
            objc_setAssociatedObject(self, &kAutomaticallyAdjustsScrollViewInsetsKey, @(b), OBJC_ASSOCIATION_ASSIGN);  
        }  
          
          
        static const charchar *kEdgesForExtendedLayoutKey;  
          
        - (UIRectEdge)edgesForExtendedLayout  
        {  
            id v=objc_getAssociatedObject(self,&kEdgesForExtendedLayoutKey);  
            if (v!=nil) {  
                return [v integerValue];  
            }else{  
                return UIRectEdgeAll;  
            }  
        }  
          
        - (void)setEdgesForExtendedLayout:(UIRectEdge)rect  
        {  
            objc_setAssociatedObject(self, &kEdgesForExtendedLayoutKey, @(rect), OBJC_ASSOCIATION_ASSIGN);  
        }  
          
        @end  



    step 2 然后写个UIApplication的category让5,6上状态栏底色消失.

    照例直接贴代码

    .h

     
        #import <UIKit/UIKit.h>  
          
        @interface UIApplication (UI7)  
        + (void)inject;  
        @end  


    .m

     
        #import "UIApplication+UI7.h"  
        #import <objc/runtime.h>  
        #import <QuartzCore/QuartzCore.h>  
          
        #define _IOS_VERSION_UI7 ([[[UIDevice currentDevice] systemVersion] floatValue])  
          
        #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_3  
        #error UI7NavigationBar doesn't support Deployement Target version < 4.3  
        #endif  
          
        @implementation UIApplication (UI7)  
          
        + (void)inject  
        {  
            Method originMethod=class_getInstanceMethod(self, @selector(setStatusBarStyle:));  
            Method newMethod=class_getInstanceMethod(self, @selector(__setStatusBarStyle:));  
              
            method_exchangeImplementations(originMethod, newMethod);  
              
            originMethod=class_getInstanceMethod(self, @selector(setStatusBarStyle:animated:));  
            newMethod=class_getInstanceMethod(self, @selector(__setStatusBarStyle:animated:));  
              
            method_exchangeImplementations(originMethod, newMethod);  
        }  
          
        - (void)__setStatusBarStyle:(UIStatusBarStyle)style  
        {  
            [self __setStatusBarStyle:style];  
            if (style==UIStatusBarStyleBlackTranslucent) {  
                [self hiddenStatusBarBackground:YES];  
            }  
        }  
          
        -(void)__setStatusBarStyle:(UIStatusBarStyle)style animated:(BOOL)animated  
        {  
            [self __setStatusBarStyle:style animated:animated];  
              
            if (style==UIStatusBarStyleBlackTranslucent) {  
                if (animated) {  
                    [self performSelector:@selector(hiddenStatusBarBackground:) withObject:@(YES) afterDelay:0.6];  
                }else{  
                    [self hiddenStatusBarBackground:YES];  
                }  
            }  
        }  
          
        - (void)hiddenStatusBarBackground:(BOOL)hidden  
        {  
            if(_IOS_VERSION_UI7<7){  
                BOOL isStatusBarHidden=[[UIApplication sharedApplication] isStatusBarHidden];  
                if (isStatusBarHidden) {  
                    [[UIApplication sharedApplication] setStatusBarHidden:NO];  
                }  
                UIView *statusbar=[[UIApplication sharedApplication] valueForKey:@"_statusBar"];  
                NSArray *vs=[statusbar subviews];  
                for (UIView *v in vs) {  
                    if ([v isKindOfClass:NSClassFromString(@"UIStatusBarBackgroundView")]) {  
                        statusbar=v;  
                        break;  
                    }  
                }  
                if (isStatusBarHidden) {  
                    [[UIApplication sharedApplication] setStatusBarHidden:YES];  
                }  
                if (hidden) {  
                    [statusbar setHidden:YES];  
                }else{  
                    [statusbar setHidden:NO];  
                }  
            }  
        }  
          
        @end  

     


    step 3实现一个UINavigationBar的子类,让自定义效果更加简单

    .h

     
    #import <UIKit/UIKit.h>  
      
    typedef NS_ENUM(NSUInteger, UI7NavBarSytle)  
    {  
        UI7NavBarSytleLight, //0.4 alpha  
        UI7NavBarSytleDark, //0.8 alpha  
        UI7NavBarSytleBlack, //1.0  
    };  
      
    @interface TTNavigationController : UINavigationController  
      
    - (void)setNavBarBgWithImage:(UIImage *)image;  
    - (void)setNavBarBgWithColor:(UIColor *)cl;  
    - (void)setNavBarStyle:(UI7NavBarSytle)style;  
      
    @end 


    .m

    #import "TTNavigationController.h"  
    #import "UIApplication+UI7.h"  
      
    @interface TTNavigationController ()  
    @property (nonatomic,strong)UIImageView *navColorOverly;  
    @end  
      
    @implementation TTNavigationController  
      
      
    - (void)viewDidLoad  
    {  
        [super viewDidLoad];  
          
        self.navigationBar.opaque = NO;  
        if (kCFCoreFoundationVersionNumber>=kCFCoreFoundationVersionNumber_iOS_5_0) {  
            NSArray *vs=[self.navigationBar subviews];  
            Class clazz;  
            if (kCFCoreFoundationVersionNumber>=kCFCoreFoundationVersionNumber_iOS_6_0) {  
                clazz=NSClassFromString(@"_UINavigationBarBackground");  
            }else{  
                clazz=NSClassFromString(@"UINavigationBarBackground");  
            }  
            for (UIView *v in vs) {  
                if ([v isKindOfClass:clazz]) {  
                    v.hidden=YES;  
                    break;  
                }  
            }  
        }  
        [self setNavBarStyle:UI7NavBarSytleDark];  
        [self.navigationBar insertSubview:_navColorOverly atIndex:0];  
    }  
      
      
      
    - (UIImageView *)navColorOverly  
    {  
        if (!_navColorOverly) {  
            if (!_navColorOverly) {  
                _navColorOverly=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.navigationBar.frame.size.width, self.navigationBar.frame.size.height+20)];  
                _navColorOverly.frame=CGRectMake(0, -20, self.navigationBar.frame.size.width, 64);  
            }  
        }  
        return _navColorOverly;  
    }  
      
    - (void)setNavBarStyle:(UI7NavBarSytle)style  
    {  
        switch (style) {  
            case UI7NavBarSytleLight:  
                [self setNavBarBgWithColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]];  
                break;  
            case UI7NavBarSytleBlack:  
                [self setNavBarBgWithColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1]];  
                break;  
            default: //UI7NavBarSytleDark:  
                [self setNavBarBgWithColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.8]];  
                break;  
        }  
    }  
      
    - (void)setNavBarBgWithColor:(UIColor *)cl  
    {  
        UIGraphicsBeginImageContext(CGSizeMake(1, 1));  
        [cl set];  
        UIRectFill(CGRectMake(0, 0, 1, 1));  
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();  
        UIGraphicsEndImageContext();  
        self.navColorOverly.image=[image stretchableImageWithLeftCapWidth:1 topCapHeight:1];  
    }  
      
    - (void)setNavBarBgWithImage:(UIImage *)image  
    {  
        self.navColorOverly.image=image;  
    }  
      
    @end  
    @implementation UINavigationBar (CustomImage)  
    - (void)drawRect:(CGRect)rect {}  
    @end 

    step 4接着是刚才提到的,在info.plist里加入UIViewControllerBasedStatusBarAppearance,设为NO



    step 5接着就写个Demo试试效果吧。

    记得appdelegate的application:didFinishLaunchingWithOptions:里记得调用[UIApplicationinject];作用就是注入状态栏,让其底色透明



    简单看下效果(iOS 5,6,7):

     

     

    https://github.com/iBcker/UI7NavigationBar

  • 相关阅读:
    如何判断是否是ssd硬盘?win10查看固态硬盘的方法
    MongoDB简单使用 —— 基本操作
    MongoDB简单使用 —— 驱动
    Visual Studio新的 .csporj 文件
    MongoDB简单使用 —— 安装
    关于MongoDB时区问题
    利用dynamic简化数据库的访问
    BrowserLog——使用Chrome控制台作为Log查看器
    在Asp.net core返回PushStream
    使用GIT进行源码管理——GIT托管服务2018
  • 原文地址:https://www.cnblogs.com/allanliu/p/4532686.html
Copyright © 2011-2022 走看看