A drop-in universal solution for moving text fields out of the way of the keyboard in iOS

Overview

TPKeyboardAvoiding

A drop-in universal solution for moving text fields out of the way of the keyboard in iOS.

Introduction

There are a hundred and one proposed solutions out there for how to move UITextField and UITextView out of the way of the keyboard during editing -- usually, it comes down to observing UIKeyboardWillShowNotification and UIKeyboardWillHideNotification, or implementing UITextFieldDelegate delegate methods, and adjusting the frame of the superview, or using UITableView's scrollToRowAtIndexPath:atScrollPosition:animated:, but most proposed solutions tend to be quite DIY, and have to be implemented for each view controller that needs it.

This is a relatively universal, drop-in solution: UIScrollView and UITableView subclasses that handle everything.

When the keyboard is about to appear, the subclass will find the subview that's about to be edited, and adjust its frame and content offset to make sure that view is visible, with an animation to match the keyboard pop-up. When the keyboard disappears, it restores its prior size.

It should work with basically any setup, either a UITableView-based interface, or one consisting of views placed manually.

It also automatically hooks up "Next" buttons on the keyboard to switch through the text fields.

Usage

For use with UITableViewController classes, drop TPKeyboardAvoidingTableView.m and TPKeyboardAvoidingTableView.h into your project, and make your UITableView a TPKeyboardAvoidingTableView in the xib. If you're not using a xib with your controller, I know of no easy way to make its UITableView a custom class: The path of least resistance is to create a xib for it.

For non-UITableViewControllers, drop the TPKeyboardAvoidingScrollView.m and TPKeyboardAvoidingScrollView.h source files into your project, pop a UIScrollView into your view controller's xib, set the scroll view's class to TPKeyboardAvoidingScrollView, and put all your controls within that scroll view. You can also create it programmatically, without using a xib - just use the TPKeyboardAvoidingScrollView as your top-level view.

To disable the automatic "Next" button functionality, change the UITextField's return key type to anything but UIReturnKeyDefault.

Notes

These classes currently adjust the contentInset parameter to avoid content moving beneath the keyboard. This is done, as opposed to adjusting the frame, in order to work around an iOS bug that results in a jerky animation where the view jumps upwards, before settling down. In order to facilitate this workaround, the contentSize is maintained to be at least same size as the view's frame.

Licence (Zlib)

Copyright (c) 2013 Michael Tyson

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.

  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

  3. This notice may not be removed or altered from any source distribution.


Michael Tyson, A Tasty Pixel
[email protected]

