Merge branch 'develop' into steve/lls_design_review

This commit is contained in:
SBiOSoftWhare 2022-07-07 10:27:18 +02:00
commit df3196e0fc
3 changed files with 27 additions and 96 deletions

View file

@ -40,25 +40,20 @@ class VectorHostingController: UIHostingController<AnyView> {
var enableNavigationBarScrollEdgeAppearance = false
/// When non-nil, the style will be applied to the status bar.
var statusBarStyle: UIStatusBarStyle?
/// Whether to force-set the hosting view's safe area insets to zero. Useful when the view is used as part of a table view.
var forceZeroSafeAreaInsets: Bool {
get {
self.view.forceZeroSafeAreaInsets
}
set {
self.view.forceZeroSafeAreaInsets = newValue
}
}
private let forceZeroSafeAreaInsets: Bool
override var preferredStatusBarStyle: UIStatusBarStyle {
statusBarStyle ?? super.preferredStatusBarStyle
}
init<Content>(rootView: Content) where Content: View {
/// Initializer
/// - Parameter rootView: Root view for the controller.
/// - Parameter forceZeroSafeAreaInsets: Whether to force-set the hosting view's safe area insets to zero. Useful when the view is used as part of a table view.
init<Content>(rootView: Content,
forceZeroSafeAreaInsets: Bool = false) where Content: View {
self.theme = ThemeService.shared().theme
self.forceZeroSafeAreaInsets = forceZeroSafeAreaInsets
super.init(rootView: AnyView(rootView.vectorContent()))
self.view.swizzleSafeAreaMethodsIfNeeded()
}
required init?(coder aDecoder: NSCoder) {
@ -106,6 +101,22 @@ class VectorHostingController: UIHostingController<AnyView> {
self.view.invalidateIntrinsicContentSize()
}
}
override func viewSafeAreaInsetsDidChange() {
super.viewSafeAreaInsetsDidChange()
guard forceZeroSafeAreaInsets else {
return
}
let counterSafeAreaInsets = UIEdgeInsets(top: -view.safeAreaInsets.top,
left: -view.safeAreaInsets.left,
bottom: -view.safeAreaInsets.bottom,
right: -view.safeAreaInsets.right)
if additionalSafeAreaInsets != counterSafeAreaInsets, counterSafeAreaInsets != .zero {
additionalSafeAreaInsets = counterSafeAreaInsets
}
}
private func registerThemeServiceDidChangeThemeNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
@ -121,83 +132,3 @@ class VectorHostingController: UIHostingController<AnyView> {
}
}
}
// Hack for forcing zero safe area insets on hosting views. This problem occurs when the hosting view is embedded
// in a table view. See https://stackoverflow.com/questions/61552497 for further info.
private var hasSwizzledSafeAreaMethods = false
private var forceZeroSafeAreaInsetsKey: Void?
private extension UIView {
var forceZeroSafeAreaInsets: Bool {
get {
return objc_getAssociatedObject(self, &forceZeroSafeAreaInsetsKey) as? Bool == true
}
set {
objc_setAssociatedObject(self, &forceZeroSafeAreaInsetsKey, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
@objc private var _safeAreaInsets: UIEdgeInsets {
return forceZeroSafeAreaInsets ? .zero : self._safeAreaInsets
}
@objc private var _safeAreaLayoutGuide: UILayoutGuide? {
return forceZeroSafeAreaInsets ? nil : self._safeAreaLayoutGuide
}
func swizzleSafeAreaMethodsIfNeeded() {
guard !hasSwizzledSafeAreaMethods else {
return
}
hasSwizzledSafeAreaMethods = true
guard let getSafeAreaInsets = class_getInstanceMethod(classForCoder.self, #selector(getter: UIView.safeAreaInsets)) else {
return
}
guard let _getSafeAreaInsets = class_getInstanceMethod(classForCoder.self, #selector(getter: UIView._safeAreaInsets)) else {
return
}
let getSafeAreaInsetsImplementation = method_getImplementation(getSafeAreaInsets)
let _getSafeAreaInsetsImplementation = method_getImplementation(_getSafeAreaInsets)
class_replaceMethod(
classForCoder,
#selector(getter: UIView.safeAreaInsets),
_getSafeAreaInsetsImplementation,
method_getTypeEncoding(getSafeAreaInsets))
class_replaceMethod(
classForCoder,
#selector(getter: UIView._safeAreaInsets),
getSafeAreaInsetsImplementation,
method_getTypeEncoding(_getSafeAreaInsets))
guard let getSafeAreaLayoutGuide = class_getInstanceMethod(classForCoder.self, #selector(getter: UIView.safeAreaLayoutGuide)) else {
return
}
guard let _getSafeAreaLayoutGuide = class_getInstanceMethod(classForCoder.self, #selector(getter: UIView._safeAreaLayoutGuide)) else {
return
}
let getSafeAreaLayoutGuideImplementation = method_getImplementation(getSafeAreaLayoutGuide)
let _getSafeAreaLayoutGuideImplementation = method_getImplementation(_getSafeAreaLayoutGuide)
class_replaceMethod(
classForCoder,
#selector(getter: UIView.safeAreaLayoutGuide),
_getSafeAreaLayoutGuideImplementation,
method_getTypeEncoding(getSafeAreaLayoutGuide))
class_replaceMethod(
classForCoder,
#selector(getter: UIView._safeAreaLayoutGuide),
getSafeAreaLayoutGuideImplementation,
method_getTypeEncoding(_getSafeAreaLayoutGuide))
}
}

View file

@ -86,9 +86,8 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
}
func toPresentable() -> UIViewController {
let controller = VectorHostingController(rootView: TimelinePollView(viewModel: viewModel.context))
controller.forceZeroSafeAreaInsets = true
return controller
return VectorHostingController(rootView: TimelinePollView(viewModel: viewModel.context),
forceZeroSafeAreaInsets: true)
}
func canEndPoll() -> Bool {

View file

@ -0,0 +1 @@
VectorHostingController: Fix infinite loop due to the safe area insets fix.