我有两个视图控制器,(cond
((and (list? tree)
(null? (cadr tree)) ; the second element is '()
(null? (caddr tree))) ; the third element is '()
(list x))
...
...)
和MainVC
。
当用户点击ModalVC
上的按钮时,会出现模态视图控制器。
然后,用户可以点击另一个按钮将其关闭并返回主按钮。
我尝试过这两种方法并且它们都完成了同样的事情:它们解雇了模态视图控制器:
MainVC
正如我所说的那样正常,但考虑另一种方法:使用委托让主控制器解雇:
//method 1:
// File: ModalVC.swift
//
@IBAction func dismissTapped() {
self.dismissViewControllerAnimated(false, completion: nil);
}
并在主视图控制器上自定义类文件:
// method 2: part A
// File: ModalVC.swift
//
protocol ModalVCDelegate {
func modalVCDismissTapped();
}
...
...
...
var delegat:ModalVCDelegate? = nil;
...
...
@IBAction func dismissTapped() {
delegate.modalVCDismissTapped();
}
由于这两种方法是必要的,我应该担心任何可能的内存泄漏吗?
任何解释都会有所帮助
答案 0 :(得分:15)
使用委托是解除视图控制器的最佳和更灵活的方法
它的目的是在你的代码中的某些未来或其他地方你可以重用这个VC,但由于某些原因你可能不会将它呈现为模态,而是推入导航堆栈。所以你的ModalVC
不知道它是如何呈现的,但代表确实如此
在这种情况下,您的代码中可以有2个位置
您呈现模态和委托调用
[self dismiss...]
您将其推入导航堆栈并委派调用
[self.navigationController popView...]
您将其添加为子VC并委派调用
[someParentVC removeChild..]
或任何其他适当的工作流程以将其删除。
答案 1 :(得分:0)
Modo Ltunzher的答案很好。 我个人更喜欢将闭包传递给“孩子”,孩子完成后会回呼“父亲”并获得奖金,我也可以传递值/结果。
一个例子:我展示了一个QRCode,它将在识别到qrcode时关闭并回调:
extension UIViewController {
func presentQRCode( pushed: Bool, callback: @escaping QRCodeCallBack){
let qrVC = ScanQRCodeController(nibName: "ScanQRCodeController", bundle: nil)
qrVC.callback = callback
if pushed{
let nc = self.navigationController!
nc.pushViewController(qrVC, animated: true)
}else{
self.present(qrVC, animated: true, completion: nil)
}
}
func dismissQRCode(pushed: Bool){
if pushed{
let nc = self.navigationController!
nc.popViewController(animated: true)
}else{
self.dismiss(animated: true, completion: nil)
}
}
}
在“父亲”中
@IBAction func doScanCodeAction(_ sender: UIBarButtonItem) {
let pushed = true
self.presentQRCode(pushed: pushed, callback: { (string: String?) in
if let qrCode = string{
self.fillFieldsWith(qrCode: qrCode)
}else{
#if DEBUG
print("QR code error")
#endif
}
self.dismissQRCode(pushed: pushed)
}
)
}
答案 2 :(得分:0)
呈现的视图控制器目前不知道它正在呈现,因此它不应该知道自己关闭。
Apple 建议从呈现视图控制器 https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss
中解除呈现的视图控制器为避免在您的情况下发生泄漏,请始终将您的委托变量声明为 weak。 为此,您的协议应从 AnyObject 继承。
protocol ModalVCDelegate: AnyObject {
func modalVCDismissTapped()
}
weak var delegate: ModalVCDelegate?
另一种方法是在呈现的 VC 上创建一个闭包变量,并在呈现的 VC 上初始化它后传递 dismiss 操作,然后在对上的操作调用闭包提交的 VC。
演示 VC 设置
class PresentingViewController: UIViewController {
@IBAction func buttonTapped(_ sender: Any) {
let presentedVC = PresentedViewController()
presentedVC.modalPresentationStyle = .fullScreen
presentedVC.onDismissAction = { [weak self] in
self?.dismiss(animated: true)
}
self.present(presentedVC, animated: true, completion: nil)
}
}
提供用于关闭的 VC 设置
class PresentedViewController: UIViewController {
var onDismissAction: (() -> Void)?
@IBAction func exitButtonTapped(_ sender: Any) {
onDismissAction?()
}
}