Swift make the keyboard adapt with the devices screen - swift

So I want to learn swift and I am making this simple chat application ... and I have some problems controlling the keyboard.
when the keyboard appears I want to push up the frame. If I wont do that I won't have access to my textfield. I found this two functions that are able to do that ... the problem is the devices screen aren't the same, and if i run the app on another device I have to change the size ...
For example if I use iPhon6 i will use a 220 and if I use a 5 it is necessary 150 ... if I remember right. The dimension doesn't matter, the thing it is that aren't the same...
I think it must be a way to easily control this future ... I'll appreciate any kind of help...
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}
//hide keyboard and get down the view
func keyboardWillHide(sender: NSNotification) {
self.view.frame.origin.y += 200
}
//show keyboard and get up the view
func keyboardWillShow(sender: NSNotification) {
self.view.frame.origin.y -= 200
}
//hide keyboard if you tap the screen
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
Thank you !

Add a ScrollView Try Below Code.
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var onTopScrollView: UIView!
var activeTextField: UITextField!
var keyboardHeight: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}
//hide keyboard and get down the view
func keyboardWillHide(sender: NSNotification) {
keyboardHeight = 0
self.activeTextField = nil
let contentInsets = UIEdgeInsetsZero
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
scrollView.contentOffset = CGPointMake(0, 0)
}
//show keyboard and get up the view
func keyboardWillShow(sender: NSNotification) {
let info : NSDictionary = sender.userInfo!
let kbSize = (info.objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue() as CGRect!).size
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
keyboardHeight = kbSize.height
println(keyboardHeight)
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
var aRect = self.onTopScrollView.frame
aRect.size.height -= keyboardHeight;
if (!CGRectContainsPoint(aRect, self.activeTextField.frame.origin) ) {
var rect = onTopScrollView.convertRect(CGRectZero, fromView: self.activeTextField)
rect.size = self.activeTextField.frame.size
//print(CGRectContainsPoint(aRect, self.activeTextField.frame.origin))
self.scrollView.scrollRectToVisible(rect, animated: true)
}
}
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
super.viewWillDisappear(animated)
}
// handle TextField Delegates
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidBeginEditing(textField: UITextField) {
self.activeTextField = textField
}

Related

Move view using Scroll View to prevent keyboard from obscuring text field or text view

