Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 315 Vote(s) - 3.57 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Move textfield when keyboard appears swift

#11
func registerForKeyboardNotifications(){
//Keyboard
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWasShown), name: UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillBeHidden), name: UIKeyboardDidHideNotification, object: nil)


}
func deregisterFromKeyboardNotifications(){

NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)

}
func keyboardWasShown(notification: NSNotification){

let userInfo: NSDictionary = notification.userInfo!
let keyboardInfoFrame = userInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)?.CGRectValue()

let windowFrame:CGRect = (UIApplication.sharedApplication().keyWindow!.convertRect(self.view.frame, fromView:self.view))

let keyboardFrame = CGRectIntersection(windowFrame, keyboardInfoFrame!)

let coveredFrame = UIApplication.sharedApplication().keyWindow!.convertRect(keyboardFrame, toView:self.view)

let contentInsets = UIEdgeInsetsMake(0, 0, (coveredFrame.size.height), 0.0)
self.scrollViewInAddCase .contentInset = contentInsets;
self.scrollViewInAddCase.scrollIndicatorInsets = contentInsets;
self.scrollViewInAddCase.contentSize = CGSizeMake((self.scrollViewInAddCase.contentSize.width), (self.scrollViewInAddCase.contentSize.height))

}
/**
this method will fire when keyboard was hidden

- parameter notification: contains keyboard details
*/
func keyboardWillBeHidden (notification: NSNotification) {

self.scrollViewInAddCase.contentInset = UIEdgeInsetsZero
self.scrollViewInAddCase.scrollIndicatorInsets = UIEdgeInsetsZero

}

Reply

#12
If you're like me, using Autolayout and not getting the keyboard when running the App on a simulator. This might be because Apple make you use the keyboard of you're computer as first Keyboard.

To make the keyboard from the device appear :

<kbd>shift</kbd> + <kbd>cmd</kbd> + <kbd>K</kbd>

Sounds stupid but I would have loved to find this answer 3 hours ago :)
Reply

#13
Such simple `UIViewController` **extension** can be used

//MARK: - Observers
extension UIViewController {

func addObserverForNotification(notificationName: String, actionBlock: (NSNotification) -> Void) {
NSNotificationCenter.defaultCenter().addObserverForName(notificationName, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: actionBlock)
}

func removeObserver(observer: AnyObject, notificationName: String) {
NSNotificationCenter.defaultCenter().removeObserver(observer, name: notificationName, object: nil)
}
}

//MARK: - Keyboard observers
extension UIViewController {

typealias KeyboardHeightClosure = (CGFloat) -> ()

func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?,
willHide willHideClosure: KeyboardHeightClosure?) {
NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillChangeFrameNotification,
object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { [weak self](notification) in
if let userInfo = notification.userInfo,
let frame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue(),
let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
let c = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt,
let kFrame = self?.view.convertRect(frame, fromView: nil),
let kBounds = self?.view.bounds {

let animationType = UIViewAnimationOptions(rawValue: c)
let kHeight = kFrame.size.height
UIView.animateWithDuration(duration, delay: 0, options: animationType, animations: {
if CGRectIntersectsRect(kBounds, kFrame) { // keyboard will be shown
willShowClosure?(kHeight)
} else { // keyboard will be hidden
willHideClosure?(kHeight)
}
}, completion: nil)
} else {
print("Invalid conditions for UIKeyboardWillChangeFrameNotification")
}
})
}

func removeKeyboardObserver() {
removeObserver(self, notificationName: UIKeyboardWillChangeFrameNotification)
}
}
Example of usage

override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)

removeKeyboardObserver()
}

override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)

addKeyboardChangeFrameObserver(willShow: { [weak self](height) in
//Update constraints here
self?.view.setNeedsUpdateConstraints()
}, willHide: { [weak self](height) in
//Reset constraints here
self?.view.setNeedsUpdateConstraints()
})
}

