iOS开发之通知机制——UIDevice通知、键盘通知

本文介绍了iOS开发中UIDevice类提供的设备通知,包括设备旋转、电池状态及电量变化等,以及如何监听键盘状态变化,如键盘显示、隐藏及其位置尺寸的变化。

一 、UIDevice通知
UIDevice类提供了一个单例对象,它代表着设备,通过它可以获得一些设备相关的信息,比如电池电量值(batteryLevel)、电池状态(batteryState)、设备的类型(model,比如iPod、iPhone等)、设备的系统(systemVersion)等

  • 获取对象
UIDevice *device = [UIDevice currentDevice];
  • UIDevice对象会不间断地发布一些通知,下列是UIDevice对象所发布通知的名称常量:
UIDeviceOrientationDidChangeNotification    // 设备旋转
UIDeviceBatteryStateDidChangeNotification   // 电池状态改变
UIDeviceBatteryLevelDidChangeNotification   // 电池电量改变
UIDeviceProximityStateDidChangeNotification // 近距离传感器(比如设备贴近了使用者的脸部)

二 、 键盘通知

我们经常需要在键盘弹出或者隐藏的时候做一些特定的操作,因此需要监听键盘的状态

键盘状态改变的时候,系统会发出一些特定的通知,常见通知如下:

UIKeyboardWillShowNotification        // 键盘即将显示
UIKeyboardDidShowNotification         // 键盘显示完毕
UIKeyboardWillHideNotification        // 键盘即将隐藏
UIKeyboardDidHideNotification         // 键盘隐藏完毕
UIKeyboardWillChangeFrameNotification // 键盘的位置尺寸即将发生改变
UIKeyboardDidChangeFrameNotification  // 键盘的位置尺寸改变完毕

系统发出键盘通知时,会附带一下跟键盘有关的额外信息(字典),字典常见的key如下:

UIKeyboardFrameBeginUserInfoKey        // 键盘刚开始的frame
UIKeyboardFrameEndUserInfoKey          // 键盘最终的frame(动画执行完毕后)
UIKeyboardAnimationDurationUserInfoKey // 键盘动画的时间
UIKeyboardAnimationCurveUserInfoKey    // 键盘动画的执行节奏(快慢)
<think>嗯,用户遇到了iOS开发中屏幕旋转通知失效的问题,特别是UIDeviceOrientationDidChangeNotification没有触发的情况。我需要先理解这个问题可能的原因,然后找出解决方案。 首先,屏幕旋转通知失效可能有几个原因。比如,用户可能没有启用设备方向通知,或者设备方向监控被关闭了。另外,iOS系统版本的不同也可能影响通知的行为,尤其是在iOS 8之后,苹果对旋转机制做了一些调整。还有可能是在某些视图控制器中,旋转被强制锁定,导致通知无法触发。 接下来,我需要回忆相关的知识点。记得UIDeviceOrientationDidChangeNotification是当设备的物理方向改变时发出的通知,但有时候应用内部的界面方向(UIInterfaceOrientation)和设备方向可能不一致。例如,如果应用只支持竖屏,即使设备旋转,界面也不会变,这时候通知可能不会触发。 然后,查看用户提供的引用内容,引用[1]提到了监听UIApplicationDidChangeStatusBarOrientationNotification,这可能是一个替代方案。因为当状态栏方向改变时,这个通知会被触发,而状态栏方向通常和界面方向一致。所以,如果设备方向通知失效,改用状态栏方向的通知可能更可靠。 引用[4]中提到了屏幕旋转的原理和代码示例,包括设置视图控制器的旋转属性和传递子控制器的属性。这可能涉及到视图控制器是否支持旋转方向,以及如何正确配置supportedInterfaceOrientationsForWindow方法。如果应用支持的方向被限制,可能会导致设备方向改变但通知不触发。 引用[5]提到了状态栏相关的设置,比如View controller-based status bar appearance必须为YES,这可能影响到状态栏方向的变化,进而影响通知的触发。如果这个设置不正确,可能导致状态栏方向不更新,从而相关的通知也不会触发。 综合这些信息,解决方案应该包括几个步骤:首先,检查是否启用了设备方向通知,调用beginGeneratingDeviceOrientationNotifications。其次,考虑使用状态栏方向变化的通知作为替代。然后,确保应用的支持方向设置正确,特别是supportedInterfaceOrientationsForWindow方法的实现。此外,还要检查视图控制器的旋转属性是否被正确覆盖,比如shouldAutorotate和supportedInterfaceOrientations。 可能还需要处理iOS版本差异,比如在iOS 8之后,设备方向通知的行为可能有所变化,需要调整监听方式。另外,模拟器上的测试可能有不同的行为,需要在真机上验证。 最后,用户可能需要示例代码来演示如何正确设置这些通知和配置,比如如何启用设备方向通知,如何监听状态栏方向变化,以及如何配置AppDelegate和视图控制器的方法。同时,要提醒用户注意版本适配和测试环境的问题。</think>### iOS屏幕旋转通知失效的解决方案 #### 核心问题定位 1. **UIDevice方向监控未启用** 需调用`beginGeneratingDeviceOrientationNotifications`启动设备方向监控[^1] 2. **系统机制变更** iOS 8+ 后界面方向与设备方向解耦,建议改用`UIApplicationDidChangeStatusBarOrientationNotification`[^1][^4] 3. **视图控制器旋转锁定** 需检查`supportedInterfaceOrientationsForWindow`方法返回值是否包含目标方向[^3] #### 分步解决方案 **步骤1:启用设备方向监控** ```objective-c // App启动时调用 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; ``` **步骤2:双通知监听组合** ```objective-c // 设备物理方向监听(需启用监控) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil]; // 界面方向监听(推荐主用) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationDidChange) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; ``` **步骤3:配置方向支持** ```objective-c // AppDelegate.m - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskAllButUpsideDown; // 按需调整支持方向[^4] } ``` **步骤4:视图控制器重写方法** ```objective-c // ViewController.m - (BOOL)shouldAutorotate { return YES; // 开启自动旋转 } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAllButUpsideDown; // 与控制权设置一致 } ``` #### 关键注意事项 1. **状态栏配置验证** 确保Info.plist中`View controller-based status bar appearance`设为YES[^5] 2. **方向强制设置方法** (仅非ARC环境可用) ```objective-c if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) { [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:@(UIInterfaceOrientationLandscapeRight)]; }[^2] ``` 3. **模态窗口处理** iOS13+建议设置`modalPresentationStyle = UIModalPresentationOverFullScreen`保证旋转正常 #### 调试建议 - 在`viewWillAppear`中强制横屏,`viewWillDisappear`恢复竖屏 - 使用Xcode的**View Debugging**工具验证实际界面方向 - 真机测试时禁用方向锁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值