Comments
  • TPKeyboardAvoidingTableView stopped working on 1.2.5+

    TPKeyboardAvoidingTableView stopped working on 1.2.5+

    I've been using TPKeyboardAvoidingTableView for a long time, and ever since I upgraded the Podfile to version 1.2.5 or to 1.2.6 it stopped working - the keyboard is hiding the lower part of my table.

    When I downgraded the pod to version 1.2.4 it worked again, so for now I'm sticking with 1.2.4.

    opened by aviramuse 21
  • Crash when TPKeyboardAvoiding*View parent view is deallocated while scrolling.

    Crash when TPKeyboardAvoiding*View parent view is deallocated while scrolling.

    If you deallocate the parent view of any of the TPKeyboardAvoiding*View objects while it's scrolling, you will get a EXC_BAD_ACCESS crash. This is caused by the following code (which is copy-pasted to all the three implementations):

    -(void)layoutSubviews 
    // --snip--
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
    [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1];
    

    performSelect increases the retain count of self in this case and since scrolling a view causes layoutSubviews to be called it gets queued to the run loop. The problem is apparent when you deallocate the parent view during this 0.1s time slot.

    opened by anlaital 21
  • TPKeyboardAvoidingScrollView not working at all at version 1.2.2 via cocoapods

    TPKeyboardAvoidingScrollView not working at all at version 1.2.2 via cocoapods

    reverting to 1.2.1 solves the problem. I really don't know enough about the project to provide more details other than I tested this with a simple UIView containing a UIScrollView (set to TPKeyboardAvoidingScrollView) and a single UITextField at the bottom of the screen.

    Did not set the delegate, so it's running off of the notifications.

    Update: setting the delegate didn't help either.

    opened by chadkouse 17
  • Not restoring contentOffset?

    Not restoring contentOffset?

    Hi,

    I ran into an issue that after the keyboard were closed, the whole view were shifted upwards aprox 85px (in my particular case...).

    In closer inspection of the code, the TPKeyboardAvoiding_idealOffsetForView method would modify the contentOffset and it would never return to the previous (0,0) value after closing the keyboard.

    I solved it in the code by adding a priorContentOffset property in the TPKeyboardAvoidingState class, and setting and resetting it in sync with the other "prior properties".

    Being a total novice using git and not being sure that this IS a good solution in all cases, I've not committed this change. But I'd like someone with more knowledge to perhaps take a look at why this weren't done in the first place?

    opened by Janne-M 13
  • Advancing to Other Fields with the Next Keyboard Button Doesn't Work

    Advancing to Other Fields with the Next Keyboard Button Doesn't Work

    Great work on this!

    Just one issue I've found. The Readme states:

    "It also automatically hooks up 'Next' buttons on the keyboard to switch through the text fields."

    I added this to a UIScrollView that has fields in it, and I haven't been able to get this part to work. The scrollView adjustments with the keyboard work fine, but hitting Next on the fields doesn't do anything.

    Thanks!

    opened by cliftonlabrum 13
  • Improved algorithm for 'focusNextTextField'

    Improved algorithm for 'focusNextTextField'

    This algorithm will to more accurately select the next text field. This works with all cases. Preferring the next text field that is to the right, then below the priorTextField.

    This fixes cases such as this:

    ---------111111- ---------22222-- --333333333--

    Previously, text field 3 would be chosen as the next text field in this case. This new algorithm selects text field 2.

    opened by AnthonyMDev 12
  • After i've changed the textfield Height text becomes awkward.

    After i've changed the textfield Height text becomes awkward.

    After i've changed the textfield Height which added in TPKeyboardAvoidingScrollView, when the cursor ends editing, the text animates to the top and become awkward.please help me. Thanks. I applied to the demo project also, it becomes the same way.

    opened by AyeChanPyaeSone 8
  • Problem with animation on iOS 9.1

    Problem with animation on iOS 9.1

    On iOS 9.1 there is a bug with TPKeyboardAvoiding framework. Steps to reproduce:

    1. Open screen with any keyboard avoiding view, for example TPKeyboardAvoidingScrollView and two UITextField. Here is test project https://github.com/anton-plebanovich/TP-framework-iOS-9.1-bug
    2. Only working with empty field. Must be at least two fields on screen to reproduce. Press and type something in empty field.
    3. Press on other field and text in first field will animate from top-left corner to his position. Can be reproduced only once. Reenter screen to test again. Bug description: TPKeyboardAvoiding is animating constraints changes with [self layoutIfNeeded] command in UIScrollView+TPKeyboardAvoidingAdditions.m in TPKeyboardAvoiding_keyboardWillShow: and TPKeyboardAvoiding_keyboardWillHide: methods. This also animate UITextField inner changes for written steps. Possible hotfixes: For me removing [self layoutIfNeeded]; or replacing it with [self layoutSubviews]; was a solution.
    opened by anton-plebanovich 8
  • Skip disabled textFields

    Skip disabled textFields

    I disabled a few fields and I can not go to the next field by pressing return button. I solved the problem by editing the method : - (void)TPKeyboardAvoiding_findTextFieldAfterTextField:(UIView*)priorTextField beneathView:

    I add this code : UITextField * textField = (UITextField *)childView; if (!textField.enabled) continue;

    after this line : if ( childView.hidden ) continue;

    Is it possible to add it to your repository , or have another solution to this problems ?

    opened by valentyn-dymaretskyi 8
  • Avoid Xcode 12 warning -> move to iOS 9

    Avoid Xcode 12 warning -> move to iOS 9

    Updated to latest version

    pod 'TPKeyboardAvoiding'

    Usage Details

    • Language: Swift
    • Platform: iPhone
    • iOS Version: iOS 9 - 14

    Expected Behavior

    Xcode 12 build without warnings, proposal to move target to iOS 9

    Actual Behavior

    Xcode 12.x warning The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.

    Steps to Reproduce the Problem

    1. Use latest Xcode 12 or 12.0.1
    2. Use TPKeyboardAvoiding in a Swift project with target iOS 11
    opened by tbechtum 7
  • Fix for a scrolling bug when the first responder is a tall text input

    Fix for a scrolling bug when the first responder is a tall text input

    When the keyboard frame changes, TPKeyboardAvoiding attempts to center the first responder view in the visible space above the keyboard. This results in a jarring change in scroll position (see the "before" video below) in certain circumstances (for example: an auto-growing text view). I believe that a better approach is to, instead of centering the first responder view, center the cursor (when possible).

    This is slightly challenging because the cursor is not accurate for a UITextView first enters its editing state. Accordingly, you'll see in my change that I've delayed the initial contentOffset adjustment due to a changing keyboard frame until a future runloop. I'm not entirely happy with this approach because of the natural hand-wavy nature of delaying to future run-loops. In addition, I found that a simple dispatch_async() was not sufficient to ensure that the UITextView's actual cursor position is measured, so I was forced to resort to a dispatch_after(0.01 seconds), which is an even-less precise method of targeting a future run-loop in which the text view's cursor will be set. I'm hopeful the there exists a better method to deterministically target the correct run-loop that I haven't yet tried.

    For reference, I've added a tab to the example project to demonstrate a non-scrolling UITextView whose height is much larger than the

    Before my change: http://cl.ly/2Y3l0S3X001A/tall_text_view_demonstration_before.mov

    After my change: http://cl.ly/0p343Y2E0R2k/tall_text_view_demonstration_after.mov

    Warnings:

    • I've only tested this on iOS 9.
    • My testing, though thorough for my own limited use cases of the TPKeyboardAvoiding library, is by no means globally thorough.
    • This hasn't yet been used in production code.
    • I couldn't find a great way to integrate this into the sample project without creating another tab. And when I did so, I didn't have an icon for the tab that matched the existing icon set. Sorry!
    opened by sibljon 7
  • Getting crash on [TPKeyboardAvoidingCollectionView layoutSubviews]

    Getting crash on [TPKeyboardAvoidingCollectionView layoutSubviews]

    I am getting crash issue on the layoutSubviews method of class TPKeyboardAvoidingCollectionView. The app getting crash on iOS 14.* devices only. In other iOS version, this is working fine. Exactly here I can see the crash point from Crashlytics.

    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];

    opened by parasjoshicasting 0
  • Text frame

    Text frame "jumps" on resignFirstResponder when not using UIReturnKeyDefault

    This can be observed using the provided sample application and making the following changes to TPKAScrollViewController

    • Modify the returnKeyType and set the delegate for each UITextField
    textField.returnKeyType = UIReturnKeyDone;
    textField.delegate = self;
    
    • Implement -(BOOL)textFieldShouldReturn:(UITextField *)textField to dismiss keyboard
    -(BOOL)textFieldShouldReturn:(UITextField *)textField {
        [textField resignFirstResponder];
        return true;
    }
    

    Type in any field and click the Done button. The _UITextContentView frame jumps to the left briefly before returning to its original position. ezgif com-gif-maker

    This was introduced in build 1.2.4 by adding [self layoutIfNeeded] to -TPKeyboardAvoiding_keyboardWillShow: in commit f533c6c. I see that the issue this was intended to address was "Scrollview stuttering problem on content inset/offset change fixed." Removing this code fixes the text jumping when resigning first responder status, but what are the ramifications?

    opened by rholstad 0
  • Can't build architectures for versions pre iOS 12 with Carthage

    Can't build architectures for versions pre iOS 12 with Carthage

    The IPHONEOS_DEPLOYMENT_TARGET was raised to iOS 12 in latest version 1.3.5 https://github.com/michaeltyson/TPKeyboardAvoiding/commit/ef7a25b3002f94667eedcf804dcc994109caf126 and anyone supporting pre iOS 12 cannot build the framework since Carthage only builds architectures available for the configured deployment target and above. Can this be lowered back to at least iOS 10? I saw it was iOS 8 before. In my opinion this should be in sync with the podspec platform which is iOS 9 currently (s.platform = :ios, '9.0'). In case it matters I am supporting iOS 10 and cannot build arhitectures for it like armv7.

    opened by CochiorasBogdan 2
  • Issue: UITableviewcell textfield not scrolling or moving in Swift 5 Xcode 12.3

    Issue: UITableviewcell textfield not scrolling or moving in Swift 5 Xcode 12.3

    I added TPKeyboardAvoidingTableView to my UITableView but when I click on my textfield it not scrolling. Please help me with this!

    https://user-images.githubusercontent.com/26963737/106014970-05bcc780-60e4-11eb-9456-da69f8a624a8.mov

    opened by YogeshPateliOS 0
