因为ScrollView不提供设置 的功能contentOffset,所以我尝试使用UIScrollViewas UIViewRepresentable。附加的代码显示了视图和视图控制器的调用者和定义。
在模拟器或预览中运行代码时,只显示一个蓝色区域。调试显示器时,Text,按预期显示。
如果不知道原因 - 是因为我做错了什么,还是因为 Xcode 或 SwiftUI 中存在错误?
这是自定义滚动视图:
struct PositionableScrollView<Content>: UIViewRepresentable where Content: View {
var content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func makeUIView(context: UIViewRepresentableContext<PositionableScrollView<Content>>) -> UIScrollView {
let scrollViewVC = PositionableScrollViewVC<Content>(nibName: nil, bundle: nil)
scrollViewVC.add(content: content)
let control = scrollViewVC.scrollView
return control
}
func updateUIView(_ uiView: UIScrollView, context: UIViewRepresentableContext<PositionableScrollView<Content>>) {
// Do nothing at the moment.
}
}
Run Code Online (Sandbox Code Playgroud)
视图控制器:
final class PositionableScrollViewVC<Content>: UIViewController where Content: View {
var scrollView: UIScrollView = UIScrollView()
var contentView: UIView!
var contentVC: UIViewController!
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
func setup() {
self.view.addSubview(self.scrollView)
self.scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
self.scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
self.scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
self.scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
self.scrollView.translatesAutoresizingMaskIntoConstraints = false
}
override func viewDidLoad() {
super.viewDidLoad()
debugPrint("self:", self.frame())
debugPrint("self.view:", self.view!.frame)
debugPrint("self.view.subviews:", self.view.subviews)
// debugPrint("self.view.subviews[0]:", self.view.subviews[0])
// debugPrint("self.view.subviews[0].subviews:", self.view.subviews[0].subviews)
}
func add(@ViewBuilder content: @escaping () -> Content) {
self.contentVC = UIHostingController(rootView: content())
self.contentView = self.contentVC.view!
self.scrollView.addSubview(contentView)
self.contentView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor).isActive = true
self.contentView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor).isActive = true
self.contentView.topAnchor.constraint(equalTo: self.scrollView.topAnchor).isActive = true
self.contentView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor).isActive = true
self.contentView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.widthAnchor.constraint(greaterThanOrEqualTo: self.scrollView.widthAnchor).isActive = true
}
}
extension PositionableScrollViewVC: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<PositionableScrollViewVC>) -> PositionableScrollViewVC {
let vc = PositionableScrollViewVC()
return vc
}
func updateUIViewController(_ uiViewController: PositionableScrollViewVC, context: UIViewControllerRepresentableContext<PositionableScrollViewVC>) {
// Do nothing at the moment.
}
}
Run Code Online (Sandbox Code Playgroud)
来电者:
struct TimelineView: View {
@State private var posX: CGFloat = 0
var body: some View {
GeometryReader { geo in
VStack {
Text("\(self.posX) || \(geo.frame(in: .global).width)")
PositionableScrollView() {
VStack {
Spacer()
Text("Hallo")
.background(Color.yellow)
Spacer()
}
.frame(width: 1000, height: 200, alignment: .bottomLeading)
}
.background(Color.blue)
}
}
}
}
struct TimelineView_Previews: PreviewProvider {
static var previews: some View {
TimelineView()
}
}
Run Code Online (Sandbox Code Playgroud)
运行时和调试器中的显示:

| 归档时间: |
|
| 查看次数: |
1228 次 |
| 最近记录: |