Original Post: November 3, 2015 (Swift 2)
If I have a default ViewControllerA, which presents ViewControllerB with 'OverCurrentContext' UIModalPresentationStyle, then I face a problem that 'viewWillAppear' in ViewControllerA is not called after ViewControllerB is dismissed. Consequently, it would be difficult for me to run some codes in ViewControllerA since I don't know when ViewControllerB is dismissed.
Here is my original description to this problem:
iOS: Detect dismissViewControllerAnimated while using UIModalPresentationStyle.OverCurrentContext
In order to run some codes in ViewControllerA right after ViewControllerB is dismissed, a completion block is created in ViewControllerB. Then function myFuncInViewControllerA() in ViewControllerA can be executed at the right moment. The solution is as below:
In order to run some codes in ViewControllerA right after ViewControllerB is dismissed, a completion block is created in ViewControllerB. Then function myFuncInViewControllerA() in ViewControllerA can be executed at the right moment. The solution is as below:
Update: August 3, 2017 (Swift 3.1 + Xcode 8.3.3)
Remember to select ViewControllerA.swift as a custom class in the identify inspector in the storyboard after renaming ViewController.swift as ViewControllerA.swift.
ViewControllerA.swift:
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: (view.frame.width-200)/2, y: 50, width: 200, height: 20))
button.setTitle("Button", for: UIControlState.normal)
button.setTitleColor(UIColor.blue, for: UIControlState.normal)
button.setTitleColor(UIColor.cyan, for: UIControlState.highlighted)
button.contentMode = UIViewContentMode.center
button.addTarget(self, action: #selector(btnPressed), for: UIControlEvents.touchUpInside)
view.addSubview(button)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear")
}
func btnPressed() {
let controllerB = ViewControllerB()
controllerB.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
controllerB.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
controllerB.dismissVCCompletion(){ () in
self.myFuncInViewControllerA()
}
present(controllerB, animated: true, completion: nil)
}
func myFuncInViewControllerA() {
print("Back to ViewControllerA!")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
ViewControllerB.swift:
import UIKit
class ViewControllerB: UIViewController {
typealias typeCompletionHandler = () -> ()
var completion : typeCompletionHandler = {}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(white: 0, alpha: 0.5)
let viewB = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width*0.6, height: view.frame.height*0.6))
viewB.center = view.center
viewB.backgroundColor = UIColor.orange
let buttonBack = UIButton(frame: CGRect(x: (viewB.frame.width-200)/2, y: 100, width: 200, height: 20))
buttonBack.setTitle("Back", for: UIControlState.normal)
buttonBack.setTitleColor(UIColor.blue, for: UIControlState.normal)
buttonBack.setTitleColor(UIColor.cyan, for: UIControlState.highlighted)
buttonBack.contentMode = UIViewContentMode.center
buttonBack.addTarget(self, action: #selector(btnBackPressed), for: UIControlEvents.touchUpInside)
viewB.addSubview(buttonBack)
view.addSubview(viewB)
}
func btnBackPressed() {
dismiss(animated: true, completion: {
self.completion()
})
}
func dismissVCCompletion(completionHandler: @escaping typeCompletionHandler) {
self.completion = completionHandler
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
Original Post: November 3, 2015 (Swift 2)
ViewControllerA.swift:
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRectMake(50, 100, 200, 20))
button.setTitle("Button", forState: UIControlState.Normal)
button.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
button.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
button.addTarget(self, action: "btnPressed:", forControlEvents: UIControlEvents.TouchUpInside)
view.addSubview(button)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear")
}
func btnPressed(sender: UIButton) {
let controllerB = ViewControllerB()
controllerB.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
controllerB.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
controllerB.dismissVCCompletion(){ () in
self.myFuncInViewControllerA()
}
presentViewController(controllerB, animated: true, completion: nil)
}
func myFuncInViewControllerA() {
print("Back to ViewControllerA!")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
ViewControllerB.swift:
class ViewControllerB: UIViewController {
typealias typeCompletionHandler = () -> ()
var completion : typeCompletionHandler = {}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(white: 0, alpha: 0.5)
let viewB = UIView(frame: CGRectMake(0,0,view.frame.width*0.6,view.frame.height*0.6))
viewB.center = view.center
viewB.backgroundColor = UIColor.orangeColor()
let buttonBack = UIButton(frame: CGRectMake(30, 100, 200, 20))
buttonBack.setTitle("Back", forState: UIControlState.Normal)
buttonBack.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
buttonBack.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
buttonBack.addTarget(self, action: "btnBackPressed:", forControlEvents: UIControlEvents.TouchUpInside)
viewB.addSubview(buttonBack)
view.addSubview(viewB)
}
func btnBackPressed(sender: UIButton) {
dismissViewControllerAnimated(true, completion: {
self.completion()
})
}
func dismissVCCompletion(completionHandler: typeCompletionHandler) {
self.completion = completionHandler
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
References:
Completion Handlers in Swift
In case you need to return something:
How to use completionHandler Closure with return in Swift?
In case you need to return something:
How to use completionHandler Closure with return in Swift?
No comments:
Post a Comment