**Swift 4 solution**

//MARK: - Observers
extension UIViewController {

func addObserverForNotification(_ notificationName: Notification.Name, actionBlock: @escaping (Notification) -> Void) {
NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main, using: actionBlock)
}

func removeObserver(_ observer: AnyObject, notificationName: Notification.Name) {
NotificationCenter.default.removeObserver(observer, name: notificationName, object: nil)
}
}

//MARK: - Keyboard handling
extension UIViewController {

typealias KeyboardHeightClosure = (CGFloat) -> ()

func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?,
willHide willHideClosure: KeyboardHeightClosure?) {
NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame,
object: nil, queue: OperationQueue.main, using: { [weak self](notification) in
if let userInfo = notification.userInfo,
let frame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
let c = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt,
let kFrame = self?.view.convert(frame, from: nil),
let kBounds = self?.view.bounds {

let animationType = UIViewAnimationOptions(rawValue: c)
let kHeight = kFrame.size.height
UIView.animate(withDuration: duration, delay: 0, options: animationType, animations: {
if kBounds.intersects(kFrame) { // keyboard will be shown
willShowClosure?(kHeight)
} else { // keyboard will be hidden
willHideClosure?(kHeight)
}
}, completion: nil)
} else {
print("Invalid conditions for UIKeyboardWillChangeFrameNotification")
}
})
}

func removeKeyboardObserver() {
removeObserver(self, notificationName: NSNotification.Name.UIKeyboardWillChangeFrame)
}
}

**Swift 4.2**

//MARK: - Keyboard handling
extension UIViewController {

func addObserverForNotification(_ notificationName: Notification.Name, actionBlock: @escaping (Notification) -> Void) {
NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main, using: actionBlock)
}

func removeObserver(_ observer: AnyObject, notificationName: Notification.Name) {
NotificationCenter.default.removeObserver(observer, name: notificationName, object: nil)
}

typealias KeyboardHeightClosure = (CGFloat) -> ()

func removeKeyboardObserver() {
removeObserver(self, notificationName: UIResponder.keyboardWillChangeFrameNotification)
}

func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?,
willHide willHideClosure: KeyboardHeightClosure?) {
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillChangeFrameNotification,
object: nil, queue: OperationQueue.main, using: { [weak self](notification) in
if let userInfo = notification.userInfo,
let frame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,
let c = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt,
let kFrame = self?.view.convert(frame, from: nil),
let kBounds = self?.view.bounds {

let animationType = UIView.AnimationOptions(rawValue: c)
let kHeight = kFrame.size.height
UIView.animate(withDuration: duration, delay: 0, options: animationType, animations: {
if kBounds.intersects(kFrame) { // keyboard will be shown
willShowClosure?(kHeight)
} else { // keyboard will be hidden
willHideClosure?(kHeight)
}
}, completion: nil)
} else {
print("Invalid conditions for UIKeyboardWillChangeFrameNotification")
}
})
}
}

Reply

#14
Just enclose your textbox inside a view and then override inputAccessoryView returning the view.
Important: Your view should be created programmatically. Do not use @IBOutlets.


override var inputAccessoryView: UIView? {
get {
return newlyProgramaticallyCreatedView
}}
Reply

#15
Swift 4.x answer, merging answers from @Joseph Lord and @Isuru. `bottomConstraint` represents the bottom constraint of the view you're interested in moving.


override func viewDidLoad() {
// Call super
super.viewDidLoad()

// Subscribe to keyboard notifications
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardNotification(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification,
object: nil)
}


deinit {
NotificationCenter.default.removeObserver(self)
}


@objc func keyboardNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
// Get keyboard frame
let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

// Set new bottom constraint constant
let bottomConstraintConstant = keyboardFrame.origin.y >= UIScreen.main.bounds.size.height ? 0.0 : keyboardFrame.size.height

// Set animation properties
let duration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
let animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw)

