Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS 13:导航控制器内部的滚动视图赢得';不要进入状态栏_Ios_Swift_Uinavigationcontroller - Fatal编程技术网

iOS 13:导航控制器内部的滚动视图赢得';不要进入状态栏

iOS 13:导航控制器内部的滚动视图赢得';不要进入状态栏,ios,swift,uinavigationcontroller,Ios,Swift,Uinavigationcontroller,我想在SwiftUI上创建一个自定义的滚动视图,让我可以设置滚动位置。我做了一半,遇到了一个问题,滚动时状态栏下的滚动视图没有正常流动 问题是这样的: class MyHostingController<Content: View>: UIHostingController<Content> { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews()

我想在SwiftUI上创建一个自定义的滚动视图,让我可以设置滚动位置。我做了一半,遇到了一个问题,滚动时状态栏下的滚动视图没有正常流动

问题是这样的:

class MyHostingController<Content: View>: UIHostingController<Content> {
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        view.subviews[0].frame = UIScreen.main.bounds
    }
}

在测试时,我做了一个基于故事板的比较项目,它没有任何代码,只是一个与代码完全相同的结构。结果是这样的,这就是我想要实现的:

看起来好像根视图控制器视图没有到达顶部,但我不明白为什么。所有其他自动滚动插入魔术作品,因为它应该

这是我的代码,您可以在Xcode 11中使用SwiftUI创建一个新项目,并将其粘贴到ContentView.swift

import SwiftUI
import UIKit

class UIScrollableViewController: UIViewController {
    let scrollView = UIScrollView()
    let contentController: UIViewController

    init(contentController: UIViewController) {
        self.contentController = contentController

        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)

        // Add child controller
        scrollView.addSubview(contentController.view)
        addChild(contentController)

        let contentView = contentController.view!

        // Constrain scroll view
        scrollView.translatesAutoresizingMaskIntoConstraints = false;
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true

        // Constrain child view to scroll view
        contentView.translatesAutoresizingMaskIntoConstraints = false
        contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
        contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

        // Constrain width of child view to width of self.view, NOT scroll view
        contentView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    }
}

class ScrollableNavigationController: UINavigationController, UINavigationBarDelegate {
}

struct ScrollableNavigationViewController<Content: View>: UIViewControllerRepresentable {
    typealias UIViewControllerType = ScrollableNavigationController

    let hostingController: UIHostingController<Content>
    let scrollableContainer: UIScrollableViewController!

    init(@ViewBuilder content: () -> Content) {
        hostingController = UIHostingController(rootView: content())
        scrollableContainer = UIScrollableViewController(contentController: hostingController)

        scrollableContainer.title = "Scrollable"
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<ScrollableNavigationViewController>) -> ScrollableNavigationController {
        let navigationController = ScrollableNavigationController(rootViewController: scrollableContainer)

        navigationController.navigationBar.prefersLargeTitles = true

        return navigationController
    }

    func updateUIViewController(_ navigationController: ScrollableNavigationController, context: UIViewControllerRepresentableContext<ScrollableNavigationViewController>) {
    }
}

struct ScrollableNavigationView<Content: View>: View {
    var content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        ScrollableNavigationViewController {
            content
        }
    }
}

// MARK: Test

struct BoxView: View {
    var colors: [Color] = [.red, .blue, .orange, .pink, .yellow]