IHKeyboardAvoiding is an elegant solution for keeping any UIView visible when the keyboard is being shown - no UIScrollView required!

IHKeyboardAvoiding An elegant solution for keeping any UIView visible when the keyboard is being shown Requirements IHKeyboardAvoiding Version Objecti

Idle Hands Apps 1.4k Dec 14, 2022
iOS utility class allows you to access keyboard view and track keyboard animation.

YYKeyboardManager iOS utility class allows you to access keyboard view and track keyboard animation. (It was used by YYText) Compatibility iPhone / iP

null 480 Nov 17, 2022
Best way to dismiss Keyboard in a View Controller iOS (Swift)

Best way to dismiss Keyboard in a View Controller iOS (Swift) First way: Implement UITextFieldDelegate’s textFieldShouldReturn method and dismiss curr

null 0 Dec 18, 2021
⌨️A Combine-based way to observe and adjust for Keyboard notifications in SwiftUI

⌨️ Keyboard Observing A Combine-based solution for observing and avoiding the keyboard in SwiftUI. Table of Contents About Requirements Installation C

Nick Fox 440 Jan 5, 2023
Codeless manager to hide keyboard by tapping on views for iOS written in Swift

KeyboardHideManager KeyboardHideManager - codeless manager to hide keyboard by tapping on views for iOS written in Swift. Structure Features Requireme

