str*_*mes 6 uitableview swift uitableviewsectionheader swiftui
UITableView
我已经掌握了一些细胞的基础知识。我使用 SwiftUIView
作为单元格和节标题的内容。奇怪的是,只有 iPhone XS Max 上似乎接触屏幕底部的部分标题似乎获得了rawSafeAreaInset
16 分(检查了“调试视图层次结构”)。我的细胞正在按预期工作。
为了看看发生了什么,我在 中添加了一个虚拟的蓝色 SwiftUI 矩形contentView
,然后在顶部放置了一个红色 UIView,两个视图都设置为相同的约束。已UITableView
设置为对标题和单元格使用自动尺寸。
public class SectionHeader: UITableViewHeaderFooterView {
public static let reusableIdentifier = "Section"
private var innerHostedViewController: UIHostingController<AnyView>!
public override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
setupHeader()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupHeader() {
self.backgroundView = UIView()
self.backgroundView?.backgroundColor = UIColor.green.withAlphaComponent(0.2)
innerHostedViewController = UIHostingController(rootView: AnyView(Rectangle().fill(Color.blue).frame(height: 48)))
innerHostedViewController.view.translatesAutoresizingMaskIntoConstraints = false
innerHostedViewController.view.frame = self.contentView.bounds
contentView.addSubview(innerHostedViewController.view)
innerHostedViewController.view.backgroundColor = .clear
let vv = UIView()
vv.translatesAutoresizingMaskIntoConstraints = false
vv.backgroundColor = .red
contentView.addSubview(vv)
NSLayoutConstraint.activate([
vv.topAnchor.constraint(equalTo: self.contentView.topAnchor),
vv.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor),
vv.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
vv.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor),
innerHostedViewController.view.topAnchor.constraint(equalTo: self.contentView.topAnchor),
innerHostedViewController.view.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor),
innerHostedViewController.view.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor),
innerHostedViewController.view.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor),
])
}
}
Run Code Online (Sandbox Code Playgroud)
如下图所示,顶部两个标题可见红色覆盖层(带有空单元格用于演示),但屏幕上的最后一个标题的蓝色 SwiftUI 矩形向上移动!
这个 SwiftUI 视图似乎以某种方式获得了一些 safeAreaInset,并且似乎没有办法将其关闭。如果向上滚动,插图也不会消失。它永远留在那里。我尝试关闭 SwiftUI 视图的安全区域插图,但这也没有帮助:
innerHostedViewController = UIHostingController(rootView: AnyView(Rectangle().fill(Color.blue).frame(height: 48).edgesIgnoringSafeArea(.all)))
Run Code Online (Sandbox Code Playgroud)
我如何摆脱这个插图?正如我所提到的 - 它只发生在UITableViewHeaderFooterView
s 上,而不发生UITableViewCell
在 s 上。
调试视图层次结构显示了基于安全区域插图的虚假底部填充修改器:
在这个子类中托管视图UIHostingController
对我来说很有效!
/// https://twitter.com/b3ll/status/1193747288302075906
class FixSafeAreaInsetsHostingViewController<Content: SwiftUI.View>: UIHostingController<Content> {
func fixApplied() -> Self {
self.fixSafeAreaInsets()
return self
}
func fixSafeAreaInsets() {
guard let _class = view?.classForCoder else {
fatalError()
}
let safeAreaInsets: @convention(block) (AnyObject) -> UIEdgeInsets = { (sself: AnyObject!) -> UIEdgeInsets in
return .zero
}
guard let method = class_getInstanceMethod(_class.self, #selector(getter: UIView.safeAreaInsets)) else { return }
class_replaceMethod(_class, #selector(getter: UIView.safeAreaInsets), imp_implementationWithBlock(safeAreaInsets), method_getTypeEncoding(method))
let safeAreaLayoutGuide: @convention(block) (AnyObject) -> UILayoutGuide? = { (sself : AnyObject!) -> UILayoutGuide? in return nil }
guard let method2 = class_getInstanceMethod(_class.self, #selector(getter: UIView.safeAreaLayoutGuide)) else { return }
class_replaceMethod(_class, #selector(getter: UIView.safeAreaLayoutGuide), imp_implementationWithBlock(safeAreaLayoutGuide), method_getTypeEncoding(method2))
}
override var prefersStatusBarHidden: Bool {
return false
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2442 次 |
最近记录: |