// Animate the view you care about
UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: {
self.bottomConstraint.constant = bottomConstraintConstant
self.view.layoutIfNeeded()
}, completion: nil)
}
}
Reply

#16
Swift 4.1,

Use TPKeyBoardAvoiding class for achieving this.
This works fine with **UIScrollView**, **UICollectionView**, **UITableView**.

Just assign this class to your scrollview, collectionview or tableview in storyboard or create its object programmatically.
All textfield or textviews inside **TPKeyboardAvoiding** scrollview will adjust automatically when the keyboard appears and disappears.

Here is the link for [TPKeyboardAvoiding][1]

**TPKeyboardAvoiding for Swift 4.1,**


import Foundation
import UIKit

// MARK: - TableView
class TPKeyboardAvoidingTableView:UITableView,UITextFieldDelegate, UITextViewDelegate {

override var frame:CGRect{
willSet{
super.frame = frame
}

didSet{
if hasAutomaticKeyboardAvoidingBehaviour() {return}
TPKeyboardAvoiding_updateContentInset()
}
}

override var contentSize:CGSize{
willSet(newValue){
if hasAutomaticKeyboardAvoidingBehaviour() {
super.contentSize = newValue
return
}

if newValue.equalTo(self.contentSize)
{
return
}

super.contentSize = newValue
self.TPKeyboardAvoiding_updateContentInset()
}

// didSet{
// self.TPKeyboardAvoiding_updateContentInset()
// }
}


override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame: frame, style: style)
self.setup()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}

override func awakeFromNib() {
setup()
}

deinit{
NotificationCenter.default.removeObserver(self)
}

func hasAutomaticKeyboardAvoidingBehaviour()->Bool
{
if #available(iOS 8.3, *) {
if self.delegate is UITableViewController
{
return true
}
}

return false
}

func focusNextTextField()->Bool
{
return self.TPKeyboardAvoiding_focusNextTextField()
}

@objc func scrollToActiveTextField()
{
return self.TPKeyboardAvoiding_scrollToActiveTextField()
}

override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
if newSuperview != nil {
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
super.touchesEnded(touches, with: event)
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if !self.focusNextTextField()
{
textField.resignFirstResponder()
}
return true
}

override func layoutSubviews() {
super.layoutSubviews()
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
}
}

private extension TPKeyboardAvoidingTableView
{
func setup()
{
if self.hasAutomaticKeyboardAvoidingBehaviour() { return }

NotificationCenter.default.addObserver(self,
selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
name: NSNotification.Name.UIKeyboardWillChangeFrame,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
name: NSNotification.Name.UIKeyboardWillHide,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(scrollToActiveTextField),
name: NSNotification.Name.UITextViewTextDidBeginEditing,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(scrollToActiveTextField),
name: NSNotification.Name.UITextFieldTextDidBeginEditing,
object: nil)
}
}

// MARK: - CollectionView
class TPKeyboardAvoidingCollectionView:UICollectionView,UITextViewDelegate {

override var contentSize:CGSize{
willSet(newValue){
if newValue.equalTo(self.contentSize)
{
return
}

super.contentSize = newValue
self.TPKeyboardAvoiding_updateContentInset()
}

// didSet{
// self.TPKeyboardAvoiding_updateContentInset()
// }
}


override var frame:CGRect{
willSet{
super.frame = frame
}

didSet{
self.TPKeyboardAvoiding_updateContentInset()
}
}

// override init(frame: CGRect) {
// super.init(frame: frame)
// }

override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
setup()
}

required init?(coder aDecoder: NSCoder) {
// fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
self.setup()

}

override func awakeFromNib() {
setup()
}

deinit{
NotificationCenter.default.removeObserver(self)
}

func focusNextTextField()->Bool
{
return self.TPKeyboardAvoiding_focusNextTextField()
}

@objc func scrollToActiveTextField()
{
return self.TPKeyboardAvoiding_scrollToActiveTextField()
}

