Last active
October 17, 2018 08:48
-
-
Save antonyalkmim/700f085decf1f6a7d5f444a8fb0ecafa to your computer and use it in GitHub Desktop.
iOS UIViewController extension to fix keyboard overriding textfield
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
// | |
// UIViewController+ext.swift | |
// Antony Alkmim | |
// | |
// Created by Antony Alkmim on 03/07/18. | |
// Copyright © 2018 Antony Alkmim. All rights reserved. | |
// | |
import UIKit | |
/// stored dataKeys | |
private var activeFieldAssocKey = 0 | |
private var scrollViewAssocKey = 0 | |
// MARK: - UITextFieldDelegate | |
extension UIViewController: UITextFieldDelegate { | |
public var activeField: UITextField? { | |
get { return objc_getAssociatedObject(self, &activeFieldAssocKey) as? UITextField } | |
set { objc_setAssociatedObject(self, &activeFieldAssocKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } | |
} | |
public func textFieldDidEndEditing(textField: UITextField) { | |
self.activeField = nil | |
} | |
public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { | |
self.activeField = textField | |
return true | |
} | |
public func textFieldShouldReturn(textField: UITextField) -> Bool { | |
guard let nextResponder = self.view.viewWithTag(textField.tag + 1) else { | |
textField.resignFirstResponder() | |
return false | |
} | |
nextResponder.becomeFirstResponder() | |
return false | |
} | |
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
self.view.endEditing(true) | |
} | |
} | |
// MARK: - UIScrollViewDelegate | |
extension UIViewController: UIScrollViewDelegate { | |
@IBOutlet var scrollView: UIScrollView? { | |
get { return objc_getAssociatedObject(self, &scrollViewAssocKey) as? UIScrollView } | |
set { objc_setAssociatedObject(self, &scrollViewAssocKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } | |
} | |
@objc func keyboardWillShow(notification: NSNotification) { | |
// Check if scrollView its referencied | |
guard self.scrollView != nil else { return } | |
if let activeField = self.activeField, let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { | |
let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0) | |
self.scrollView!.contentInset = contentInsets | |
self.scrollView!.scrollIndicatorInsets = contentInsets | |
var aRect = self.view.frame | |
aRect.size.height -= keyboardSize.size.height //subtract keyboard height | |
if !aRect.contains(activeField.frame.origin) { | |
self.scrollView!.scrollRectToVisible(activeField.frame, animated: true) | |
} | |
} | |
} | |
@objc func keyboardWillBeHidden(notification: NSNotification) { | |
guard self.scrollView != nil else {return} | |
UIView.animate(withDuration: 0.17) { | |
self.scrollView!.contentInset = UIEdgeInsets.zero | |
self.scrollView!.scrollIndicatorInsets = UIEdgeInsets.zero | |
self.scrollView!.layoutIfNeeded() | |
} | |
} | |
func setupScrollKeyboard() { | |
NotificationCenter.default.addObserver(self, | |
selector: #selector(self.keyboardWillShow), | |
name: NSNotification.Name.UIKeyboardDidShow, | |
object: nil) | |
NotificationCenter.default.addObserver(self, | |
selector: #selector(self.keyboardWillBeHidden), | |
name: NSNotification.Name.UIKeyboardDidHide, | |
object: nil) | |
} | |
} | |
extension UIScrollView { | |
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
self.endEditing(true) | |
} | |
} |
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 ViewController: UIViewController { | |
// MARK: - Outlets | |
@IBOutlet weak var textfield: UITextField! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
textfield.delegate = self | |
setupScrollKeyboard() | |
textfield.becomeFirstResponder() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment