iOS基础之UIView、CALayer、UIControl、UIResponder、UIWindow、UIApplication、UIScreen、UIDevice

目录

  1. UIView : UIResponder
  2. CALayer : NSObject
  3. UIControl : UIView
  4. UIResponder : NSObject 事件响应基类
  5. UIWindow : UIView
  6. UIApplication : UIResponder
  7. UIScreen : NSObject
  8. UIDevice : NSObject 

1. UIView : UIResponder

几乎所有控件都直接或间接继承自UIView(即拥有UIView的属性和方法)

UIView是一块矩形区域,可用来作为其他控件的容器,继承自UIResponder所以拥有响应处理事件的能力。

    1. 父视图先于子视图渲染,视图后者居上,所以子视图绘制在父视图上方;
    2. 子视图只能有一个父视图,父视图可有多个子视图;
        重复addSubview会从上一个父视图中移除添加到新的父视图中
    3. 默认子视图的绘制范围可以超出父视图;

/*
1).UIView 是 iOS 系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由 CoreAnimation 来实现的。它真正的绘图部分,是由一个 CALayer 类来管理。 UIView 本身更像是一个 CALayer 的管理器,访问CALayer的跟绘图和跟坐标有关的属性。
2).UIView 有个重要属性 layer ,可以返回它的主 CALayer 实例。
3).UIView 的 CALayer 类似 UIView 的子 View 树形结构,也可以向它的 layer 上添加子layer ,来完成某些特殊的表示。即 CALayer 层是可以嵌套的。
4).UIView 的 layer 树形在系统内部,被维护着三份 copy 。分别是逻辑树,这里是代码可以操纵的;动画树,是一个中间层,系统就在这一层上更改属性,进行各种渲染操作;显示树,其内容就是当前正被显示在屏幕上得内容。
5).动画的运作:对 UIView 的 subLayer (非主 Layer )属性进行更改,系统将自动进行动画生成,动画持续时间的缺省值似乎是 0.5 秒。
6).坐标系统: CALayer 的坐标系统比 UIView 多了一个 anchorPoint 属性,使用CGPoint 结构表示,值域是 0~1 ,是个比例值。这个点是各种图形变换的坐标原点,同时会更改 layer 的 position 的位置,它的缺省值是 {0.5,0.5} ,即在 layer 的中央。
7).渲染:当更新层,改变不能立即显示在屏幕上。当所有的层都准备好时,可以调用setNeedsDisplay 方法来重绘显示。
8).变换:要在一个层中添加一个 3D 或仿射变换,可以分别设置层的 transform 或affineTransform 属性。
9).变形: Quartz Core 的渲染能力,使二维图像可以被自由操纵,就好像是三维的。图像可以在一个三维坐标系中以任意角度被旋转,缩放和倾斜。 CATransform3D 的一套方法提供了一些魔术般的变换效果。
*/

创建

    //
    UIView *view=[UIView new];
    [self.view addSubview:view];  
    [view autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];


方式一:[YTView new]    [[YTView alloc]init] 会先调用initWithFrame再调用init
方式二:[[YTView alloc]initWithFrame] 调用initWithFrame
所以仅需在initWithFrame中做基类相关逻辑。不能同时在init和initWithFrame调用同一个自定义方法。

/*
2个页面不同颜色,需要滚动过渡时可设置2个View的alpha,在scrollViewDidScroll方法中做相关逻辑
*/

常用

    // 设置 frame
    [view setFrame:CGRectMake(0, 0, 0, 0)];
    // [view setCenter:CGPointMake(0, 0)];  // center中心点
    // [view setBounds:CGRectMake(0, 0, 100, 20)];  // bounds

    // 设置 背景色
    [view setBackgroundColor:[UIColor blueColor]];
    // 设置 透明度
    [view setAlpha:1.0];
    // 设置 是否隐藏
    [view setHidden:true];
    // 设置 是否剪裁(true则子视图不会超过父视图的范围)
    [view setClipsToBounds:true];

    // 设置 tag(用于获取指定控件)
    [view setTag:100];
    // 获取 指定View(根据tag,不止可以从父视图中获取,还可以是从父父...View中获取,注意tag冲突)
    UIView *cusView=[self.view viewWithTag:100];