override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
if newSuperview != nil {
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
super.touchesEnded(touches, with: event)
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if !self.focusNextTextField()
{
textField.resignFirstResponder()
}
return true
}

override func layoutSubviews() {
super.layoutSubviews()
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
}
}

private extension TPKeyboardAvoidingCollectionView
{
func setup()
{
NotificationCenter.default.addObserver(self,
selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
name: NSNotification.Name.UIKeyboardWillChangeFrame,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
name: NSNotification.Name.UIKeyboardWillHide,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(scrollToActiveTextField),
name: NSNotification.Name.UITextViewTextDidBeginEditing,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(scrollToActiveTextField),
name: NSNotification.Name.UITextFieldTextDidBeginEditing,
object: nil)
}
}

// MARK: - ScrollView
class TPKeyboardAvoidingScrollView:UIScrollView,UITextFieldDelegate,UITextViewDelegate
{
override var contentSize:CGSize{
didSet{
self.TPKeyboardAvoiding_updateFromContentSizeChange()
}
}


override var frame:CGRect{
didSet{
self.TPKeyboardAvoiding_updateContentInset()
}
}

override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}

override func awakeFromNib() {
setup()
}

func contentSizeToFit()
{
self.contentSize = self.TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames()
}

func focusNextTextField() ->Bool
{
return self.TPKeyboardAvoiding_focusNextTextField()
}

@objc func scrollToActiveTextField()
{
return self.TPKeyboardAvoiding_scrollToActiveTextField()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}

deinit{
NotificationCenter.default.removeObserver(self)
}

override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
if newSuperview != nil {
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
super.touchesEnded(touches, with: event)
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if !self.focusNextTextField()
{
textField.resignFirstResponder()
}
return true
}

override func layoutSubviews() {
super.layoutSubviews()
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
}
}

private extension TPKeyboardAvoidingScrollView
{
func setup()
{
NotificationCenter.default.addObserver(self,
selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
name: NSNotification.Name.UIKeyboardWillChangeFrame,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
name: NSNotification.Name.UIKeyboardWillHide,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(scrollToActiveTextField),
name: NSNotification.Name.UITextViewTextDidBeginEditing,
object: nil)

NotificationCenter.default.addObserver(self,
selector: #selector(scrollToActiveTextField),
name: NSNotification.Name.UITextFieldTextDidBeginEditing,
object: nil)
}
}

// MARK: - Process Event
let kCalculatedContentPadding:CGFloat = 10;
let kMinimumScrollOffsetPadding:CGFloat = 20;

