はじめに
非公開のクラスやプロパティにアクセスしているので審査に通るのかは不明です
(自分は試したことないです)
今後OSのアップデートによって使えなくなる可能性もあります
また、今回紹介するものは、簡単に利用できるようにこちらにライブラリとしてまとめてるので是非使ってください。
https://github.com/p-x9/NotchCorners
本編
準備
statusBarManagerからプロパティを辿っていく形で取得するので、まずUIApplicationの拡張を書きます。
KVCを利用するので、安全のためresponds(to:)
でメソッドが存在するかの確認を行なっています
(ディスプレイの角の半径(Display Corner Radius)を取得するだけの場合は必要ありません)
extension UIApplication {
var statusBarProviderClassName: String? {
// KeyWindowを取得
let window = self.windows.first {
$0.isKeyWindow
}
guard let keyWindow = window,
let windowScene = keyWindow.windowScene,
let statusBarManager = windowScene.statusBarManager else {
return nil
}
// _UIStatusBarLocalView
guard statusBarManager.responds(to: Selector(("createLocalStatusBar"))),
let statusBarLocalView = statusBarManager.perform(Selector(("createLocalStatusBar"))).takeUnretainedValue() as? UIView else {
return nil
}
// UIStatusBar
guard statusBarLocalView.responds(to: Selector(("statusBar"))),
let statusBar = statusBarLocalView.perform(Selector(("statusBar"))).takeUnretainedValue() as? UIView else {
return nil
}
// _UIStatusBar
guard statusBar.responds(to: Selector(("statusBar"))),
let _statusBar = statusBar.perform(Selector(("statusBar"))).takeUnretainedValue() as? UIView else {
return nil
}
// Get _UIStatusVisualProvider_iOS
if _statusBar.responds(to: Selector(("_visualProviderClassName"))) {
return _statusBar.value(forKey: "_visualProviderClassName") as? String
}
return nil
}
}
これを利用してNotchの各種プロパティを取得していきます。
Notch Size
let notchSizeKey = "notchSize"
public var notchSize: CGSize {
guard let className = UIApplication.shared.statusBarProviderClassName,
let providerClass = NSClassFromString(className),
providerClass.responds(to: Selector(notchSizeKey)) else {
return .zero
}
return providerClass.value(forKey: notchSizeKey) as! CGSize
}
Notch Top Radius
let notchTopCornerRadiusKey = "notchTopCornerRadius"
public var notchTopCornerRadius: CGFloat {
guard let className = UIApplication.shared.statusBarProviderClassName,
let providerClass = NSClassFromString(className) as? NSObject.Type,
providerClass.responds(to: Selector(notchTopCornerRadiusKey)),
let notchTopCornerRadius = providerClass.value(forKey: notchTopCornerRadiusKey) as? CGFloat else {
return 0
}
return notchTopCornerRadius
}
Notch Bottom Radius
let notchBottomCornerRadiusKey = "notchBottomCornerRadius"
public var notchBottomCornerRadius: CGFloat {
guard let className = UIApplication.shared.statusBarProviderClassName,
let providerClass = NSClassFromString(className) as? NSObject.Type,
providerClass.responds(to: Selector(notchBottomCornerRadiusKey)),
let notchBottomCornerRadius = providerClass.value(forKey: notchBottomCornerRadiusKey) as? CGFloat else {
return 0
}
return notchBottomCornerRadius
}
Display Corner Radius
let displayCornerRadiusKey = "_displayCornerRadius"
public var displayCornerRadius: CGFloat {
guard let cornerRadius = self.value(forKey: displayCornerRadiusKey) as? CGFloat else {
return 0
}
return cornerRadius
}
終わりに
今回取得したNotchのプロパティを使ってこんなのも作ってみました
もしこれを使ってAppStoreの審査に通ったら教えてほしいです
ありがとうございました。