I am implementing an app where tapping a button will pop up a location entry screen which is implemented with Modally presented Segue and Visual Effect with Blur to make the entry window appear hovering above the main screen.
The pop up screen has a text field for location name and a multi line text view for remarks.
Problem is the multi line text view is partially obscured by the keyboard on smaller devices and in landscape view.
Landscape View
Portrait View
Modal Segue View
I tried to utiize the solution described here, which is supposed to utilize scroll view to shift the view when keyboard appears, but it doesn't seem to work for my project: Move a view up only when the keyboard covers an input field
This question doesn't answer my problem as my text field and view are inside another view to make it appear like a popup to the main screen: Move a view up only when the keyboard covers an input field
In order to implement the pop up view (in a modal segue) I placed the text field and view inside a View which is placed inside a Scroll View which is located inside the view of the Visual Effects with Blur View.
Another problem I'm experiencing is I impleneted the following code to dismiss keyboard when tapping outside the text field/view, but for some reason it doesn't seem to work
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
self.view.endEditing(true)
}
Here is the code for the View Controller of the pop up view in Xcode 9.2
Archive of the project: Xcode Project Archive
//
// LocationEntryScrollViewController.swift
//
import UIKit
class LocationEntryScrollViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate {
#IBOutlet weak var ScrollView: UIScrollView!
#IBOutlet weak var LocationEntryView: UIView!
#IBOutlet weak var LocationTextField: UITextField!
#IBOutlet weak var RemarksTextView: UITextView!
var activeTextField: UITextField?
var activeTextView: UITextView?
override func viewDidLoad()
{
super.viewDidLoad()
registerForKeyboardNotifications()
LocationEntryView.layer.cornerRadius = 10
LocationEntryView.layer.masksToBounds = true
LocationTextField.delegate = self // dismiss keyboard when tapped outside keyboard
RemarksTextView.delegate = self // dismiss keyboard when tapped outside keyboard
}
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
LocationTextField.becomeFirstResponder()
RemarksTextView.becomeFirstResponder()
}
/**
* Called when the user click on the view (outside the UITextField).
*/
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
self.view.endEditing(true)
}
override func viewDidDisappear(_ animated: Bool)
{
deregisterFromKeyboardNotifications()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func DoneButtonTapped(_ sender: Any)
{
dismiss(animated: true, completion: nil)
}
#IBAction func CancelButtonTapped(_ sender: Any)
{
}
#objc func keyboardWasShown(notification: NSNotification)
{
//Need to calculate keyboard exact size due to Apple suggestions
self.ScrollView.isScrollEnabled = true
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.ScrollView.contentInset = contentInsets
self.ScrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeTextField = self.activeTextField
{
if (!aRect.contains(activeTextField.frame.origin))
{
self.ScrollView.scrollRectToVisible(activeTextField.frame, animated: true)
}
}
if let activeTextView = self.activeTextView
{
if (!aRect.contains(activeTextView.frame.origin))
{
self.ScrollView.scrollRectToVisible(activeTextView.frame, animated: true)
}
}
}
#objc func keyboardWillBeHidden(notification: NSNotification)
{
//Once keyboard disappears, restore original positions
let info : NSDictionary = notification.userInfo! as NSDictionary
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
self.ScrollView.contentInset = contentInsets
self.ScrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
self.ScrollView.isScrollEnabled = false
}
func textFieldDidBeginEditing(_ textField: UITextField)
{
activeTextField = textField
}
func textFieldDidEndEditing(_ textField: UITextField)
{
activeTextField = nil
}
func textViewDidBeginEditing(_ textView: UITextView)
{
activeTextView = textView
}
func textViewDidEndEditing(_ textView: UITextView) {
activeTextView = nil
}
func registerForKeyboardNotifications()
{
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func deregisterFromKeyboardNotifications()
{
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
}

move UITextField up when keyboard present

I have recently started to develop my own app following the instructions on internet. I am just a beginner (with no knowledge of coding) and hence may be doing very stupid mistake that I am not able to catch.
In my app I am facing a situation where my email text field is hiding behind the keyboard whenever I try to type email address. I did some research (on stack overflow) and wrote a piece of code that suppose to move my text field up but it is not ... I believe overall structure of code is right (I may be wrong here though) but it may be just tiny mistake that making my code ineffective.
can anyone guide me on what I am doing wrong here?
below is the piece of code I wrote:
{
import UIKit
import WebKit
import CoreGraphics
import AVFoundation
import QuartzCore
import Foundation
class StudentSignUpViewController: UIViewController,UIScrollViewDelegate, UITextFieldDelegate {
#IBOutlet weak var yourEmail: UITextField!
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
//setting portrait
AppUtility.lockOrientation(.portrait)
//hide keyboard when click outside
self.hideKeyboardWhenTappedAround()
//hide keyboard when click on return
self.yourEmail.delegate = self
self.scrollView.delegate = self
//boarder line for yourEmail
yourEmail.frame.size.height = UIScreen.main.fixedCoordinateSpace.bounds.size.width * CGFloat(0.05)
yourEmail.font = UIFont.italicSystemFont(ofSize: UIScreen.main.fixedCoordinateSpace.bounds.size.width * CGFloat(0.04))
bottomBoader(BottomLine: "UrEmailTextBottomLine", length: 1.0, yourTextBox: yourEmail)
yourEmail.applyCustomClearButton(yourTextBox: yourEmail)
registerForKeyboardNotifications()
deregisterFromKeyboardNotifications()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
AppUtility.lockOrientation(.portrait)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
AppUtility.lockOrientation(.all)
}
// *************************************************** moving textfiles when keyborad present ***********************************************************
func registerForKeyboardNotifications(){
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func deregisterFromKeyboardNotifications(){
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
#objc func keyboardWasShown(notification: NSNotification){
//Need to calculate keyboard exact size due to Apple suggestions
self.scrollView.isScrollEnabled = true
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeField = self.yourEmail {
if (!aRect.contains(activeField.frame.origin)){
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
}
}
#objc func keyboardWillBeHidden(notification: NSNotification){
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
self.scrollView.isScrollEnabled = false
//self.scrollView.contentInset = UIEdgeInsets.zero
}
func textFieldDidBeginEditing( textField: UITextField){
yourEmail = textField
}
func textFieldDidEndEditing(textField: UITextField){
yourEmail = nil
}
The problem is you are registerForKeyboardNotifications() and then immediately deregisterFromKeyboardNotifications() so you aren't getting keyboard notifications. You should move the deregister to the deinit:
deinit {
deregisterFromKeyboardNotifications()
}
Edit
As #matt pointed out you don't need to deregisterFromKeyboardNotifications so just delete that code (including my suggestion of deinit)
Embedding your controls in a UITableView with static cells on a Storyboard will let the system take care of the scrolling for you.
hey bro why are call both the functions in viewDidLoad
registerForKeyboardNotifications()
deregisterFromKeyboardNotifications()
In viewDidLoad call only registerForKeyboardNotifications() and in deinit call deregisterFromKeyboardNotifications()
final solution that is working fine, I have copied it from stack overflow and tweak it little bit for my purpose:
var activeField: UITextField?
func registerForKeyboardNotifications(){
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
#objc func keyboardWasShown(notification: NSNotification){
//Need to calculate keyboard exact size due to Apple suggestions
self.scrollView.isScrollEnabled = true
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeField = self.activeField {
if activeField.frame.maxY > (scrollView.frame.height - keyboardSize!.height){
self.scrollView.setContentOffset(CGPoint.init(x: 0, y: activeField.frame.maxY - (scrollView.frame.height - keyboardSize!.height) + 20), animated: true)
} else {
return
}
print(activeField.frame.maxY)
print(scrollView.frame.height)
print(keyboardSize!.height)
print(scrollView.frame.height - keyboardSize!.height)
print(activeField.frame.maxY - (scrollView.frame.height - keyboardSize!.height) + 20)
}
}
#objc func keyboardWillBeHidden(notification: NSNotification){
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
self.scrollView.isScrollEnabled = false
}
func textFieldDidBeginEditing(_ textField: UITextField){
activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField){
activeField = nil
}

Swift Scroll to UITextField via UiscrollView only acts first time bug

im posting my full code here. the problem is when initially loading the app and the viewcontroller. it fully works. tap on the two textfields and the scrollview pushes up and keyboard is below the current textfield. but then if tapping out of the text field.. moving the the view up and retaping on the textfield it doesnt do it anymore. Also, if going back via nav controller and then loading again this viewcontroller, it wont do anything. it doesnt scroll anymore..( doesnt push the textfield up and keyboard goes below it anymore ) ...
import UIKit
import Parse
import Alamofire
import SwiftyJSON
class VCreservacion: UIViewController,UITextFieldDelegate,UIScrollViewDelegate {
var SUCURSALID = 0
var EMP_NOMBRE = ""
var DIRECCION = ""
var PROVINCIA = ""
var RESTID = 20556
#IBOutlet var lbl_empresa: UILabel!
#IBOutlet var lbl_direccion: UILabel!
#IBOutlet var lbl_step: UILabel!
#IBOutlet var cantidadView: UIView!
#IBOutlet var datePicker: UIDatePicker!
#IBOutlet var btn_reservar: UIButton!
#IBOutlet var stackView: UIStackView!
#IBOutlet var scrollView: UIScrollView!
#IBOutlet var txtComentario: UITextField!
#IBOutlet weak var txtCelular: UITextField!
var activeField: UITextField?
var steps = 2
// MARK: RESERVE ACTION
#IBAction func ReserveAction(_ sender: UIButton) {
print("Reservando...")
// For date formater
var dateformated = ""
var dateformated2 = ""
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
//formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) as TimeZone!
dateformated = formatter.string(from: datePicker.clampedDate)
dateformated2 = formatter.string(from: datePicker.date)
print(dateformated)
print(dateformated2)
let cart = Cart.sharedInstance
guard let user = PFUser.current() else {
cart.showAlertView("Login", message: "Debes estar logeado para poder reservar.")
return
}
Alamofire.request("URL String", parameters: ["qty": "\(steps)","sucursalid":"\(self.SUCURSALID)","restid":"\(RESTID)","comment":"\(txtComentario.text!)","phone":"\(txtCelular.text!)","datetime":"\(dateformated)","action":"request","userid":"\(user.objectId!)"]).authenticate(usingCredential: cart.credential).responseJSON() {
response in
if (response.error != nil ) {
print(response.error.debugDescription)
print(response.request)
cart.showAlertView("Error", message: "there was an error.")
}
if(response.result.value != nil) {
let json = JSON(response.result.value!);
print(json);
let success:Bool = json["success"].boolValue
let error: Bool = json["error"].boolValue
if(success) {
print("con exito")
let alert = UIAlertController(title: "Reserva Enviada", message: "Tu reserva ha sido enviada y serĂ¡ revisada por el establecimiento", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
UIAlertAction in
// Get the previous Controller.
let targetController: UIViewController = (self.navigationController?.viewControllers[self.navigationController!.viewControllers.count - 3])!
// And go to that Controller
self.navigationController?.popToViewController(targetController, animated: true)
}
alert.addAction(okAction)
self.present(alert,animated:true)
}
}
}
}
#IBAction func stepperValue(_ sender: UIStepper) {
self.lbl_step.text = Int(sender.value).description
steps = Int(sender.value)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
registerForKeyboardNotifications()
self.scrollView.delegate = self
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
deregisterFromKeyboardNotifications()
self.scrollView.delegate = nil
}
// MARK: Viewdidload
override func viewDidLoad() {
super.viewDidLoad()
// enable scroll on scrollview
self.scrollView.isScrollEnabled = true
// step label initial value 2
self.lbl_step.text = "2"
// Get celular or phone
if ( Cart.sharedInstance.User_celular != "") {
txtCelular.text = Cart.sharedInstance.User_celular
} else {
txtCelular.text = Cart.sharedInstance.User_phone
}
let nearesthour = Date().nearestHour()
self.datePicker.minimumDate = nearesthour
self.txtComentario.delegate = self
self.txtCelular.delegate = self
self.txtCelular.tag = 20
self.scrollView.delegate = self
// tap gesture recognizer
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
self.scrollView.addGestureRecognizer(tap)
print("el enarest hour es \(nearesthour as Date?) y el date normal es \(Date())")
self.btn_reservar.layer.cornerRadius = 10
self.cantidadView.layer.cornerRadius = 10
self.lbl_empresa.text = EMP_NOMBRE
self.lbl_direccion.text = DIRECCION
/*
print("VC Reservacion")
print("SUCURSAL \(SUCURSALID) ")
print("EMP NOMBRE " + EMP_NOMBRE)
print("DIRECCION " + DIRECCION)
*/
}
// MARK: TEXTFIELD STUFF
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
self.activeField = textField
return true
}
/*
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
*/
func textFieldDidEndEditing(_ textField: UITextField) {
activeField = nil
}
func registerForKeyboardNotifications(){
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func deregisterFromKeyboardNotifications(){
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
#objc func keyboardWasShown(notification: NSNotification){
//Need to calculate keyboard exact size due to Apple suggestions
print(" Keyboaard shown")
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
print(" el keyboardsize is \(keyboardSize)")
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height + 80, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
print("VIEW COMPLETE FRAME IS \(aRect)")
print("KEYBOARD FRAME HEIGHT \(keyboardSize!.height)")
aRect.size.height -= keyboardSize!.height
print("FRAME MENOS KEYBOARD ES \(aRect)")
print("SCROLLVIEW CONTENT \(self.scrollView.contentSize)")
if let activeField = self.activeField {
print("ACTIVEFIELD FRAME ORIGIN \(activeField.frame.origin) ")
print("Active field is textfield tag is \(activeField.tag)")
// if (!aRect.contains(activeField.frame.origin)){
print("arect Does Not contains activeField")
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
print("TEXTFIELD FRAME ES \(activeField.frame)")
print(" SCROLLVIEW CONTENT \(self.scrollView.contentSize)")
//}
}
}
#objc func keyboardWillBeHidden(notification: NSNotification){
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.activeField = nil
self.view.endEditing(true)
self.scrollView.isScrollEnabled = false
}
#objc func handleTap(_ sender: UITapGestureRecognizer) {
self.view.endEditing(true)
print("Tap")
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return false
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSize(width: view.frame.width, height: view.frame.height)
print(" SCROLLVIEW CONTENT AFTER SUBVIEWS \(self.scrollView.contentSize)")
}
/* // NOT WORKING BECAUSE OF UISCROLLVIEW IN PLACE, MUST USE UITAPGESTURE RECOGNIZER
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
self.activeField?.resignFirstResponder()
}
*/
}
I had the same problem. Apparently there is a change in getting the size of the keyboard. I changed UIKeyboardFrameBeginUserInfoKey to UIKeyboardFrameEndUserInfoKey and got it to work again.
Here is my exact code for moving the view when the textfield is pressed
#objc func keyboardWasShown(notification: NSNotification){
self.scrollView.isScrollEnabled = true
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
guard let kbHeight = keyboardSize?.height else{return}
aRect.size.height -= kbHeight
if let activeField = self.activeTextField {
if (!aRect.contains(activeField.frame.origin)){
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
}
}