extension UIScrollView
{
@objc func TPKeyboardAvoiding_keyboardWillShow(_ notification:Notification)
{
guard let userInfo = notification.userInfo else { return }
guard let rectNotification = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else
{
return
}

let keyboardRect = self.convert(rectNotification.cgRectValue , from: nil)
if keyboardRect.isEmpty
{
return
}

let state = self.keyboardAvoidingState()

guard let firstResponder = self.TPKeyboardAvoiding_findFirstResponderBeneathView(self) else { return}
state.keyboardRect = keyboardRect
if !state.keyboardVisible
{
state.priorInset = self.contentInset
state.priorScrollIndicatorInsets = self.scrollIndicatorInsets
state.priorPagingEnabled = self.isPagingEnabled
}

state.keyboardVisible = true
self.isPagingEnabled = false

if self is TPKeyboardAvoidingScrollView
{
state.priorContentSize = self.contentSize
if self.contentSize.equalTo(CGSize.zero)
{
self.contentSize = self.TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames()
}
}

let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Float ?? 0.0
let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int ?? 0
let options = UIViewAnimationOptions(rawValue: UInt(curve))

UIView.animate(withDuration: TimeInterval(duration),
delay: 0,
options: options,
animations: { [weak self]() -> Void in
if let actualSelf = self
{
actualSelf.contentInset = actualSelf.TPKeyboardAvoiding_contentInsetForKeyboard()
let viewableHeight = actualSelf.bounds.size.height - actualSelf.contentInset.top - actualSelf.contentInset.bottom
let point = CGPoint(x: actualSelf.contentOffset.x, y: actualSelf.TPKeyboardAvoiding_idealOffsetForView(firstResponder, viewAreaHeight: viewableHeight))
actualSelf.setContentOffset(point, animated: false)

actualSelf.scrollIndicatorInsets = actualSelf.contentInset
actualSelf.layoutIfNeeded()
}

}) { (finished) -> Void in

}
}

@objc func TPKeyboardAvoiding_keyboardWillHide(_ notification:Notification)
{
guard let userInfo = notification.userInfo else { return }

guard let rectNotification = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else
{
return
}
let keyboardRect = self.convert(rectNotification.cgRectValue , from: nil)
if keyboardRect.isEmpty
{
return
}
let state = self.keyboardAvoidingState()

if !state.keyboardVisible
{
return
}
state.keyboardRect = CGRect.zero
state.keyboardVisible = false

let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Float ?? 0.0
let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int ?? 0
let options = UIViewAnimationOptions(rawValue: UInt(curve))

UIView.animate(withDuration: TimeInterval(duration),
delay: 0,
options: options,
animations: { [weak self]() -> Void in
if let actualSelf = self
{
if actualSelf is TPKeyboardAvoidingScrollView {
actualSelf.contentSize = state.priorContentSize
actualSelf.contentInset = state.priorInset
actualSelf.scrollIndicatorInsets = state.priorScrollIndicatorInsets
actualSelf.isPagingEnabled = state.priorPagingEnabled
actualSelf.layoutIfNeeded()
}
}

}) { (finished) -> Void in

}
}

func TPKeyboardAvoiding_updateFromContentSizeChange()
{
let state = self.keyboardAvoidingState()
if state.keyboardVisible
{
state.priorContentSize = self.contentSize
}
}

func TPKeyboardAvoiding_focusNextTextField() ->Bool
{
guard let firstResponder = self.TPKeyboardAvoiding_findFirstResponderBeneathView(self) else { return false}
guard let view = self.TPKeyboardAvoiding_findNextInputViewAfterView(firstResponder, beneathView: self) else { return false}
Timer.scheduledTimer(timeInterval: 0.1, target: view, selector: #selector(becomeFirstResponder), userInfo: nil, repeats: false)

return true

}

func TPKeyboardAvoiding_scrollToActiveTextField()
{
let state = self.keyboardAvoidingState()

if !state.keyboardVisible { return }

let visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom

let idealOffset = CGPoint(x: 0,
y: self.TPKeyboardAvoiding_idealOffsetForView(self.TPKeyboardAvoiding_findFirstResponderBeneathView(self),
viewAreaHeight: visibleSpace))

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double((Int64)(0 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) {[weak self] () -> Void in
self?.setContentOffset(idealOffset, animated: true)
}
}

//Helper
func TPKeyboardAvoiding_findFirstResponderBeneathView(_ view:UIView) -> UIView?
{
for childView in view.subviews
{
if childView.responds(to: #selector(getter: isFirstResponder)) && childView.isFirstResponder
{
return childView
}
let result = TPKeyboardAvoiding_findFirstResponderBeneathView(childView)
if result != nil
{
return result
}
}
return nil
}

func TPKeyboardAvoiding_updateContentInset()
{
let state = self.keyboardAvoidingState()
if state.keyboardVisible
{
self.contentInset = self.TPKeyboardAvoiding_contentInsetForKeyboard()
}
}

func TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames() ->CGSize
{
let wasShowingVerticalScrollIndicator = self.showsVerticalScrollIndicator
let wasShowingHorizontalScrollIndicator = self.showsHorizontalScrollIndicator

self.showsVerticalScrollIndicator = false
self.showsHorizontalScrollIndicator = false

var rect = CGRect.zero

for view in self.subviews
{
rect = rect.union(view.frame)
}

rect.size.height += kCalculatedContentPadding
self.showsVerticalScrollIndicator = wasShowingVerticalScrollIndicator
self.showsHorizontalScrollIndicator = wasShowingHorizontalScrollIndicator

return rect.size
}

func TPKeyboardAvoiding_idealOffsetForView(_ view:UIView?,viewAreaHeight:CGFloat) -> CGFloat
{
let contentSize = self.contentSize

var offset:CGFloat = 0.0
let subviewRect = view != nil ? view!.convert(view!.bounds, to: self) : CGRect.zero

var padding = (viewAreaHeight - subviewRect.height)/2
if padding < kMinimumScrollOffsetPadding
{
padding = kMinimumScrollOffsetPadding
}

offset = subviewRect.origin.y - padding - self.contentInset.top

if offset > (contentSize.height - viewAreaHeight)
{
offset = contentSize.height - viewAreaHeight
}

if offset < -self.contentInset.top
{
offset = -self.contentInset.top
}

return offset
}

func TPKeyboardAvoiding_contentInsetForKeyboard() -> UIEdgeInsets
{
let state = self.keyboardAvoidingState()
var newInset = self.contentInset;

let keyboardRect = state.keyboardRect
newInset.bottom = keyboardRect.size.height - max(keyboardRect.maxY - self.bounds.maxY, 0)

return newInset

}

func TPKeyboardAvoiding_viewIsValidKeyViewCandidate(_ view:UIView)->Bool
{
if view.isHidden || !view.isUserInteractionEnabled {return false}

if view is UITextField
{
if (view as! UITextField).isEnabled {return true}
}

if view is UITextView
{
if (view as! UITextView).isEditable {return true}
}

return false
}

func TPKeyboardAvoiding_findNextInputViewAfterView(_ priorView:UIView,beneathView view:UIView, candidateView bestCandidate: inout UIView?)
{
let priorFrame = self.convert(priorView.frame, to: priorView.superview)
let candidateFrame = bestCandidate == nil ? CGRect.zero : self.convert(bestCandidate!.frame, to: bestCandidate!.superview)

var bestCandidateHeuristic = -sqrt(candidateFrame.origin.x*candidateFrame.origin.x + candidateFrame.origin.y*candidateFrame.origin.y) + ( Float(fabs(candidateFrame.minY - priorFrame.minY))<Float.ulpOfOne ? 1e6 : 0)

for childView in view.subviews
{
if TPKeyboardAvoiding_viewIsValidKeyViewCandidate(childView)
{
let frame = self.convert(childView.frame, to: view)
let heuristic = -sqrt(frame.origin.x*frame.origin.x + frame.origin.y*frame.origin.y)
+ (Float(fabs(frame.minY - priorFrame.minY)) < Float.ulpOfOne ? 1e6 : 0)

if childView != priorView && (Float(fabs(frame.minY - priorFrame.minY)) < Float.ulpOfOne
&& frame.minX > priorFrame.minX
|| frame.minY > priorFrame.minY)
&& (bestCandidate == nil || heuristic > bestCandidateHeuristic)
{
bestCandidate = childView
bestCandidateHeuristic = heuristic
}
}else
{
self.TPKeyboardAvoiding_findNextInputViewAfterView(priorView, beneathView: view, candidateView: &bestCandidate)
}
}
}

func TPKeyboardAvoiding_findNextInputViewAfterView(_ priorView:UIView,beneathView view:UIView) ->UIView?
{
var candidate:UIView?
self.TPKeyboardAvoiding_findNextInputViewAfterView(priorView, beneathView: view, candidateView: &candidate)
return candidate
}


@objc func TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_ obj: AnyObject)
{
func processWithView(_ view: UIView) {
for childView in view.subviews
{
if childView is UITextField || childView is UITextView
{
self.TPKeyboardAvoiding_initializeView(childView)
}else
{
self.TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(childView)
}
}
}

if let timer = obj as? Timer, let view = timer.userInfo as? UIView {
processWithView(view)
}
else if let view = obj as? UIView {
processWithView(view)
}
}

func TPKeyboardAvoiding_initializeView(_ view:UIView)
{
if let textField = view as? UITextField,
let delegate = self as? UITextFieldDelegate, textField.returnKeyType == UIReturnKeyType.default &&
textField.delegate !== delegate
{
textField.delegate = delegate
let otherView = self.TPKeyboardAvoiding_findNextInputViewAfterView(view, beneathView: self)
textField.returnKeyType = otherView != nil ? .next : .done

}
}

func keyboardAvoidingState()->TPKeyboardAvoidingState
{
var state = objc_getAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName) as? TPKeyboardAvoidingState
if state == nil
{
state = TPKeyboardAvoidingState()
self.state = state
}

return self.state!
}

}

// MARK: - Internal object observer
internal class TPKeyboardAvoidingState:NSObject
{
var priorInset = UIEdgeInsets.zero
var priorScrollIndicatorInsets = UIEdgeInsets.zero

var keyboardVisible = false
var keyboardRect = CGRect.zero
var priorContentSize = CGSize.zero

var priorPagingEnabled = false
}

internal extension UIScrollView
{
fileprivate struct AssociatedKeysKeyboard {
static var DescriptiveName = "KeyBoard_DescriptiveName"
}

var state:TPKeyboardAvoidingState?{
get{
let optionalObject:AnyObject? = objc_getAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName) as AnyObject?
if let object:AnyObject = optionalObject {
return object as? TPKeyboardAvoidingState
} else {
return nil
}
}
set{
objc_setAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}


[1]:

[To see links please register here]

Reply

#17
In Swift 4.0 -


func textFieldDidBeginEditing(_ textField: UITextField) {
animateViewMoving(up: true, moveValue: 100)
}

func textFieldDidEndEditing(_ textField: UITextField) {
animateViewMoving(up: false, moveValue: 100)
}
func animateViewMoving (up:Bool, moveValue :CGFloat){
let movementDuration:TimeInterval = 0.3
let movement:CGFloat = ( up ? -moveValue : moveValue)
UIView.beginAnimations( "animateView", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration )
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
}
Reply

#18
The best way is using NotificationCenter to catch keyboard actions. You can follow the steps in this short article

[To see links please register here]

Reply

#19
i am working with **swift 4** and i am solved this issue without use any extra bottom constraint look my code is here.its really working on my case

**1) Add Notification Observer in did load**

> override func viewDidLoad() {
> super.viewDidLoad()
> setupManager()
> // Do any additional setup after loading the view.
> NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
> NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
> }

**2) Remove Notification Observer like**

> deinit {
> NotificationCenter.default.removeObserver(self)
> }

**3) Add keyboard show/ hide methods like**



@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
UIView.animate(withDuration: 0.1, animations: { () -> Void in
self.view.frame.origin.y -= keyboardSize.height
self.view.layoutIfNeeded()
})
}
}

@objc func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
UIView.animate(withDuration: 0.1, animations: { () -> Void in
self.view.frame.origin.y += keyboardSize.height
self.view.layoutIfNeeded()
})
}
}

**4) Add textfeild delegate and add touchesBegan methods .usefull for hide the keyboard when touch outside the textfeild on screen**

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)

}
Reply

#20
The Swift 4 solution I use, takes in keyboard size. Replace `serverStatusStackView` with whatever view you care about, e.g.: `self.view`:

deinit {
NotificationCenter.default.removeObserver(self)
}

@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
serverStatusStackView.frame.origin.y = keyboardSize.height * 2 - serverStatusStackView.frame.height
}
}

@objc func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
serverStatusStackView.frame.origin.y += keyboardSize.height
}
}

override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through