如何从 SwiftUI 按钮调用用 UIKit/UIController/Storyboard 编写的函数
How do I call a function written in UIKit/UIController/Storyboard from SwiftUI button
我是一个 SwiftUI 新手,正在努力为我现有的 UIKit/Storyboard 代码添加 SwiftUI 功能。我想从 SwiftUI 按钮调用 UIKit 函数。非常感谢您的帮助。这是针对此讨论简化的相关代码。
在下面的代码中,我想从 SwiftUI...
中的 If 语句调用函数 startAction() 和 stopAction()
if (startStop_flag) {
//******** call StartAction()
} else {
//******* call StopAction()
}
下面是完整的代码。
一些上下文:当应用程序是 运行 时,屏幕的下半部分将显示“UIkit Storyboard View”并显示按钮“Open Swift Container View”。当用户单击此按钮时,SwiftUI 容器视图将打开。该视图将显示“This is a swiftUI view”并显示一个按钮“Start/Stop”。当用户单击此按钮时,需要调用 StartAction() 或 StopAction()。这两个函数驻留在UIViewController中。我希望我清楚问题和要求。
ViewController.swift
class ViewController: UIViewController {
@IBOutlet weak var nativeView: UIView!
@IBOutlet weak var nativeView_Label: UILabel!
@IBOutlet weak var nativeView_openSwiftViewBtn: UIButton!
@IBOutlet weak var containerView_forSwiftUI: UIView!
@IBSegueAction func embedSwiftUIView(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(coder: coder, rootView: SwiftUIView2(text: "Container View"))
}
var toggleOpenCloseContainerView : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
containerView_forSwiftUI.isHidden = true
}
@IBAction func openContainerView_touchInside(_ sender: Any) {
if (toggleOpenCloseContainerView) {
containerView_forSwiftUI.isHidden = false
toggleOpenCloseContainerView = false
nativeView_openSwiftViewBtn.setTitle("Close Swift Container View", for: .normal)
} else {
containerView_forSwiftUI.isHidden = true
toggleOpenCloseContainerView = true
nativeView_openSwiftViewBtn.setTitle("Open Swift Container View", for: .normal)
}
}
// These two functions need to be called from the SwiftUI's button.
func startAction() {
print("Start Action called from SwiftUI's button")
}
func stopAction() {
print("Stop Action called from SwiftUI's button")
}
}
swiftUI 函数在这个文件中
struct SwiftUIView2: View {
var text: String
@State var startStop_flag: Bool = true
var body: some View {
VStack {
Text(text)
HStack {
Image(systemName: "smiley")
Text("This is a SwiftUI View")
Spacer()
Button("\(startStop_flag ? "Start": "Stop")") {
startStop_flag = !startStop_flag
if (startStop_flag) {
//******** call StartAction()
} else {
//******* call StopAction()
}
} .padding()
.background(Color.red)
.cornerRadius(40)
.foregroundColor(.white)
.padding(5)
.overlay(
RoundedRectangle(cornerRadius: 40)
.stroke(Color.red, lineWidth: 1)
)
}
}
.font(.largeTitle)
.background(Color.blue)
}
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView2(text: "Sample Text")
}
}
您可以为此使用 closures。首先,在您的 SwiftUI 视图中定义并调用它们。
struct SwiftUIView2: View {
var text: String
var startAction: (() -> Void) /// define closure 1
var stopAction: (() -> Void) /// define closure 2
...
...
Button("\(startStop_flag ? "Start": "Stop")") {
startStop_flag = !startStop_flag
if (startStop_flag) {
//******** call StartAction()
startAction()
} else {
//******* call StopAction()
stopAction()
}
}
}
然后,只需在 ViewController.swift
.
中分配闭包的内容
@IBSegueAction func embedSwiftUIView(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(
coder: coder,
rootView: SwiftUIView2(
text: "Container View",
startAction: { [weak self] in
self?.startAction()
},
stopAction: { [weak self] in
self?.stopAction()
}
)
)
}
我是一个 SwiftUI 新手,正在努力为我现有的 UIKit/Storyboard 代码添加 SwiftUI 功能。我想从 SwiftUI 按钮调用 UIKit 函数。非常感谢您的帮助。这是针对此讨论简化的相关代码。 在下面的代码中,我想从 SwiftUI...
中的 If 语句调用函数 startAction() 和 stopAction() if (startStop_flag) {
//******** call StartAction()
} else {
//******* call StopAction()
}
下面是完整的代码。 一些上下文:当应用程序是 运行 时,屏幕的下半部分将显示“UIkit Storyboard View”并显示按钮“Open Swift Container View”。当用户单击此按钮时,SwiftUI 容器视图将打开。该视图将显示“This is a swiftUI view”并显示一个按钮“Start/Stop”。当用户单击此按钮时,需要调用 StartAction() 或 StopAction()。这两个函数驻留在UIViewController中。我希望我清楚问题和要求。
ViewController.swift
class ViewController: UIViewController {
@IBOutlet weak var nativeView: UIView!
@IBOutlet weak var nativeView_Label: UILabel!
@IBOutlet weak var nativeView_openSwiftViewBtn: UIButton!
@IBOutlet weak var containerView_forSwiftUI: UIView!
@IBSegueAction func embedSwiftUIView(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(coder: coder, rootView: SwiftUIView2(text: "Container View"))
}
var toggleOpenCloseContainerView : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
containerView_forSwiftUI.isHidden = true
}
@IBAction func openContainerView_touchInside(_ sender: Any) {
if (toggleOpenCloseContainerView) {
containerView_forSwiftUI.isHidden = false
toggleOpenCloseContainerView = false
nativeView_openSwiftViewBtn.setTitle("Close Swift Container View", for: .normal)
} else {
containerView_forSwiftUI.isHidden = true
toggleOpenCloseContainerView = true
nativeView_openSwiftViewBtn.setTitle("Open Swift Container View", for: .normal)
}
}
// These two functions need to be called from the SwiftUI's button.
func startAction() {
print("Start Action called from SwiftUI's button")
}
func stopAction() {
print("Stop Action called from SwiftUI's button")
}
}
swiftUI 函数在这个文件中
struct SwiftUIView2: View {
var text: String
@State var startStop_flag: Bool = true
var body: some View {
VStack {
Text(text)
HStack {
Image(systemName: "smiley")
Text("This is a SwiftUI View")
Spacer()
Button("\(startStop_flag ? "Start": "Stop")") {
startStop_flag = !startStop_flag
if (startStop_flag) {
//******** call StartAction()
} else {
//******* call StopAction()
}
} .padding()
.background(Color.red)
.cornerRadius(40)
.foregroundColor(.white)
.padding(5)
.overlay(
RoundedRectangle(cornerRadius: 40)
.stroke(Color.red, lineWidth: 1)
)
}
}
.font(.largeTitle)
.background(Color.blue)
}
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView2(text: "Sample Text")
}
}
您可以为此使用 closures。首先,在您的 SwiftUI 视图中定义并调用它们。
struct SwiftUIView2: View {
var text: String
var startAction: (() -> Void) /// define closure 1
var stopAction: (() -> Void) /// define closure 2
...
...
Button("\(startStop_flag ? "Start": "Stop")") {
startStop_flag = !startStop_flag
if (startStop_flag) {
//******** call StartAction()
startAction()
} else {
//******* call StopAction()
stopAction()
}
}
}
然后,只需在 ViewController.swift
.
@IBSegueAction func embedSwiftUIView(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(
coder: coder,
rootView: SwiftUIView2(
text: "Container View",
startAction: { [weak self] in
self?.startAction()
},
stopAction: { [weak self] in
self?.stopAction()
}
)
)
}