Bondar Yaroslav 55 Oct 19, 2022
Swift UIKit keyboard manager for iOS apps.

Typist Typist is a small, drop-in Swift UIKit keyboard manager for iOS apps. It helps you manage keyboard's screen presence and behavior without notif

Toto Tvalavadze 1.1k Dec 10, 2022
KeyboardKit is a Swift library that helps you create custom keyboard extensions for iOS and ipadOS.

KeyboardKit is a Swift library that helps you create custom keyboard extensions for iOS and ipadOS.

KeyboardKit 900 Jan 9, 2023
Objective-C library for tracking keyboard in iOS apps.

NgKeyboardTracker Objective-c library for tracking keyboard in iOS apps. Adding to your project If you are using CocoaPods, add to your Podfile: pod '

Meiwin Fu 808 Nov 17, 2022
Emoji Keyboard SDK (iOS)

Makemoji SDK Makemoji is a free emoji keyboard for mobile apps. By installing our keyboard SDK every user of your app will instantly have access to ne

Makemoji 100 Nov 3, 2022
A Chinese keyboard for iOS that helps Chinese language learners remember tones.

ToneBoard ToneBoard is a Chinese keyboard for iOS that requires you to enter the correct tones while typing simplified Chinese with Pinyin. It is avai

Kevin Bell 7 Sep 27, 2022
SwiftyKeyboard: a full customized numeric keyboard for iOS

SwiftyKeyboard Overview SwiftyKeyboard is an iOS customized enhanced keyboard. T

SwiftyKit 2 Jun 30, 2022
Slidden is an open source, customizable, iOS 8 keyboard, written in Swift

Slidden is an open source, customizable, iOS 8 keyboard, written in Swift. iOS 8 brought us the ability to create fully customizable keyboards, but do

Daniel Brim 595 Jan 5, 2023
Emoji Keyboard for iOS

English | 中文 An easy to use Emoji keyboard for iOS. Has been rewritten with swift, the old Objective-C version on branch oc. Features Written in Swift

isaced 450 Dec 24, 2022
⌨️ Add user-customizable global keyboard shortcuts to your macOS app in minutes

This package lets you add support for user-customizable global keyboard shortcuts to your macOS app in minutes. It's fully sandbox and Mac App Store c

Sindre Sorhus 1.1k Dec 29, 2022
Suppress mouse & keyboard events on MacOSX. Baby-proof my Mac!

Suppress mouse & keyboard events on MacOSX Catches all events (mouse, keyboard, everything), and either consumes them (locked state) or passes them th

Albert Zeyer 6 Oct 21, 2022
QMK Agent is a macOS menubar application which sends commands to a QMK enabled keyboard

QMKagent QMK Agent is a macOS menubar application which sends commands to a QMK enabled keyboard Features System volume indicator using top row (Esc t

Mike Killewald 4 Apr 24, 2022
Showing / dismissing keyboard animation in simple UIViewController category.

RSKKeyboardAnimationObserver Easy way to handle iOS keyboard showing/dismissing. Introduction Working with iOS keyboard demands a lot of duplicated co

Ruslan Skorb 45 Jun 9, 2022
A simple keyboard to use with numbers and, optionally, a decimal point.

MMNumberKeyboard A simple keyboard to use with numbers and, optionally, a decimal point. Installation From CocoaPods CocoaPods is a dependency manager

Matías Martínez 957 Nov 17, 2022
For less complicated keyboard event handling.

KeyboardObserver For less complicated keyboard event handling. Features Less complicated keyboard event handling. Do not use Notification , but event

Morita Naoki 163 May 24, 2022