子视图(添加/移除)

    // 判断view 是否是 view2或View2的子View(包含孙子辈)
    BOOL isSubsView=[view isDescendantOfView:view2];

    // 获取所有一级子视图
    NSArray *viewArr=[view subviews];
    // 获取所在index
    NSInteger index=[view.subviews indexOfObject:subView];

    // 移到最上
    // 只在调用前该子View已经被渲染时有效(如hidden为true则无效)
    [view bringSubviewToFront:subView];
    // 移到最下
    [view sendSubviewToBack:subView];
    // 交换视图(指定索引)
    [view exchangeSubviewAtIndex:0 withSubviewAtIndex:1];

    // 添加子视图
    [view addSubview:subView];
    // 插入子视图(0在最下边,超过最大值则相当于addSubView不会崩)
    [view insertSubview:subView atIndex:0];
    // 插入子视图(位于指定视图上方)
    [view insertSubview:subView aboveSubview:subView2];
    // 插入子视图(位于指定视图下方)
    [view insertSubview:subView belowSubview:subView2];
    
    // 从父视图中移除
    [subView removeFromSuperview];
    // 移除所有子视图
    [view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

圆角、阴影、边框线

更多layer操作参见CALayer

contentMode

视图在初次绘制完成后,系统会对绘制结果进行快照,之后尽可能地使用快照,避免重新绘制。
如果视图的几何属性发生改变,系统会根据视图的 contentMode 来决定如何改变显示效果。默认的 contentMode 是 UIViewContentModeScaleToFill ,系统会拉伸当前的快照,使其符合新的 frame 尺寸。大部分 contentMode 都会对当前的快照进行拉伸或者移动等操作。如果需要重新绘制,可以把 contentMode 设置为 UIViewContentModeRedraw,强制视图在改变大小之类的操作时调用drawRect:重绘。

typedef NS_ENUM(NSInteger, UIViewContentMode) {
    UIViewContentModeScaleToFill,
    UIViewContentModeScaleAspectFit,      
    UIViewContentModeScaleAspectFill,    
    UIViewContentModeRedraw,         // 重新绘制     
    UIViewContentModeCenter,             
    UIViewContentModeTop,
    UIViewContentModeBottom,
    UIViewContentModeLeft,
    UIViewContentModeRight,
    UIViewContentModeTopLeft,
    UIViewContentModeTopRight,
    UIViewContentModeBottomLeft,
    UIViewContentModeBottomRight,
};

2. CALayer : NSObject

1、一个UIView对应一个CALayer(创建View后自动创建layer,真正用来显示内容,可以独立显示)。
改变view位置大小的实质是改变layer位置大小。
若superView和view构成父子视图,则superView.layer和view.layer构成父子图层关系。

2、CALayer不能响应交互(不是继承自UIResponder),UIView(是对CALayer的封装)可以响应交互。有些操作必须使用CALayer(如:阴影、圆角、边框线、3D形变、图像绘制、复杂动画)。

常用操作

圆角、阴影、边框线

    // 设置 圆角(对子图层无效)
    [view.layer setCornerRadius:5.0];
    // 设置 是否剪裁
    [view.layer setMasksToBounds:true];

    // 阴影
    // 需要设置view的背景色,否则会失效,UIView默认背景色为clearColor。
    // 剪裁会导致阴影被剪裁掉。
    // 阴影是根据contents内容(没有则是图层边界)绘制
    // 设置 阴影色
    [view.layer setShadowColor:[UIColor blueColor].CGColor];
    // 设置 阴影不透明度(默认0)
    [view.layer setShadowOpacity:1];
    // 设置 阴影偏移(横向,纵向),默认(0,-3)阴影在上
    [view.layer setShadowOffset:CGSizeMake(0, 0)];
    // 设置 阴影模糊度(0时边界明显)
    [view.layer setShadowRadius:10];

    // 边框线 颜色
    [view.layer setBorderColor:[UIColor whiteColor].CGColor];
    // 边框线 宽度(默认0)
    [view.layer setBorderWidth:1.0];
    // 透明度(默认1)  ==UIView的alpha   ,影响子层级
    layer1.opacity=1;
    // 隐藏
    layer1.hidden=true;
    // 即 View的center(0.5*width,0.5*height)
    layer1.position;
    // 通过bounds center transform来确定
    // 注意:当旋转后,值等于把旋转后的VIew全部罩住的虚拟矩形的frame
    layer1.frame;
    // (0,0,原width,原height)
    layer1.bounds;
    // z坐标轴的位置,图层的显示顺序(别太小浮点计算耗时)
    // 只能影响显示的层次,不能改变事件传递的顺序
    layer1.zPosition=1.0;
    // bgColor
    layer1.backgroundColor=[UIColor blueColor].CGColor;

    // 添加删除layer
    [view.layer insertSublayer:layer1 above:layer2];
    [view.layer insertSublayer:layer1 below:layer2];
    [view.layer insertSublayer:layer1 atIndex:0];
    [view.layer addSublayer:layer1];
    [layer1 removeFromSuperlayer];
    // 子layer数组
    NSArray<CALayer *> *subArray=view.layer.sublayers;
    // 父layer
    CALayer *superLayer=view.layer.superlayer;

    // 返回点击中的layer
    CALayer *layer=[layer1 hitTest:CGPointMake(100, 100)];
    // 锚点,默认:(0.5,0.5),可用作旋转时的中心点
    layer1.anchorPoint=CGPointMake(0.1, 0.1);
    // 是否包含此点(通过坐标转换而来的point)
    [layer1 containsPoint:CGPointZero];
    // 是否双面绘制(默认:true)(反转180之后的背面)
    layer1.doubleSided=false;
    
    // 将图层和子图层整合成一张图绘制
    layer1.shouldRasterize=true;
    // 拉伸(前提shouldRasterize为true)
    layer1.rasterizationScale=[UIScreen mainScreen].scale;

坐标转换

    // 坐标转换 将一个点或rect 转换到另一个layer的坐标系下   from则点原是from中的
    [layer1 convertRect:CGRectZero toLayer:layer2];
    [layer1 convertRect:CGRectZero fromLayer:layer2];
    [layer1 convertPoint:CGPointZero toLayer:layer2];
    [layer1 convertPoint:CGPointZero fromLayer:layer2];

contents

    // 设置contents为图片
    [view.layer setContents:[UIImage imageNamed:@"a"].CGImage];
    // img填充格式 (左右正常,上下怪)
    [view.layer setContentsGravity:kCAGravityResize];
    /*
    kCAGravityResizeAspectFill(变换size宽高比例填充,可能超出layer)、kCAGravityResize(变换size不按比例填充,不会超出layer,其他都可能超出,默认)、
     以下模式都会超出(变换size宽高比例填充,可能超出layer)
    kCAGravityTop(底部对齐)、kCAGravityBottom(顶部对齐)、kCAGravityLeft(左边对齐)、kCAGravityRight(右边对齐)、kCAGravityCenter(中心点对齐)、kCAGravityTopLeft(左下角对齐)、kCAGravityBottomLeft(左上角对齐)、kCAGravityTopRight(右下角对齐)、kCAGravityBottomRight(右上角对齐)
     */
    // 默认:1正常屏幕(2则每点2像素,若设置了contentsGravity则无效)
    [view.layer setContentsScale:2];
    
    // 显示裁剪图片: 0~1(此处显示图片左上角)
    view.layer.contentsRect=CGRectMake(0, 0, 0.5, 0.5);
    // 显示拉伸压缩图片  可以将圆形拉伸为圆角矩形(0.5,0.5,0,0)
    view.layer.contentsCenter=CGRectMake(0.5,0.5,0.5,0.5);
  1. layer使用示例

预期效果图(内凹陷+圆角+阴影):


部分代码如下:

    // 添加背景layer
    CAShapeLayer *bgLayer = [CAShapeLayer layer];
    [bgLayer setFillColor:[UIColor whiteColor].CGColor];
    // 设置阴影...
    [bgLayer setPath:({
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(0, 10)];
        [path addArcWithCenter:CGPointMake(10, 10) radius:10 startAngle:M_PI endAngle:M_PI*1.5 clockwise:true];   // 左上角
        // path....
        
        path.CGPath;
    })];
    //
    [contentView.layer insertSublayer:bgLayer atIndex:0];
