UIViewControllerRepresentable 未正确占用空间

Tim*_*mmy 4 uikit ios swiftui uiviewcontrollerrepresentable

UIViewController我正在尝试在 SwiftUI 视图中使用自定义。我设置了一个在方法中UIViewControllerRepresentable创建的类。这将创建并显示按钮,但是,不占用任何空间。UIViewControllermakeUIViewControllerUIViewControllerUIViewControllerRepresentable

我尝试使用 aUIImagePickerController而不是我的自定义控制器,并且尺寸正确。我让控制器占用空间的唯一方法是在UIViewControllerRepresentableSwiftUI 视图中设置固定框架,但我绝对不想这样做。

注意:我确实需要使用 a,UIViewController因为我正在尝试UIMenuController在 SwiftUI 中实现 a。除了我遇到的尺寸不正确的问题之外,所有这些都可以工作。

这是我的代码:

struct ViewControllerRepresentable: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> MenuViewController {
        let controller = MenuViewController()
        return controller
    }
    
    func updateUIViewController(_ uiViewController: MenuViewController, context: Context) {
        
    }
}

class MenuViewController: UIViewController {
    override func viewDidLoad() {
        let button = UIButton()
        button.setTitle("Test button", for: .normal)
        button.setTitleColor(.red, for: .normal)
        
        self.view.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
        button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        button.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
        button.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    }
}
Run Code Online (Sandbox Code Playgroud)

我的 SwiftUI 视图:

struct ClientView: View {
    var body: some View {
        VStack(spacing: 0) {
            EntityViewItem(copyValue: "copy value", label: {
                Text("Name")
            }, content: {
                Text("Random name")
            })
            .border(Color.green)
            
            ViewControllerRepresentable()
                .border(Color.red)
            
            EntityViewItem(copyValue: "copy value", label: {
                Text("Route")
            }, content: {
                HStack(alignment: .center) {
                    Text("Random route name")
                }
            })
            .border(Color.blue)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

截屏:

问题截图

我对 UIKit 没有太多经验 - 我唯一的经验是编写 UIKit 视图以在 SwiftUI 中使用。这个问题很可能与我缺乏 UIKit 知识有关。

提前致谢!

编辑:

这是 的代码EntityViewItem。我还将提供ClientView以下位置的容器视图 -EntityView容器视图。

我还清理了其余的代码,并将对的引用替换为Entity硬编码值。

struct EntityViewItem<Label: View, Content: View>: View {
    var copyValue: String
    var label: Label
    var content: Content
    var action: (() -> Void)?
    
    init(copyValue: String, @ViewBuilder label: () -> Label, @ViewBuilder content: () -> Content, action: (() -> Void)? = nil) {
        self.copyValue = copyValue
        self.label = label()
        self.content = content()
        self.action = action
    }
    
    var body: some View {
        VStack(alignment: .leading, spacing: 2) {
            label
                .opacity(0.6)
            content
                .onTapGesture {
                    guard let unwrappedAction = action else {
                        return
                    }
                    unwrappedAction()
                }
                .contextMenu {
                    Button(action: {
                        UIPasteboard.general.string = copyValue
                    }) {
                        Text("Copy to clipboard")
                        Image(systemName: "doc.on.doc")
                    }
                }
        }
        .padding([.top, .leading, .trailing])
        .frame(maxWidth: .infinity, alignment: .leading)
    }
}
Run Code Online (Sandbox Code Playgroud)

容器ClientView

struct EntityView: View {
    let headerHeight: CGFloat = 56
    
    var body: some View {
        ZStack {
            ScrollView(showsIndicators: false) {
                VStack(spacing: 0) {
                    Color.clear.frame(
                        height: headerHeight
                    )
                    ClientView()
                }
            }
            VStack(spacing: 0) {
                HStack {
                    Button(action: {
                    }, label: {
                        Text("Back")
                    })
                    Spacer()
                    Text("An entity name")
                        .lineLimit(1)
                        .minimumScaleFactor(0.5)
                    
                    Spacer()
                    Color.clear
                        .frame(width: 24, height: 0)
                }
                .frame(height: headerHeight)
                .padding(.leading)
                .padding(.trailing)
                .background(
                    Color.white
                        .ignoresSafeArea()
                        .opacity(0.95)
                )
                Spacer()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Edu*_*djr 6

如果其他人试图找到更简单的解决方案,则可以使用任何视图控制器并调整大小以适合其内容:

struct ViewControllerContainer: UIViewControllerRepresentable {
    let content: UIViewController
    
    init(_ content: UIViewController) {
        self.content = content
    }
        
    func makeUIViewController(context: Context) -> UIViewController {
        let size = content.view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
        content.preferredContentSize = size
        return content
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当您在 SwiftUI 中使用它时,请确保调用.fixedSize()

struct MainView: View {
    var body: some View {
        VStack(spacing: 0) {
 
            ViewControllerContainer(MenuViewController())
                .fixedSize()
 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)