Moving content behind keyboard doesn't work, Swift

In view controller I have UIImageView and multiple uitextfields. I'm using the following code, based on Apple documentation, to move the scrollView up when a keyboard notification is called, to push up the hidden text fields. However the when the keyboard appears the view does move up.
Am I missing something here?
class NewViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var scrollView: UIScrollView!
var activeTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
scrollView.contentSize.height = 1000
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func registerForKeyboardNotifications() {
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: "keyboardWillBeShown:", name: UIKeyboardWillShowNotification, object: nil)
notificationCenter.addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWillBeShown(sender: NSNotification) {
let info: NSDictionary = sender.userInfo!
let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as! NSValue
let keyboardSize: CGSize = value.CGRectValue().size
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(self.scrollView.contentInset.top, 0.0, keyboardSize.height, 0.0)
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardSize.height
print(aRect)
let activeTextFieldRect: CGRect? = activeTextField?.frame
let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.origin
if (!CGRectContainsPoint(aRect, activeTextFieldOrigin!)) {
scrollView.scrollRectToVisible(activeTextFieldRect!, animated:true)
}
}
func keyboardWillBeHidden(sender: NSNotification) {
let contentInsets: UIEdgeInsets = UIEdgeInsetsZero
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
}
func textFieldDidBeginEditing(textField: UITextField) {
activeTextField = textField
}
func textFieldDidEndEditing(textField: UITextField) {
activeTextField = nil
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.registerForKeyboardNotifications()
}
override func viewDidDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Try this code and set "moveValue" for your situation.
Remember to extends UITextFieldDelegate
func textFieldDidBeginEditing(textField: UITextField)
{
self.animateViewMoving(true, moveValue: 85)
}
func textFieldDidEndEditing(textField: UITextField)
{
self.animateViewMoving(false, moveValue: 85)
}
func animateViewMoving (up:Bool, moveValue :CGFloat)
{
let durataMovimento:NSTimeInterval = 0.3
let movimento:CGFloat = ( up ? -moveValue : moveValue)
UIView.beginAnimations( "animateView", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(durataMovimento )
self.view.frame = CGRectOffset(self.view.frame, 0, movimento)
UIView.commitAnimations()
}

keyboard is hiding UITextField in swift

i have a UITextField added by code, and when the keyboard is opened, it hides the textfield.
i searched a lot and got the same results and her is my code as apple documentation suggest, but still it is not working!
import Foundation
import UIKit
class testkey: UIViewController, UITextFieldDelegate {
var txt1: UITextField! = nil
var scrollView: UIScrollView! = nil
var activeTextField: UITextField!
override func viewDidLoad() {
txt1 = UITextField(frame: CGRect(x: 0, y:250, width: 223, height: 30))
txt1.text = "text"
txt1.borderStyle = UITextBorderStyle.RoundedRect
txt1.delegate = self
scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 225.00, height: 290));
scrollView.addSubview(txt1)
self.view.addSubview(scrollView)
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// Call this method somewhere in your view controller setup code.
func registerForKeyboardNotifications() {
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self,
selector: "keyboardWillBeShown:",
name: UIKeyboardWillShowNotification,
object: nil)
notificationCenter.addObserver(self,
selector: "keyboardWillBeHidden:",
name: UIKeyboardWillHideNotification,
object: nil)
}
// Called when the UIKeyboardDidShowNotification is sent.
func keyboardWillBeShown(sender: NSNotification) {
let info: NSDictionary = sender.userInfo!
let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as NSValue
let keyboardSize: CGSize = value.CGRectValue().size
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0)
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardSize.height
let activeTextFieldRect: CGRect? = activeTextField?.frame
let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.origin
if (!CGRectContainsPoint(aRect, activeTextFieldOrigin!)) {
scrollView.scrollRectToVisible(activeTextFieldRect!, animated:true)
}
}
// Called when the UIKeyboardWillHideNotification is sent
func keyboardWillBeHidden(sender: NSNotification) {
let contentInsets: UIEdgeInsets = UIEdgeInsetsZero
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
}
func textFieldDidBeginEditing(textField: UITextField!) {
activeTextField = textField
scrollView.scrollEnabled = true
}
func textFieldDidEndEditing(textField: UITextField!) {
activeTextField = nil
scrollView.scrollEnabled = false
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.registerForKeyboardNotifications()
}
override func viewDidDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore.
{
textField.resignFirstResponder()
return true;
}
}
(Assuming the maths are correct) what you should use is UIKeyboardFrameEndUserInfoKey instead of UIKeyboardFrameBeginUserInfoKey.
Please check the Documentation of Keyboard Notification User Info Keys
i found the missing part,
the following should be changed for the scroll view:
scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height));
scrollView.contentSize = self.view.frame.size;