虚线(自定义UIView,覆写drawRect)

- (void)drawRect:(CGRect)rect {
    //
    CAShapeLayer *dotteShapeLayer = [CAShapeLayer layer];
    CGMutablePathRef dotteShapePath =  CGPathCreateMutable();
    // 设置虚线颜色
    [dotteShapeLayer setStrokeColor:kBackF1Color.CGColor];
    // 1=线的宽度 2=每条线的间距
    NSArray *dotteShapeArr = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:2], nil];
    [dotteShapeLayer setLineDashPattern:dotteShapeArr];
    
    // 50为虚线Y值,和下面的50一起用。
    // kScreenWidth为虚线宽度
    CGPathMoveToPoint(dotteShapePath, NULL, 0 ,0);
    CGPathAddLineToPoint(dotteShapePath, NULL, rect.size.width, rect.size.height);
    [dotteShapeLayer setPath:dotteShapePath];
    CGPathRelease(dotteShapePath);
    
    // 把绘制好的虚线添加上来
    [self.layer addSublayer:dotteShapeLayer];
}
  1. 自定义设置上下左右圆角
    // 圆角自定义切
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.sliderHeadView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight |UIRectCornerBottomRight | UIRectCornerBottomLeft cornerRadii:CGSizeMake(10, 10)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.sliderHeadView.bounds;
    maskLayer.path = maskPath.CGPath;
    view1.layer.mask  = maskLayer;

