Created
November 12, 2015 20:54
-
-
Save cellularmitosis/8205610a80112eebd96c to your computer and use it in GitHub Desktop.
UIViewController containment bug demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.swift | |
// ContainerTimingBugDemo | |
// | |
// Created by Jason Pepas on 11/12/15. | |
// Copyright © 2015 Jason Pepas. All rights reserved. | |
// | |
/* | |
Instructions: | |
1. Create a new "Single View Application" Xcode project. | |
2. Replace the contents of ViewController.swift with this gist. | |
3. Uncomment the below test cases one-by-one. | |
*/ | |
import UIKit | |
extension UIViewController | |
{ | |
func containChildViewController(childVC:UIViewController, inView containerView:UIView) | |
{ | |
addChildViewController(childVC) | |
containerView.addSubview(childVC.view) | |
childVC.didMoveToParentViewController(self) | |
containerView.bringSubviewToFront(childVC.view) | |
childVC.view.translatesAutoresizingMaskIntoConstraints = false | |
} | |
func containChildViewController(child:UIViewController) | |
{ | |
self.containChildViewController(child, inView:view) | |
} | |
} | |
class ViewController: UIViewController | |
{ | |
override func viewDidAppear(animated: Bool) | |
{ | |
super.viewDidAppear(animated) | |
// self.presentViewController(VCTestCase1(), animated: true, completion: nil) | |
// self.presentViewController(VCTestCase2(), animated: true, completion: nil) | |
// self.presentViewController(VCTestCase3(), animated: true, completion: nil) | |
self.presentViewController(VCTestCase4(), animated: true, completion: nil) | |
// self.presentViewController(VCTestCase5(), animated: true, completion: nil) | |
// self.presentViewController(VCTestCase6(), animated: true, completion: nil) | |
} | |
} | |
class VerboseVC: UIViewController | |
{ | |
override func viewDidLoad() | |
{ | |
debugPrint("\(self.dynamicType): \(__FUNCTION__)") | |
super.viewDidLoad() | |
} | |
override func viewWillAppear(animated: Bool) | |
{ | |
debugPrint("\(self.dynamicType): \(__FUNCTION__)") | |
super.viewWillAppear(animated) | |
} | |
override func viewDidAppear(animated: Bool) | |
{ | |
debugPrint("\(self.dynamicType): \(__FUNCTION__)") | |
super.viewDidAppear(animated) | |
} | |
override func viewWillDisappear(animated: Bool) | |
{ | |
debugPrint("\(self.dynamicType): \(__FUNCTION__)") | |
super.viewWillDisappear(animated) | |
} | |
override func viewDidDisappear(animated: Bool) | |
{ | |
debugPrint("\(self.dynamicType): \(__FUNCTION__)") | |
super.viewDidDisappear(animated) | |
} | |
} | |
class ChildVC: VerboseVC {} | |
class VCTestCase1: VerboseVC | |
{ | |
override func viewDidLoad() | |
{ | |
super.viewDidLoad() | |
// CORRECT: SubViewController will correctly receive viewWillAppear and viewDidAppear | |
containChildViewController(ChildVC()) | |
} | |
} | |
class VCTestCase2: VerboseVC | |
{ | |
override func viewWillAppear(animated: Bool) | |
{ | |
// CORRECT: SubViewController will correctly receive viewWillAppear and viewDidAppear | |
self.containChildViewController(ChildVC()) | |
super.viewWillAppear(animated) | |
} | |
} | |
class VCTestCase3: VerboseVC | |
{ | |
override func viewWillAppear(animated: Bool) | |
{ | |
super.viewWillAppear(animated) | |
// CORRECT: SubViewController will correctly receive viewWillAppear and viewDidAppear | |
self.containChildViewController(ChildVC()) | |
} | |
} | |
class VCTestCase4: VerboseVC | |
{ | |
override func viewWillAppear(animated: Bool) | |
{ | |
super.viewWillAppear(animated) | |
dispatch_async(dispatch_get_main_queue()) { () -> Void in | |
/* | |
ERROR: SubViewController receives viewDidLoad, then viewDidAppear. viewWillAppear is not called. | |
Specifically, you should see this in the console: | |
"VCTestCase4: viewDidLoad()" | |
"VCTestCase4: viewWillAppear" | |
"ChildVC: viewDidLoad()" | |
"VCTestCase4: viewDidAppear" | |
"ChildVC: viewDidAppear" | |
*/ | |
self.containChildViewController(ChildVC()) | |
} | |
} | |
} | |
class VCTestCase5: VerboseVC | |
{ | |
override func viewDidAppear(animated: Bool) | |
{ | |
// CORRECT: SubViewController will correctly receive viewWillAppear and viewDidAppear | |
self.containChildViewController(ChildVC()) | |
super.viewDidAppear(animated) | |
} | |
} | |
class VCTestCase6: VerboseVC | |
{ | |
override func viewDidAppear(animated: Bool) | |
{ | |
super.viewDidAppear(animated) | |
// CORRECT: SubViewController will correctly receive viewWillAppear and viewDidAppear | |
self.containChildViewController(ChildVC()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment