Skip to content

Instantly share code, notes, and snippets.

@SamuelFolledo
Created July 13, 2020 01:12
Show Gist options
  • Save SamuelFolledo/7954775ac1f251b741a171a7e2751b66 to your computer and use it in GitHub Desktop.
Save SamuelFolledo/7954775ac1f251b741a171a7e2751b66 to your computer and use it in GitHub Desktop.
import UIKit
extension UIViewController {
/// method that instantiate a xib file given a string name using Generic
static func loadFromNib() -> Self {
func instantiateFromNib<T: UIViewController>() -> T {
return T.init(nibName: String(describing: T.self), bundle: nil)
}
return instantiateFromNib()
}
/// method that instantiate a xib file given a string name
static func instantiate() -> Self {
return self.init(nibName: String(describing: self), bundle: nil)
}
// MARK: Keyboards
/// hides keyboard when page is tapped. Call it in setupViews()
func hideKeyboardOnTap() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
// MARK: Keyboard Notifications
func registerKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: UIResponder.keyboardDidShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
func removeKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardDidShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardDidShow(notification: NSNotification) {
guard let keyboardFrame = notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardHeight = view.convert(keyboardFrame.cgRectValue, from: nil).size.height
scrollView.contentInset.bottom = keyboardHeight + 200
submitApplicationButton.snp.updateConstraints { (make) in
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-keyboardHeight + 10)
}
}
@objc func keyboardWillHide(notification: NSNotification) {
scrollView.contentInset.bottom = 0
submitApplicationButton.snp.updateConstraints { (make) in
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-10)
}
}
// MARK: Alerts
func presentAlert(title: String, message: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
/// Presents an alert with customizable button title and a completion handler
/// - Parameters:
/// - title: Title for alert
/// - message: Message for alert
/// - options: Button titles separated by comma
/// - completion: Returns which options was tapped
/// - Reference: https://stackoverflow.com/questions/29633938/swift-displaying-alerts-best-practices
func presentAlertWithOptions(title: String, message: String, options: String..., completion: @escaping (Int) -> Void) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
if options.count == 0 { // if there is no options, show a basic alert
let OKAction = UIAlertAction(title: "OK", style: .default, handler: { (action) in
completion(0)
})
alertController.addAction(OKAction)
} else { // alert with options
for (index, option) in options.enumerated() {
var alertStyle = UIAlertAction.Style.default
switch option { // check if we should style the buttons
case "Cancel": // cancel style
alertStyle = .cancel
case "Logout", "Discard Changes", "Discard", "Delete", "Remove": // destructive style
alertStyle = .destructive
default: break // keep as default
}
alertController.addAction(UIAlertAction(title: option, style: alertStyle, handler: { (action) in
completion(index)
}))
}
}
self.present(alertController, animated: true, completion: nil)
}
func presentAlertWithPassword(title: String? = nil,
subtitle: String? = nil,
actionTitle: String? = "Confirm",
cancelTitle: String? = "Cancel",
inputPlaceholder: String? = nil,
inputKeyboardType: UIKeyboardType = UIKeyboardType.default,
cancelHandler: ((UIAlertAction) -> Swift.Void)? = nil,
actionHandler: ((_ text: String?) -> Void)? = nil) {
let alert = UIAlertController(title: title, message: subtitle, preferredStyle: .alert)
alert.addTextField { (textField: UITextField) in
textField.placeholder = inputPlaceholder
textField.keyboardType = inputKeyboardType
textField.isSecureTextEntry = true
}
alert.addAction(UIAlertAction(title: actionTitle, style: .default, handler: { (action: UIAlertAction) in
guard let textField = alert.textFields?.first else {
actionHandler?(nil)
return
}
actionHandler?(textField.text)
}))
alert.addAction(UIAlertAction(title: cancelTitle, style: .cancel, handler: cancelHandler))
self.present(alert, animated: true, completion: nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment