1 // Copyright 2022-present 650 Industries. All rights reserved. 2 3 /** 4 Since iOS 11, launching ImagePicker with `allowsEditing` option makes cropping rectangle 5 slightly moved upwards, because of StatusBar visibility. 6 Hiding StatusBar during picking process solves the displacement issue. 7 See https://forums.developer.apple.com/thread/98274 8 */ 9 internal class StatusBarVisibilityController { 10 private var shouldRestoreStatusBarVisibility = false 11 12 func maybePreserveVisibilityAndHideStatusBar(_ shouldHideStatusBar: Bool) { 13 guard shouldHideStatusBar && !UIApplication.shared.isStatusBarHidden else { 14 return 15 } 16 17 shouldRestoreStatusBarVisibility = true 18 setStatusBarHidden(true) 19 } 20 21 func maybeRestoreStatusBarVisibility() { 22 guard shouldRestoreStatusBarVisibility else { 23 return 24 } 25 26 shouldRestoreStatusBarVisibility = false 27 setStatusBarHidden(false) 28 } 29 30 /** 31 Calling -[UIApplication setStatusBarHidden:withAnimation:] triggers a warning 32 that should be suppressable with -Wdeprecated-declarations, but is not. 33 The warning suggests to use -[UIViewController prefersStatusBarHidden]. 34 Unfortunately until we stop presenting view controllers on detached VCs 35 the setting doesn't have any effect and we need to set status bar like that. 36 */ 37 private func setStatusBarHidden(_ hidden: Bool) { 38 let selector = NSSelectorFromString("setStatusBarHidden:withAnimation:") 39 UIApplication.shared.perform(selector, with: hidden, with: false) 40 41 // TODO: (@bbarthec) below is possible alternative 42 // let obj = X() 43 // let sel = #selector(obj.sayHiTo) 44 // let meth = class_getInstanceMethod(object_getClass(obj), sel) 45 // let imp = method_getImplementation(meth) 46 // 47 // typealias ClosureType = @convention(c) (AnyObject, Selector, String) -> Void 48 // let sayHiTo : ClosureType = unsafeBitCast(imp, ClosureType.self) 49 // sayHiTo(obj, sel, "Fabio") 50 // prints "Hello Fabio!" 51 } 52 } 53