    var body: some View {
        ForEach(0 ..< 20) { i in
            ZStack {
                Rectangle()
                    .fill(self.colors[i % 5])
                    .padding()
                    .frame(height: 130)
                Text("\(i)")
                    .font(.title)
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        ScrollableNavigationView {
            BoxView()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
导入快捷界面
导入UIKit
类UIScrollableViewController:UIViewController{
让scrollView=UIScrollView()
让contentController:UIViewController
初始化(contentController:UIViewController){
self.contentController=contentController
super.init(nibName:nil,bundle:nil)
}
必需初始化?(编码器:NSCoder){
fatalError(“初始化(编码者:)尚未实现”)
}
重写func viewDidLoad(){
super.viewDidLoad()
view.addSubview(滚动视图)
//添加子控制器
scrollView.addSubview(contentController.view)
addChild(contentController)
让contentView=contentController.view!
//约束滚动视图
scrollView.TranslatesAutoResizezingMaskintoConstraints=false;
scrollView.leadingAnchor.constraint(等式:view.leadingAnchor,常数:0)。isActive=true
scrollView.topAnchor.constraint(equalTo:view.topAnchor,常量:0)。isActive=true
scrollView.trailingAnchor.constraint(equalTo:view.trailingAnchor,常量:0)。isActive=true
scrollView.bottomAnchor.constraint(equalTo:view.bottomAnchor,常量:0)。isActive=true
//将子视图约束到滚动视图
contentView.translatesAutoResizezingMaskintoConstraints=false
contentView.leadingAnchor.constraint(等式:scrollView.leadingAnchor).isActive=true
contentView.topAnchor.constraint(equalTo:scrollView.topAnchor).isActive=true
contentView.trailingAnchor.constraint(equalTo:scrollView.trailingAnchor).isActive=true
contentView.bottomAnchor.constraint(equalTo:scrollView.bottomAnchor).isActive=true
//将子视图的宽度约束为self.view的宽度,而不是滚动视图
contentView.widthAnchor.constraint(equalTo:view.widthAnchor).isActive=true
}
}
类ScrollableNavigationController:UINavigationController,UINavigationBarDelegate{
}
结构ScrollableNavigationViewController:UIViewControllerRepresentable{
typealias UIViewControllerType=ScrollableNavigationController
让hostingController:UIHostingController
让scrollableContainer:UIScrollableViewController!
init(@ViewBuilder内容:()->content){
hostingController=UIHostingController(rootView:content())
scrollableContainer=UIScrollableViewController(contentController:hostingController)
scrollableContainer.title=“可滚动”
}
func makeUIViewController(上下文:UIViewControllerRepresentableContext)->ScrollableNavigationController{
让navigationController=ScrollableNavigationController(rootViewController:scrollableContainer)
navigationController.navigationBar.prefersLargeTitles=true
返回导航控制器
}
func updateUIViewController(uNavigationController:ScrollableNavigationController,上下文:UIViewControllerRepresentableContext){
}
}
结构ScrollableNavigationView:视图{
var-content:content
init(@ViewBuilder内容:()->content){
self.content=content()
}
var body:一些观点{
ScrollableNavigationViewController{
内容
}
}
}
//马克:测试
结构BoxView:视图{
变量颜色:[颜色]=[.红色、.蓝色、.橙色、.粉色、.黄色]
var body:一些观点{
ForEach(0..<20){i in
ZStack{
矩形()
.fill(自我颜色[i%5])
.padding()
.框架(高度:130)
文本(“\(i)”)
.font(.title)
}
}
}
}
结构ContentView:View{
var body:一些观点{
滚动导航视图{
BoxView()
}
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}

问题似乎在于场景代理,它导致整个视图层次被包装在
UIHostingController
中,而嵌套的SwiftUI控制器似乎能够避免这种插入魔法。为了证明这一点,我提出了一个略显粗糙的解决方案

替换此项:

window.rootViewController = UIHostingController(rootView: ContentView())
与:

MyHostingController
如下所示:

class MyHostingController<Content: View>: UIHostingController<Content> {
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        view.subviews[0].frame = UIScreen.main.bounds
    }
}
类MyHostingController:UIHostingController{
重写func viewdilayoutsubviews(){
super.viewDidLayoutSubviews()
view.subview[0]。frame=UIScreen.main.bounds
}
}
从iOS 13.1开始,您似乎应该只尝试在两层UIKit之间集成SwiftUI,而不是相反。SwiftUI的内部包含了太多未记录的魔法