这可能是一个简单的问题,但由于我是初学者,最好问一下。
正如标题所说,我应该使用什么来代替UIScreen.mainScreen().applicationFrame
,因为它在9.0中已被弃用。
如果可能的话,如果你能给我一个样本或例子就太好了,因为我觉得苹果的文档很难。
目前我使用以下代码,但我希望将其更改为新版本。我很想听听你的消息!
let sizeRect = UIScreen.mainScreen().applicationFrame
let posX = arc4random_uniform(UInt32(sizeRect.size.width))
let posY = arc4random_uniform(UInt32(sizeRect.size.height))
Enemy.position = CGPoint(x: CGFloat(posX), y: CGFloat(posY))
使用
let rect1 = UIScreen.mainScreen().bounds // Returns CGRect
let rect2 = UIScreen.mainScreen().bounds.size // Returns CGSize
Swift 3+:
let rect1 = UIScreen.main.bounds // Returns CGRect
let rect2 = UIScreen.main.bounds.size // Returns CGSize
我知道UIScreen.mainScreen().bounds
是推荐的替代方案;然而,它并不完全等同于UIScreen.mainScreen().applicationFrame
,尤其是当您的应用程序没有占据整个屏幕时,某些iPad上的"拆分视图"one_answers"滑盖"功能会出现这种情况。
在这种情况下,这是一个很好的选择:UIApplication.sharedApplication.keyWindow.frame
。(当然keyWindow
必须可用,也就是说,您确实调用了makeKeyAndVisible
)
从swift 3开始,您现在需要这样使用它。
let SCREEN_WIDTH = UIScreen.main.bounds.size.width
let SCREEN_HEIGHT = UIScreen.main.bounds.size.height
用于:
let width = UIScreen.mainScreen().bounds.width
和:
let height = UIScreen.mainScreen().bounds.height
不幸的是,UIScreen.main
和UIScreen.mainScreen()
自iOS 16以来都已弃用。
苹果公司不鼓励使用这个符号。请改用通过上下文找到的UIScreen实例。例如,通过管理包含视图的窗口的窗口场景上的screen属性,引用显示视图的屏幕。
和往常一样,苹果文档非常善于告诉你不该做什么,但很少给你该做什么的例子。因此,经过一些搜索和测试,我想出了自己的解决方案。
我创建了一个带有静态函数的助手类,使我可以访问当前场景以及窗口和屏幕。
此解决方案仅适用于iOS等单窗口应用程序,并且需要为iPad和macOS应用程序做一些额外的工作。
我的解决方案是从这个线程中的响应组合中派生出来的。两个答案都会在主应用程序条目中创建一个UIWindow?
变量。
第一次响应
@main
struct DemoApp: App {
var window: UIWindow? {
guard let scene = UIApplication.shared.connectedScenes.first,
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
let window = windowSceneDelegate.window else {
return nil
}
return window
}
[...]
}
第二次响应
@main
struct TestApp: App {
var window: UIWindow? {
guard let scene = UIApplication.shared.connectedScenes.first,
let windowScene = scene as? UIWindowScene else {
return nil
}
return .init(windowScene: windowScene)
}
}
我不赞成第二个响应,因为它从UIWindowScene
创建了一个新的UIWindow
。您可以从UIWindowScene
访问一组窗口。
我对这个解决方案的第一次尝试是创建一个助手和方便函数,然后用方便函数将它们公开到View
上。
助手
struct Application {
public static var scene: UIScene? {
guard let scene = UIApplication.shared.connectedScenes.first else {
return nil
}
return scene
}
public static var window: UIWindow? {
guard let scene = self.scene,
let delegate = scene.delegate as? UIWindowSceneDelegate,
let window = delegate.window else {
return nil
}
return window
}
public static var screen: UIScreen? {
guard let window = self.window else {
return nil
}
return window.screen
}
}
我选择从代表访问UIScene
,而不是将UIScene
强制转换为UIWindowScene
,因为根据苹果针对UIScene
的文档,它是:
表示应用程序用户界面的一个实例的对象。
阅读苹果公司UIWindowScene
的文档让我相信,通过代表获得它是更可靠的方式。我很好奇在info.plist中使用UISceneConfiguration
条目是否更好?
扩展
extension View {
var scene: UIScene? {
return Application.scene
}
var window: UIWindow? {
return Application.window
}
var screen: UIScreen? {
return Application.screen
}
}
我不是一个经验丰富的Swift开发人员,所以我相信有更好的解决方案。我想知道还有什么更好的解决方案?UIScreen.main
似乎是一个非常常见的对象——如果能为它的使用建立一个新的模式,那就太好了。
Swift 3+:
let width = UIScreen.main.bounds.width
let height = UIScreen.main.bounds.height