Last active
February 12, 2019 05:06
-
-
Save michaeleisel/4b8ba210dc12c78f87cd2314f0451747 to your computer and use it in GitHub Desktop.
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
import UIKit | |
class MyViewController: UIViewController { | |
@IBOutlet weak var button: UIButton! | |
var vc: UIViewController? = nil | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
button.addTarget(self, action: #selector(down), for: .touchDown) | |
// If user generated touchDown and then didn't generate touchUpInside, we would have | |
// set up a view controller that won't even be presented, which can cause problems, | |
// e.g. with metrics. | |
// Instead, run the .up() method for *every* possible outcome after touchDown: | |
// touchUpInside, touchUpOutside, and touchCancel | |
button.addTarget(self, action: #selector(up), for: .touchUpInside) | |
button.addTarget(self, action: #selector(up), for: .touchUpOutside) | |
button.addTarget(self, action: #selector(up), for: .touchCancel) | |
// Don't let the user do anything else while they're pressing the button | |
button.isExclusiveTouch = true | |
} | |
@objc private func up() { | |
if let vc = vc { | |
present(vc, animated: true, completion: nil) | |
} else { | |
// This else block would only happen in the (probably) impossible case when .async | |
// is still enqueued from .down() | |
} | |
vc = nil | |
} | |
@objc private func down() { | |
// This .async call is necessary if the button has an animation that you want to run | |
// while the main thread is blocked to set up the new VC. | |
// You might think that blocking the main thread, even after the animation has just | |
// begun, will still block the animation. But actually, once they've been started, | |
// animations keep going even when the main thread is blocked | |
DispatchQueue.main.async { | |
let vc = UIViewController() | |
let _ = vc.view // Calling .view triggers viewDidLoad etc., so that more setup can occur | |
self.vc = vc | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment