Ios 在横向模式下,iPad mini上的UIWindow出现了奇怪的问题
我已经创建了一条自定义的toast消息,并将此消息添加到自定义的Ios 在横向模式下,iPad mini上的UIWindow出现了奇怪的问题,ios,swift,ipad,orientation,uiwindow,Ios,Swift,Ipad,Orientation,Uiwindow,我已经创建了一条自定义的toast消息,并将此消息添加到自定义的ui窗口(因为我希望此消息位于所有内容之上)。 我的自定义toast消息只不过是UIViewController的子类和UIViewController的子类。我添加了一个UILabel作为toast消息 就定制的ui窗口而言,我从jltoos中获取了这个类,它看起来就是这样的 public class JLToastWindow: UIWindow { public static let sharedWindow = J
ui窗口
(因为我希望此消息位于所有内容之上)。
我的自定义toast消息只不过是UIViewController
的子类和UIViewController
的子类。我添加了一个UILabel
作为toast消息
就定制的ui窗口
而言,我从jltoos
中获取了这个类,它看起来就是这样的
public class JLToastWindow: UIWindow {
public static let sharedWindow = JLToastWindow(frame: UIScreen.mainScreen().bounds)
/// Will not return `rootViewController` while this value is `true`. Or the rotation will be fucked in iOS 9.
var isStatusBarOrientationChanging = false
var shouldRotateManually: Bool {
let iPad = UIDevice.currentDevice().userInterfaceIdiom == .Pad
let application = UIApplication.sharedApplication()
let window = application.delegate?.window ?? nil
let supportsAllOrientations = application.supportedInterfaceOrientationsForWindow(window) == .All
let info = NSBundle.mainBundle().infoDictionary
let requiresFullScreen = info?["UIRequiresFullScreen"]?.boolValue == true
let hasLaunchStoryboard = info?["UILaunchStoryboardName"] != nil
if #available(iOS 9, *), iPad && supportsAllOrientations && !requiresFullScreen && hasLaunchStoryboard {
return false
}
return true
}
override public var rootViewController: UIViewController? {
get {
guard !self.isStatusBarOrientationChanging else { return nil }
return UIApplication.sharedApplication().windows.first?.rootViewController
}
set { /* Do nothing */ }
}
public override init(frame: CGRect) {
super.init(frame: frame)
self.userInteractionEnabled = false
self.windowLevel = CGFloat.max
self.backgroundColor = .clearColor()
self.hidden = false
self.handleRotate(UIApplication.sharedApplication().statusBarOrientation)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(self.bringWindowToTop),
name: UIWindowDidBecomeVisibleNotification,
object: nil
)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(self.statusBarOrientationWillChange),
name: UIApplicationWillChangeStatusBarOrientationNotification,
object: nil
)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(self.statusBarOrientationDidChange),
name: UIApplicationDidChangeStatusBarOrientationNotification,
object: nil
)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(self.applicationDidBecomeActive),
name: UIApplicationDidBecomeActiveNotification,
object: nil
)
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/// Bring JLToastWindow to top when another window is being shown.
func bringWindowToTop(notification: NSNotification) {
if !(notification.object is JLToastWindow) {
self.dynamicType.sharedWindow.hidden = true
self.dynamicType.sharedWindow.hidden = false
}
}
dynamic func statusBarOrientationWillChange() {
self.isStatusBarOrientationChanging = true
}
dynamic func statusBarOrientationDidChange() {
let orientation = UIApplication.sharedApplication().statusBarOrientation
self.handleRotate(orientation)
self.isStatusBarOrientationChanging = false
}
func applicationDidBecomeActive() {
let orientation = UIApplication.sharedApplication().statusBarOrientation
self.handleRotate(orientation)
}
func handleRotate(orientation: UIInterfaceOrientation) {
let angle = self.angleForOrientation(orientation)
if self.shouldRotateManually {
self.transform = CGAffineTransformMakeRotation(CGFloat(angle))
}
if let window = UIApplication.sharedApplication().windows.first {
if orientation.isPortrait || !self.shouldRotateManually {
self.frame.size.width = window.bounds.size.width
self.frame.size.height = window.bounds.size.height
} else {
self.frame.size.width = window.bounds.size.height
self.frame.size.height = window.bounds.size.width
}
}
self.frame.origin = .zero
dispatch_async(dispatch_get_main_queue()) {
JLToastCenter.defaultCenter().currentToast?.view.updateView()
}
}
func angleForOrientation(orientation: UIInterfaceOrientation) -> Double {
switch orientation {
case .LandscapeLeft: return -M_PI_2
case .LandscapeRight: return M_PI_2
case .PortraitUpsideDown: return M_PI
default: return 0
}
}
}
我知道,UIWindow
在ios8中有一些实现更改,因此如果我向UIWindow
添加一些视图(我正在做的就是,向上面的自定义UIWindow
添加toast消息视图),那么UIView/UIWindow
将不会收到任何旋转更改。由于JLToast buddy,此问题由上面的窗口处理。
我的toast消息在几乎所有设备上都运行良好,但问题在于iPad mini 9.3.1和iPad 3 8.3(在rest设备和版本中,这很好)UIWindow/UIView在使用横向
启动应用程序或将设备移动到横向
时没有旋转有趣的是,在iPad mini 9.2上显示良好,但在iPad mini 9.3.1上显示不好
任何人都可以为这个问题提供一些指针
编辑:请查找演示
正如我已经提到的,根据我的发现,这个问题可以在iPadMiniIOS9.3.1(非视网膜)和iPad3IOS8.3上找到