3. UIControl : UIView

很多可交互的控件都继承了UIControl(UITextField、UIButton、)

UIControl的属性
    enable                              控件是否禁用
    selected                            控件是否被选中
    highlighted                         控件是否高亮
    state                               state(readOnly)
        UIControlStateNormal      
        UIControlStateHighlighted            
        UIControlStateDisabled     
        UIControlStateSelected        
        UIControlStateFocused 
        UIControlStateApplication 
        UIControlStateReserved    
    contentHorizontalAlignment          控件内容 水平方向对齐方式
        UIControlContentHorizontalAlignmentCenter 
        UIControlContentHorizontalAlignmentLeft   
        UIControlContentHorizontalAlignmentRight  
        UIControlContentHorizontalAlignmentFill   
    contentVerticalAlignment            控件内容 垂直方向对齐方式
        UIControlContentVerticalAlignmentCenter 
        UIControlContentVerticalAlignmentTop   
        UIControlContentVerticalAlignmentBottom 
        UIControlContentVerticalAlignmentFill   
UIControl的方法

// 添加/移除 事件监听
- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
- (void)removeTarget:(nullable id)target action:(nullable SEL)action forControlEvents:(UIControlEvents)controlEvents;

controlEvents(控件主要响应的3种事件):
  1.基于触摸的事件
    UIControlEventTouchDown             触摸事件(单点)
    UIControlEventTouchDownRepeat       触摸事件(多点)
    UIControlEventTouchDragInside       在控件内拖动
    UIControlEventTouchDragOutside      在控件外拖动
    UIControlEventTouchDragEnter        由控件外到控件内拖动
    UIControlEventTouchDragExit         由控件内到控件外拖动
    UIControlEventTouchUpInside         点击事件
    UIControlEventTouchUpOutside        件外抬起
    UIControlEventTouchCancel           取消触摸事件
  2.基于值改变的事件
    UIControlEventValueChanged          值改变事件
  3.基于编辑的事件
    UIControlEventEditingDidBegin       开始编辑事件
    UIControlEventEditingChanged        文本内容改变事件(如:UITextField)
    UIControlEventEditingDidEnd         编辑结束事件
    UIControlEventEditingDidOnExit      退出编辑事件
  所有事件
    UIControlEventAlltouchEvents        所有触摸事件
    UIControlEventAllEditingEvents      所有编辑事件
    UIControlEventAllEvents             所有事件

4. UIResponder : NSObject 事件响应基类

