Last active
August 14, 2021 09:02
-
-
Save cozzin/b55ec5a894ad8e7a1a5f8e08fecfc19a to your computer and use it in GitHub Desktop.
UIHostingCell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@available(iOS 13.0, *) | |
final class FixedSafeAreaInsetsHostingViewController<Content: SwiftUI.View>: UIHostingController<Content> { | |
override var prefersStatusBarHidden: Bool { | |
return false | |
} | |
override init(rootView: Content) { | |
super.init(rootView: rootView) | |
UIView.classInit | |
} | |
@objc required dynamic init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
} | |
extension UIView { | |
fileprivate static let classInit: Void = { | |
guard let originalSafeAreaInsets = class_getInstanceMethod(UIView.self, #selector(getter: UIView.safeAreaInsets)), | |
let fixedSafeAreaInsets = class_getInstanceMethod(UIView.self, #selector(fix_safeAreaInsets)) else { | |
return | |
} | |
guard let originalSafeAreaLayoutGuide = class_getInstanceMethod(UIView.self, #selector(getter: UIView.safeAreaLayoutGuide)), | |
let fixedSafeAreaLayoutGuide = class_getInstanceMethod(UIView.self, #selector(fix_safeAreaLayoutGuide)) else { | |
return | |
} | |
method_exchangeImplementations(originalSafeAreaInsets, fixedSafeAreaInsets) | |
method_exchangeImplementations(originalSafeAreaLayoutGuide, fixedSafeAreaLayoutGuide) | |
}() | |
private var isHostingView: Bool { | |
// _TtGC7SwiftUI14_UIHostingViewGSqV3Edu15PageWordRowItem__ | |
let className = NSStringFromClass(classForCoder) | |
return className.contains("SwiftUI") && className.contains("_UIHostingView") | |
} | |
private var isNeedFixSafeArea: Bool { | |
guard let next = next, NSStringFromClass(next.classForCoder).contains("FixedSafeAreaInsetsHostingViewController") else { | |
return false | |
} | |
return isHostingView | |
} | |
@objc private func fix_safeAreaInsets() -> UIEdgeInsets { | |
isNeedFixSafeArea ? .zero : fix_safeAreaInsets() | |
} | |
@objc private func fix_safeAreaLayoutGuide() -> UILayoutGuide? { | |
isNeedFixSafeArea ? nil : fix_safeAreaLayoutGuide() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import SwiftUI | |
@available(iOS 14.0, *) | |
public final class UIHostingCell<Content>: UITableViewCell where Content: View { | |
private let hostingController = UIHostingController<Content?>(rootView: nil) | |
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { | |
super.init(style: style, reuseIdentifier: reuseIdentifier) | |
hostingController.view.translatesAutoresizingMaskIntoConstraints = false | |
contentView.addSubview(hostingController.view) | |
hostingController.view.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true | |
hostingController.view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true | |
hostingController.view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true | |
hostingController.view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
public override func prepareForReuse() { | |
super.prepareForReuse() | |
hostingController.rootView = nil | |
} | |
public func configure(with view: Content) { | |
hostingController.rootView = view | |
setNeedsLayout() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import SwiftUI | |
@available(iOS 14.0, *) | |
public final class UIHostingCell<Content>: UITableViewCell where Content: View { | |
// ...생략... | |
public override func prepareForReuse() { | |
super.prepareForReuse() | |
hostingController.willMove(toParent: nil) | |
hostingController.rootView = nil | |
hostingController.removeFromParent() | |
} | |
public func configure(view: Content, parent: UIViewController?) { | |
parent?.addChild(hostingController) | |
hostingController.rootView = view | |
hostingController.view.invalidateIntrinsicContentSize() | |
hostingController.didMove(toParent: parent) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment