gpt4 book ai didi

swift - 带有 SwiftUI 内容的 UITableViewHeaderFooterView 自动插入安全区域

转载 作者:行者123 更新时间:2023-12-04 10:06:43 24 4
gpt4 key购买 nike

我有一个基本的 UITableView与一些细胞。我正在使用 SwiftUI View作为我的单元格和节标题的内容。奇怪的是,只有在 iPhone XS Max 上似乎触碰屏幕底部的部分标题似乎得到了 rawSafeAreaInset 16pts(检查调试 View 层次结构)。我的细胞按预期工作。

为了看看发生了什么,我在 contentView 中添加了一个虚拟的蓝色 SwiftUI 矩形。 ,然后在顶部放置一个红色的 UIView,两个 View 都设置为相同的约束。 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),
])
}
}

正如您在下图中所看到的,顶部两个标题(带有空单元格用于演示)可见红色叠加层,但屏幕上的最后一个蓝色 SwiftUI 矩形向上移动!

enter image description here

这个 SwiftUI View 似乎以某种方式获得了一些 safeAreaInset,并且似乎没有办法关闭它。如果向上滚动,插图也不会消失。它永远留在那里。我尝试关闭 SwiftUI View 的安全区域插图,但这也无济于事:
innerHostedViewController = UIHostingController(rootView: AnyView(Rectangle().fill(Color.blue).frame(height: 48).edgesIgnoringSafeArea(.all)))

我如何摆脱这个插图?正如我提到的 - 它只发生在 UITableViewHeaderFooterView s 而不是 UITableViewCell s。

调试 View 层次结构揭示了基于安全区域插图的虚假底部填充修饰符:

enter image description here

最佳答案

在这个子类中托管 View 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
}
}

关于swift - 带有 SwiftUI 内容的 UITableViewHeaderFooterView 自动插入安全区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61552497/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com