UIViewControllerRepresentable 一遍又一遍地实例化视图控制器
我是 iOS 开发新手。因此,我使用 Storyboard 制作了一个 ViewController,并通过单击按钮在 SwiftUI 视图中显示它。 可代表:
import UIKit
import SwiftUI
struct StartTraining: UIViewControllerRepresentable{
func makeUIViewController(context: UIViewControllerRepresentableContext<StartTraining>) -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let controller = storyboard.instantiateViewController(identifier: "StartTraining")
return controller
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<StartTraining>) {
//I'm not updating anything, I just need to show the ViewController and everything will be done there
}
}
SwiftUI View:
struct WorkoutDescriptionView: View {
@State private var isPresented = false
var body: some View {
Button(action: {
self.isPresented = true
}, label: {
Text("Start")
.bold()
.font(.title2)
.frame(width: 350, height: 50)
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(10)
})
.padding(.bottom).fullScreenCover(isPresented:$isPresented){
StartTraining().ignoresSafeArea()
}
}
它有效!当我单击按钮时,我确实看到 ViewController 全屏显示,但是,ViewController 中确实发生了很多事情,一旦我单击 WorkoutDescriptionView 中的“开始”按钮,并且当我想返回时,内存使用量就会增加 200 MB在用 SwiftUI 编写的主菜单(ContentView())中,单击 ViewController 内的按钮,仅释放 20MB 的内存使用量,您可以看到这是怎么回事:每次连续单击按钮打开 ViewController,内存使用量都会增加200MB甚至更多而不被释放。 (所以就像:第一次单击按钮时使用了 300MB 的总内存,然后第二次单击时使用了 500MB,然后是 700MB,依此类推)
在 View Controller 内部有一个按钮显示另一个 ViewController:
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let secondVC = storyboard.instantiateViewController(identifier: "ResultStoryboard")
self.show(secondVC, sender: self)
从另一个 ViewController 我返回到主菜单:
@objc func didTapButton(){
ViewController.updateFirebaseValues()
ViewController.camera.stop()
if #available(iOS 14.0, *) {
let vc = UIHostingController(rootView: ContentView())
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)
// self.presentingViewController?.dismiss(animated: true, completion: nil)
} else {
// Fallback on earlier versions
}
}
我想我设法杀死重型和加载的 ViewController 内的所有操作,因为如果我取消到 ContentView() 的转换,我只会看到黑屏,所以我认为问题在于我不断实例化新的视图控制器故事板并通过单击按钮呈现它们,而不删除以前创建的故事板。 这里:
func makeUIViewController(context: UIViewControllerRepresentableContext<StartTraining>) -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let controller = storyboard.instantiateViewController(identifier: "StartTraining")
return controller
}
所以我的问题是:从 switui 视图打开 uikit 视图控制器并在返回 SwiftUI 视图时关闭视图控制器时释放所有内存的最佳实践是什么?
太感谢了!
I'm new to development on iOS. So, I made a ViewController with Storyboard and am showing it in SwiftUI View on a button click.
Representable:
import UIKit
import SwiftUI
struct StartTraining: UIViewControllerRepresentable{
func makeUIViewController(context: UIViewControllerRepresentableContext<StartTraining>) -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let controller = storyboard.instantiateViewController(identifier: "StartTraining")
return controller
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<StartTraining>) {
//I'm not updating anything, I just need to show the ViewController and everything will be done there
}
}
SwiftUI View:
struct WorkoutDescriptionView: View {
@State private var isPresented = false
var body: some View {
Button(action: {
self.isPresented = true
}, label: {
Text("Start")
.bold()
.font(.title2)
.frame(width: 350, height: 50)
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(10)
})
.padding(.bottom).fullScreenCover(isPresented:$isPresented){
StartTraining().ignoresSafeArea()
}
}
And it works! I do see the ViewController in full screen when I click the button, however, there is really a lot going on in the ViewController, and memory usage increases by 200 MB once I click the Start Button in WorkoutDescriptionView, and when I want to go back to the Main Menu (ContentView()) written in SwiftUI on a button click inside the ViewController, only 20MB of the memory usage gets released, and you can see where this is going: with every consecutive button click to open ViewController memory usage increases by 200MB or even more without being released. (So it is like: 300MB of total memory usage on the first button click, then 500MB on the second click, then 700, and so on)
Inside View Controller there is a button that shows another ViewController:
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let secondVC = storyboard.instantiateViewController(identifier: "ResultStoryboard")
self.show(secondVC, sender: self)
And from the other ViewController I return to the Main Menu:
@objc func didTapButton(){
ViewController.updateFirebaseValues()
ViewController.camera.stop()
if #available(iOS 14.0, *) {
let vc = UIHostingController(rootView: ContentView())
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)
// self.presentingViewController?.dismiss(animated: true, completion: nil)
} else {
// Fallback on earlier versions
}
}
I think I manage to kill all operations inside the heavy and loaded ViewController because I see only black screen if I dismiss transition to ContentView(), so I think the issue is in my constantly instantiating new view controllers from storyboard and presenting them on Button click without removing previously created ones.
Here:
func makeUIViewController(context: UIViewControllerRepresentableContext<StartTraining>) -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let controller = storyboard.instantiateViewController(identifier: "StartTraining")
return controller
}
So my question is: what is the best practice to open uikit view controllers from switui view and release all the memory when closing view controller while coming back to SwiftUI view?
Thank you so much!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试
如果它嵌入在 UINavigationController 中,
此代码是否会进入您要忽略的视图控制器,因此在您的情况下:
try
if it's embedded in a UINavigationController do
this code goes in the view controller you are dismissing from so in your case: