从托管视图控制器委托 SwiftUI 视图
Delegate for SwiftUI View from Hosting View Controller
我将 UIHostingViewController 添加到我的 Storyboard 并为此制作了 class。
在控制器初始化中加载 mySwiftUIView。一切正常。
但我想为我的SwiftUIView 创建像委托一样的托管控制器,因为我想处理视图中的按钮按下。
required init?(coder: NSCoder) {
var mySwiftView = MySwiftUIView()
mySwiftView.delegate = self //self used before super.init call
super.init(coder: coder,rootView: mySwiftView)
}
Id 不起作用,因为我在托管控制器完全初始化之前通过了视图。 Swift 显示消息“在 super.init 调用之前已使用”
如果我将使用通常的 UIViewController 并将 HostingController 放入其中 - 它是有效的。但这不适合我,因为它会调用尺寸和导航问题。
如何使用单独的 UIHostingController 来实现。谢谢
完整代码
import UIKit
import SwiftUI
protocol MySwiftUIViewDelegate{
func buttonPressed()
}
struct MySwiftUIView: View {
var delegate: MySwiftUIViewDelegate?
var body: some View {
Button(action: {
delegate?.buttonPressed()
}) {
Text("My button")
}
}
}
class MyHostingViewController: UIHostingController<MySwiftUIView>, MySwiftUIViewDelegate {
required init?(coder: NSCoder) {
var mySwiftView = MySwiftUIView()
//mySwiftView.delegate = self //self used before super.init call
super.init(coder: coder,rootView: mySwiftView)
}
override func viewDidLoad() {
super.viewDidLoad()
}
func buttonPressed() {
performSegue(withIdentifier: "GoToOtherScreenSegue", sender: self)
}
}
由于 MyHostingViewController
知道它的 rootView
是 MySwiftUIView
,您可以随后将视图控制器指定为委托:
required init?(coder: NSCoder) {
var mySwiftView = MySwiftUIView()
super.init(coder: coder, rootView: mySwiftView)
rootView.delegate = self
}
您可以将委托包装成 class
import UIKit
import SwiftUI
protocol MySwiftUIViewDelegate{
func buttonPressed()
}
struct MySwiftUIView: View {
let configuration: Configuration
var body: some View {
Button(action: {
configuration.delegate?.buttonPressed()
}) {
Text("My button")
}
}
}
extension MySwiftUIView {
final class Configuration {
unowned var delegate: MySwiftUIViewDelegate?
}
}
class MyHostingViewController: UIHostingController<MySwiftUIView>, MySwiftUIViewDelegate {
required init?(coder: NSCoder) {
let configuration = MySwiftUIView.Configuration()
let mySwiftView = MySwiftUIView(configuration: configuration)
super.init(coder: coder,rootView: mySwiftView)
configuration.delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
}
func buttonPressed() {
performSegue(withIdentifier: "GoToOtherScreenSegue", sender: self)
}
}
我将 UIHostingViewController 添加到我的 Storyboard 并为此制作了 class。 在控制器初始化中加载 mySwiftUIView。一切正常。
但我想为我的SwiftUIView 创建像委托一样的托管控制器,因为我想处理视图中的按钮按下。
required init?(coder: NSCoder) {
var mySwiftView = MySwiftUIView()
mySwiftView.delegate = self //self used before super.init call
super.init(coder: coder,rootView: mySwiftView)
}
Id 不起作用,因为我在托管控制器完全初始化之前通过了视图。 Swift 显示消息“在 super.init 调用之前已使用”
如果我将使用通常的 UIViewController 并将 HostingController 放入其中 - 它是有效的。但这不适合我,因为它会调用尺寸和导航问题。
如何使用单独的 UIHostingController 来实现。谢谢
完整代码
import UIKit
import SwiftUI
protocol MySwiftUIViewDelegate{
func buttonPressed()
}
struct MySwiftUIView: View {
var delegate: MySwiftUIViewDelegate?
var body: some View {
Button(action: {
delegate?.buttonPressed()
}) {
Text("My button")
}
}
}
class MyHostingViewController: UIHostingController<MySwiftUIView>, MySwiftUIViewDelegate {
required init?(coder: NSCoder) {
var mySwiftView = MySwiftUIView()
//mySwiftView.delegate = self //self used before super.init call
super.init(coder: coder,rootView: mySwiftView)
}
override func viewDidLoad() {
super.viewDidLoad()
}
func buttonPressed() {
performSegue(withIdentifier: "GoToOtherScreenSegue", sender: self)
}
}
由于 MyHostingViewController
知道它的 rootView
是 MySwiftUIView
,您可以随后将视图控制器指定为委托:
required init?(coder: NSCoder) {
var mySwiftView = MySwiftUIView()
super.init(coder: coder, rootView: mySwiftView)
rootView.delegate = self
}
您可以将委托包装成 class
import UIKit
import SwiftUI
protocol MySwiftUIViewDelegate{
func buttonPressed()
}
struct MySwiftUIView: View {
let configuration: Configuration
var body: some View {
Button(action: {
configuration.delegate?.buttonPressed()
}) {
Text("My button")
}
}
}
extension MySwiftUIView {
final class Configuration {
unowned var delegate: MySwiftUIViewDelegate?
}
}
class MyHostingViewController: UIHostingController<MySwiftUIView>, MySwiftUIViewDelegate {
required init?(coder: NSCoder) {
let configuration = MySwiftUIView.Configuration()
let mySwiftView = MySwiftUIView(configuration: configuration)
super.init(coder: coder,rootView: mySwiftView)
configuration.delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
}
func buttonPressed() {
performSegue(withIdentifier: "GoToOtherScreenSegue", sender: self)
}
}