UIView、UIViewController、UIApplication、AppDelegate均继承自UIResponder

    // 是否 可以成为/注销第一响应者
    [responder canBecomeFirstResponder];
    [responder canResignFirstResponder];
    // 是否 是第一响应者
    [responder isFirstResponder];
    // 成为/注销 第一响应者(常用于使UITextField获取/失去焦点)
    [responder becomeFirstResponder];
    [responder resignFirstResponder];
    
    // 响应者链中的下一个响应者
    UIResponder *nextResponder=[responder nextResponder];

以下方法(可用在子类中覆写)

触摸

// 开始触摸
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
// 触摸移动后
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
// 触摸结束
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
// 触摸取消
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
按压

// 开始按压
-(void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
// 按压值改变
-(void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
// 按压结束
-(void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
// 按压取消
-(void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
移动

// 开始移动
-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{}
// 结束移动
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{}
// 取消移动
-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{}

5. UIWindow : UIView

didFinishLaunchingWithOptions

// 应用加载完毕后调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // 设置 主窗口
    self.window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    // 设置 主窗口背景色
    [self.window setBackgroundColor:[UIColor whiteColor]];
    // 设置 主窗口可见(必须调用)
    [self.window makeKeyAndVisible];
    // 设置 主窗口根控制器(可通过该方法用于切换两端:用户端/商家端)
    [self.window setRootViewController:[[YTNavController alloc]initWithRootViewController:[YTVoiceViewController new]]];


    // 初始化一些第三方
    [self setupThird];
    
    return YES;
}

UIWindow属性和方法

     // 屏幕。默认是[UIScreen mainScreen],改变会耗内存。
     @property(nonatomic,strong) UIScreen *screen;

     // 显示优先级(默认为0,大在上,相同也在上)
     // 可以自定义值
     // UIWindowLevelNormal 0、UIWindowLevelAlert 2000、UIWindowLevelStatusBar 1000、自定义数字
     @property(nonatomic) UIWindowLevel windowLevel; 

     // 主控制器。改变可以更换根界面。
     @property(nullable, nonatomic,strong) UIViewController *rootViewController;

     // window是否是keyWindow
     @property(nonatomic,readonly,getter=isKeyWindow) BOOL keyWindow;
    // 使window变为keyWindow
    [window makeKeyWindow];

     // 使主窗口可见
     // 不同于View,Window创建后不需要添加到其他View上,需要使用 [myWindow makeKeyAndVisible];
     // 再创建其他窗口,相同的windowLevel,调用makeKeyAndVisible时无效。
     [self.window makeKeyAndVisible];

     // 可查看当前所有windows
     [UIApplication sharedApplication].windows 

     // 分发事件
     [window sendEvent:[UIEvent new]];

    // window间坐标转换
    CGRect rect=[window convertRect:CGRectMake(0, 0, 0, 0) toWindow:window2];
    CGPoint point=[window convertPoint:CGPointMake(0, 0) toWindow:window2];
    CGRect rect=[window convertRect:CGRectMake(0, 0, 0, 0) fromWindow:window2];
    CGPoint point=[window convertPoint:CGPointMake(0, 0) fromWindow:window2];

    // 子类覆写,不能直接调用
    - (void)becomeKeyWindow;
    - (void)resignKeyWindow;

常用(弹窗)

    // 主窗口添加子视图,不建议直接加到keyWindow上,级别太高。
    [[UIApplication sharedApplication].keyWindow addSubview:[UIView new]];

通知

    UIWindowDidBecomeVisibleNotification    // window可见
    UIWindowDidBecomeHiddenNotification     // window隐藏
    UIWindowDidBecomeKeyNotification        // makekey后
    UIWindowDidResignKeyNotification        // resignKey后

6. UIApplication : UIResponder

一个应用对应一个UIApplication。
UIApplication主要负责处理事件队列中的用户事件。

    // 获取 UIApplication(当前应用的单例)
    UIApplication *sharedApplication=[UIApplication sharedApplication];

    // 获取 UIWindow(主窗口,一般情况下:应用只有一个主窗口)
    UIWindow *window=sharedApplication.keyWindow;

    // 获取 AppDelegate
    id<UIApplicationDelegate> dele=sharedApplication.delegate;

    // 应用角标
    [sharedApplication setApplicationIconBadgeNumber:-1]; //  -1角标清0

    // 获取 应用当前状态
    UIApplicationState state=sharedApplication.applicationState;
    /*
     UIApplicationStateActive,      活跃状态(可交互)
     UIApplicationStateInactive,
     UIApplicationStateBackground   后台
     */

    // 获取 应用后台存活时间(只读)
    NSTimeInterval backTime=sharedApplication.backgroundTimeRemaining;
    // 获取 应用后台刷新状态
    UIBackgroundRefreshStatus status=sharedApplication.backgroundRefreshStatus;
    /*
     UIBackgroundRefreshStatusRestricted, //
     UIBackgroundRefreshStatusDenied,     // 不允许刷新
     UIBackgroundRefreshStatusAvailable   // 允许刷新
    */

    // 忽略交互事件
    [sharedApplication beginIgnoringInteractionEvents];
    // 接受交互事件
    [sharedApplication endIgnoringInteractionEvents];

强制不熄屏

不息屏
[[UIApplication sharedApplication] setIdleTimerDisabled:true];
恢复系统息屏(调试运行时一直都不熄屏,测试时点击启动应用)
[[UIApplication sharedApplication] setIdleTimerDisabled:false];

跳转(具体参考iOS之跳转

    // 是否允许打开其他应用
    BOOL isCanOpen=[sharedApplication canOpenURL:[NSURL URLWithString:@""]];
    // 打开其他应用
    [sharedApplication openURL:[NSURL URLWithString:@""]];
    [sharedApplication openURL:[NSURL URLWithString:@""] options:@{} completionHandler:^(BOOL success) {
    }];

状态栏

    状态栏字体颜色(默认:黑色) ,两种: 
            黑色(UIStatusBarStyleDefault,默认),状态栏字体白色
            白色(UIStatusBarStyleLightContent),状态栏字体黑色。

改为白色:

方法一(此方式已过期)    info.plist
    View controller-based status bar appearance     :false // 默认为true
    status bar style               :UIStatusBarStyleLightContent   // 默认为UIStatusBarStyleDefault
    注意:
      1. true  则 [UIApplication sharedApplication].statusBarStyle 无效(preferredStatusBarStyle方法有效,若需要设置个别页的状态栏颜色,则在willAppear willDisAppear中调用即可)
      2. false 则 仅[UIApplication sharedApplication].statusBarStyle 设置有效(preferredStatusBarStyle方法无效)


方法二    preferredStatusBarStyle方法(前提:上述plist使用默认true)
    // 状态栏(如果VC在navC中,则需在navC中添加该方法,否则无效)
    // VC中
    - (UIStatusBarStyle)preferredStatusBarStyle{
        // 状态栏为白色.  UIStatusBarStyleDefault:黑色
        return UIStatusBarStyleLightContent;
    }
    // navC中
    - (UIStatusBarStyle)preferredStatusBarStyle{
        return [self.topViewController preferredStatusBarStyle];
    }

注意:
    // 以下方法会强制调用navC(没有navC 则VC)中的preferredStatusBarStyle。
    [self setNeedsStatusBarAppearanceUpdate];
    // 获取 应用状态栏方向(readOnly)
    UIInterfaceOrientation interfaceOrien=sharedApplication.statusBarOrientation;
    /*
    UIInterfaceOrientationUnknown            = UIDeviceOrientationUnknown,
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,             Home在下
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,   Home在上
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,       Home在
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
    */
    // 获取 应用状态栏动画时间(readOnly)
    NSTimeInterval durTime=sharedApplication.statusBarOrientationAnimationDuration;
    // 获取 应用状态栏frame(readOnly)
    CGRect applicationFrame=sharedApplication.statusBarFrame;


    // 设置 是否显示网络加载圈(状态栏中)
    [sharedApplication setNetworkActivityIndicatorVisible:true];


    // 隐藏状态栏(此方式已过期)
    sharedApplication.statusBarHidden=true;
    [sharedApplication setStatusBarHidden:true withAnimation:UIStatusBarAnimationFade];

通知

  应用进入后台后
    UIApplicationDidEnterBackgroundNotification
  应用即将进入前台时
    UIApplicationWillEnterForegroundNotification
  应用加载完毕后
    UIApplicationDidFinishLaunchingNotification
  应用允许交互后
    UIApplicationDidBecomeActiveNotification
  应用即将不允许交互时
    UIApplicationWillResignActiveNotification
  应用收到内存紧张警告时
    UIApplicationDidReceiveMemoryWarningNotification
  应用即将销毁时
    UIApplicationWillTerminateNotification;
  应用后台刷新状态改变
    UIApplicationBackgroundRefreshStatusDidChangeNotification
  应用?
    UIApplicationSignificantTimeChangeNotification;


  应用状态栏方向即将改变时
    UIApplicationWillChangeStatusBarOrientationNotification 
  应用状态栏方向改变后
    UIApplicationDidChangeStatusBarOrientationNotification 
  应用状态栏即将改变frame
    UIApplicationWillChangeStatusBarFrameNotification 
  应用状态栏改变frame后
    UIApplicationDidChangeStatusBarFrameNotification

7. UIScreen : NSObject

    // 获取 屏幕
    UIScreen *mainScreen=[UIScreen mainScreen];
    // 获取 屏幕大小
    CGRect rect=mainScreen.bounds;

8. UIDevice : NSObject

    // 获取 当前设备
    UIDevice *currentDevice=[UIDevice currentDevice];

    // 获取 设备昵称
    NSString *deviceName=currentDevice.name;
    // 获取 设备机型 (iPhone / iPod touch / iPad)
    NSString *deviceModel=currentDevice.model;
    // 获取 设备机型
    NSString *deviceLModel=currentDevice.localizedModel;
    // 获取 设备系统
    NSString *deviceSysName=currentDevice.systemName;
    // 获取 设备系统版本
    NSString *deviceSysVersion=currentDevice.systemVersion;

    // 获取 设备方向
    UIDeviceOrientation deviceOrientation=currentDevice.orientation;
    /*
     UIDeviceOrientationUnknown,
     UIDeviceOrientationPortrait,            // Home键在下
     UIDeviceOrientationPortraitUpsideDown,  // Home键在上
     UIDeviceOrientationLandscapeLeft,       // Home键在左
     UIDeviceOrientationLandscapeRight,      // Home键在右
     UIDeviceOrientationFaceUp,              // 水平放置,正面朝上
     UIDeviceOrientationFaceDown             // 水平放置,正面朝下
     */

电池

    // 是否监测电池
    BOOL battoryMonitor=currentDevice.batteryMonitoringEnabled;

    // 获取电池电量
    float deviceBattoryLevel=currentDevice.batteryLevel;

    // 获取电池状态
    UIDeviceBatteryState state=currentDevice.batteryState;
    /*
     UIDeviceBatteryStateUnknown,
     UIDeviceBatteryStateUnplugged,   // 耗电中
     UIDeviceBatteryStateCharging,    // 充电中 小于100%
     UIDeviceBatteryStateFull,        // 充电中 等于100%
     */

旋转

    // 获取 设备旋转时是否发送通知
    BOOL isRoteNoti=currentDevice.generatesDeviceOrientationNotifications;
    // 允许设备旋转时发送通知
    [currentDevice beginGeneratingDeviceOrientationNotifications];
    // 不允许设备旋转时发送通知
    [currentDevice endGeneratingDeviceOrientationNotifications];

    UIUserInterfaceIdiom interFace=currentDevice.userInterfaceIdiom;

近距离

    // 获取 设备近距离靠近时是否发送通知(例:用于通话时,放在耳朵旁界面变暗)
    BOOL isProximityMonitor=currentDevice.proximityMonitoringEnabled;
    // 获取 是否近距离靠近
    BOOL isPro=currentDevice.proximityState;

// 通知
[[UIDevice currentDevice] setProximityMonitoringEnabled:YES];[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(sensorStateChange:)name:@"UIDeviceProximityStateDidChangeNotification"object:nil];
-(void)sensorStateChange:(NSNotificationCenter *)notification{
    if ([[UIDevice currentDevice] proximityState] == YES) {
        NSLog(@"屏幕熄灭");
    }else{
        NSLog(@"屏幕亮起");
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352