I have a view controller which contains a full-screen UITextView
. When the keyboard is shown I would like to resize the text view so that it is not hidden under
I read the docs which talk about this very topic. I translated it into Swift and it worked absolutely beautifully for me.
This is used for a full page UITextView like iMessage.
I am using iOS 8.2 and Swift on XCode 6.2 and here's my code. Just call this setupKeyboardNotifications
from your viewDidLoad
or other initialization method.
func setupKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWasShown:"), name: UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillBeHidden:"), name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWasShown(aNotification:NSNotification) {
let info = aNotification.userInfo
let infoNSValue = info![UIKeyboardFrameBeginUserInfoKey] as NSValue
let kbSize = infoNSValue.CGRectValue().size
let contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0)
codeTextView.contentInset = contentInsets
codeTextView.scrollIndicatorInsets = contentInsets
}
func keyboardWillBeHidden(aNotification:NSNotification) {
let contentInsets = UIEdgeInsetsZero
codeTextView.contentInset = contentInsets
codeTextView.scrollIndicatorInsets = contentInsets
}
Also if you are having issues with the caret being in the right place when rotated check for the orientation change and scroll to the right position.
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
scrollToCaretInTextView(codeTextView, animated: true)
}
func scrollToCaretInTextView(textView:UITextView, animated:Bool) {
var rect = textView.caretRectForPosition(textView.selectedTextRange?.end)
rect.size.height += textView.textContainerInset.bottom
textView.scrollRectToVisible(rect, animated: animated)
}
Swift 3:
func configureKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(aNotification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(aNotification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWasShown(aNotification:NSNotification) {
let info = aNotification.userInfo
let infoNSValue = info![UIKeyboardFrameBeginUserInfoKey] as! NSValue
let kbSize = infoNSValue.cgRectValue.size
let contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0)
textView.contentInset = contentInsets
textView.scrollIndicatorInsets = contentInsets
}
func keyboardWillBeHidden(aNotification:NSNotification) {
let contentInsets = UIEdgeInsets.zero
textView.contentInset = contentInsets
textView.scrollIndicatorInsets = contentInsets
}
Swift 4 & 5:
func setupKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_ :)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(_ notification:NSNotification) {
let d = notification.userInfo!
var r = (d[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
r = self.textView.convert(r, from:nil)
self.textView.contentInset.bottom = r.size.height
self.textView.verticalScrollIndicatorInsets.bottom = r.size.height
}
@objc func keyboardWillHide(_ notification:NSNotification) {
let contentInsets = UIEdgeInsets.zero
self.textView.contentInset = contentInsets
self.textView.verticalScrollIndicatorInsets = contentInsets
}
Following on is working for me :
.h file
@interface ViewController : UIViewController <UITextViewDelegate> {
UITextView *textView ;
}
@property(nonatomic,strong)IBOutlet UITextView *textView;
@end
.m file
@implementation ViewController
@synthesize textView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect textViewFrame = CGRectMake(20.0f, 20.0f, 280.0f, 424.0f);
//UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame];
textView.frame = textViewFrame;
textView.delegate = self;
textView.returnKeyType = UIReturnKeyDone;
textView.backgroundColor = [UIColor greenColor];
textView.textColor = [UIColor blackColor];
[self.view addSubview:textView];
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
NSLog(@"textViewShouldBeginEditing:");
return YES;
}
- (void)textViewDidBeginEditing:(UITextView *)textView1 {
NSLog(@"textViewDidBeginEditing:");
CGRect textViewFrame = CGRectMake(20.0f, 20.0f, 280.0f, 224.0f);
textView1.frame = textViewFrame;
}
- (BOOL)textViewShouldEndEditing:(UITextView *)textView{
NSLog(@"textViewShouldEndEditing:");
return YES;
}
- (void)textViewDidEndEditing:(UITextView *)textView{
NSLog(@"textViewDidEndEditing:");
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
return YES;
}
- (void)textViewDidChange:(UITextView *)textView{
NSLog(@"textViewDidChange:");
}
- (void)textViewDidChangeSelection:(UITextView *)textView{
NSLog(@"textViewDidChangeSelection:");
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"touchesBegan:withEvent:");
CGRect textViewFrame = CGRectMake(20.0f, 20.0f, 280.0f, 424.0f);
textView.frame = textViewFrame;
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
@end