This is my whole code when keyboard appears it hides the top 1 textfield and one is half visible. It works but when it hiddes the top fields it looks to wired.
I found this code on net but i can't able to fix it.
class ViewController2: UIViewController, ENSideMenuDelegate, UITextFieldDelegate {
#IBOutlet weak var text1: UITextField!
#IBOutlet weak var text2: UITextField!
#IBOutlet weak var text3: UITextField!
#IBOutlet weak var text4: UITextField!
#IBOutlet weak var scrollview: UIScrollView!
var activeTextField: UITextField!
#IBOutlet weak var container_view: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//Move next line to viewWillAppear functon if you store your view controllers
self.sideMenuController()?.sideMenu?.delegate = self
// Do any additional setup after loading the view.
self.text1.delegate = self
self.text2.delegate = self
self.text3.delegate = self
self.text4.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - ENSideMenu Delegate
func sideMenuWillOpen() {
println("sideMenuWillOpen")
}
func sideMenuWillClose() {
println("sideMenuWillClose")
}
func sideMenuDidClose() {
println("sideMenuDidClose")
}
func sideMenuDidOpen() {
println("sideMenuDidOpen")
}
/*
func sideMenuShouldOpenSideMenu() -> Bool {
println("sideMenuShouldOpenSideMenu")
return false
}
*/
// MARK: - Keyboard
// 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)
}
func unregisterFromKeyboardNotifications () {
let center: NSNotificationCenter = NSNotificationCenter.defaultCenter()
center.removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
center.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
private func stopObservingKeyboardEvents() {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, 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 + 80
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
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.registerForKeyboardNotifications()
}
override func viewDidDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
// MARK: - Text Field
func textFieldDidBeginEditing(textField: UITextField) {
self.activeTextField = textField
}
func textFieldDidEndEditing(textField: UITextField) {
self.activeTextField = nil
}
}
Instead of doing this
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardSize.height + 80
do this
self.view.frame.y -= keyboardSize.height + 80
(not sure what the 80 is, but I'm keeping it there in case it is accounting for something on your app.)
the .height property will stretch your frame while the .y property will move it.
Related
I'm having a weird behavior from a keyboard. But only on one of the view controllers. I have another view controller with a UITextField and that one works charms (as soon as I press the return button it disappears). And the weird part is that that one isnt even setup at all. it only has becomefirstresponder on viewdidload and resignfirstresponder on viewwilldissapear.
THIS keyboard however, VIDEO OF NASTY KEYBOARD is quite the nasty booger.
NOTE: In the video I do the following:
* Tap the UITextfield
* Keyboard Appears (view shifts up)
* I type lol and then press send (nothing happens)
* I start tapping frantically all around the screen (except the UITextField)
* Keyboard dissapears
Here's the code for this View:
class ChatScreenVC: UIViewController, UITextFieldDelegate {
var gameDelegate: GameManagerDelegate?
var chatLogString: String = ""
var offsetY:CGFloat = 0
#IBOutlet weak var chatView: UIView!
#IBOutlet weak var closeBtn: UIButton!
#IBOutlet weak var titleBtn: UILabel!
#IBOutlet weak var chatLog: UITextView!
#IBOutlet weak var chatInput: UITextField!
#IBOutlet weak var sendBtn: UIButton!
#IBOutlet weak var viewCenterConstraint: NSLayoutConstraint!
#IBAction func inputTapped(_ sender: Any) {
chatInput.becomeFirstResponder()
}
#IBAction func closeTapped(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
#IBAction func sendTapped(_ sender: Any) {
if chatInput.text != nil && chatInput.text != "" && chatInput.text != " " {
gameDelegate?.sendChat(message: chatInput.text!)
}
chatInput.text = ""
chatInput.resignFirstResponder()
self.view.endEditing(true)
}
#objc func keyboardWillShow(_ notification: Notification) {
if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
viewCenterConstraint.constant = -keyboardHeight
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("THIS IS HAPPENING!")
chatInput.resignFirstResponder()
self.view.endEditing(true)
return true
}
#objc func keyboardWillHide(_ notification: Notification) {
if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
viewCenterConstraint.constant = 0
}
}
#objc func reloadData() {
chatLogString = (gameDelegate?.updateChatString())!
chatLog.text = chatLogString
}
override func viewDidLoad() {
super.viewDidLoad()
chatLog.text = chatLogString
chatLog.isEditable = false
chatInput.autocorrectionType = .no
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
setupView()
animateView()
}
override func viewWillDisappear(_ animated: Bool) {
chatInput.resignFirstResponder()
}
override func viewDidAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(self.reloadData), name: Notification.Name(rawValue: SMACK_TALK), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewDidDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: SMACK_TALK), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}
}
Now before you go and tell me "not to use both the resignfirstresponder and the endediting(true)" I gotta clear out that I tried both individually and together and still don't get any response.
You can resign keyboard before sendChat(). I think it is sync call and it will block main thread for sometimes thats why this weird behaviour occurs.
chatInput.resignFirstResponder() before you are making API call.
#IBAction func sendTapped(_ sender: Any) {
if chatInput.text != nil && chatInput.text != "" && chatInput.text != " " {
chatInput.resignFirstResponder()
self.view.endEditing(true)
gameDelegate?.sendChat(message: chatInput.text!)
}
}
There are several TextFields in a UIView.I want move view up when user edit TextField.And then i try it reference Move view with keyboard using Swift
My core code is below:
//MARK: Properties
#IBOutlet weak var userAccountTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
#IBOutlet weak var confirmPasswordTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var phoneTextField: UITextField!
//MARK: Callback
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
if self.view.frame.origin.y == 0{
//self.view.frame.origin.y -= keyboardSize.height
self.view.frame.origin.y -= 150
}
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
if self.view.frame.origin.y != 0{
//self.view.frame.origin.y += keyboardSize.height
self.view.frame.origin.y += 150
}
}
}
There are two issues:
1.The keyboardSize.height with hide the keyboard is bigger than keyboardSize.height with show the keyboard.Then there will be a black field top after the keyboard hide. So now i must use a constant number.
2.The view move up after the keyboard show, it's good.But the view move down again when i type some chars or i click other TextFiled.It's good If i put these TextFields into a ScrollView.But i don't it's why.Like below picture:
enter image description here
Any help would be greatly appreciated.
Your “viewDidLoad” method contains an error, you have to add and not to remove the observer, you have to remove it in “viewWillDisappear”
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
I have a loginView, inside that i have two textFields and a button. I have to move up the view while tapping on textField and move down the view when press the return key.
My problem is that it is working fine for all conditions but while tap on the one textField view is moving up but at same time when we go for next textField view is moving down.
import UIKit
class CheckFontIconView: UIViewController,UITextFieldDelegate {
var activeField: UITextField?
#IBOutlet weak var loginFieldsView: UIView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var mobileNo: UITextField!
#IBOutlet weak var textFieldPassword: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
mobileNo.delegate = self
textFieldPassword.delegate = self
registerForKeyboardNotifications()
}
#IBAction func btnLoginAction(_ sender: Any) {
}
deinit {
//NotificationCenter.default.removeObserver(self)
self.deregisterFromKeyboardNotifications()
}
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)
}
func keyboardWasShown(notification: NSNotification) {
//Need to calculate keyboard exact size due to Apple suggestions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if self.activeField != nil {
self.loginFieldsView.frame.origin.y -= (keyboardSize?.height)!
}
}
func keyboardWillBeHidden(notification: NSNotification) {
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
self.loginFieldsView.frame.origin.y -= (keyboardSize?.height)!
self.loginFieldsView.endEditing(true)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
activeField?.resignFirstResponder()
return true
}
}
Once try with scrollView,I hope it will help you.
Use a scroll view to moving text field up and down.
Making Up
Make a #IBOutlet weak var scroller: UIScrollView!;
Under textFieldDidBeginEditing:textField method
Create a CGPoint with x: 0 and y texfield.frame.origin.y
And then start moving the scroller with setContentOffset:animated function.(Parameter will be your CGPoint and a boolean value true).
Making Down
Under textFieldDidEndEditing:textField set your scroller to CGPoint.zero with same setContentOffset:animated function.
*And your textFieldShouldReturn:textField should be resignFirstResponder or to next textField.
Please let me know if having any problem on this.
Thanks for ask question...
Use TPKeyboard to achieve above functionality then no manage this kind of stuff (Automatically manage by TPKeyboard)...
Update:
I think you have done some mistake in given below code...
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
You have to DEBUG and identify exact issue..
Happy coding...
I made the simple code for your problem. It is not good but you can refer with that idea for fix your problem.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
var activeField: UITextField?
#IBOutlet weak var loginFieldsView: UIView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var mobileNo: UITextField!
#IBOutlet weak var textFieldPassword: UITextField!
var originalHeight:CGFloat!
override func viewDidLoad() {
super.viewDidLoad()
mobileNo.delegate = self
textFieldPassword.delegate = self
originalHeight = self.loginFieldsView.frame.origin.y
registerForKeyboardNotifications()
}
#IBAction func btnLoginAction(_ sender: Any) {
}
deinit {
//NotificationCenter.default.removeObserver(self)
self.deregisterFromKeyboardNotifications()
}
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)
}
func keyboardWasShown(notification: NSNotification) {
//Need to calculate keyboard exact size due to Apple suggestions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if self.activeField != nil {
if self.loginFieldsView.frame.origin.y == originalHeight {
self.loginFieldsView.frame.origin.y -= (keyboardSize?.height)!
}
}
}
func keyboardWillBeHidden(notification: NSNotification) {
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if originalHeight > self.loginFieldsView.frame.origin.y {
self.loginFieldsView.frame.origin.y += (keyboardSize?.height)!
}
self.loginFieldsView.endEditing(true)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
activeField?.resignFirstResponder()
return true
}
}
Just one change hold your view old frame in a variable and assign it again to your view when keyboard disappear.
import UIKit
class CheckFontIconView: UIViewController,UITextFieldDelegate {
var activeField: UITextField?
#IBOutlet weak var loginFieldsView: UIView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var mobileNo: UITextField!
#IBOutlet weak var textFieldPassword: UITextField!
var previousFrame : CGRect!
override func viewDidLoad() {
super.viewDidLoad()
previousFrame=self.loginFieldsView.frame
mobileNo.delegate = self
textFieldPassword.delegate = self
registerForKeyboardNotifications()
}
func keyboardWasShown(notification: NSNotification) {
//Need to calculate keyboard exact size due to Apple suggestions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if self.activeField != nil {
self.loginFieldsView.frame.origin.y = previousFrame.origin.y-(keyboardSize?.height)!
}
}
func keyboardWillBeHidden(notification: NSNotification) {
//Once keyboard disappears, restore original positions
/*var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size*/
self.loginFieldsView.frame = previousFrame
//self.loginFieldsView.endEditing(true)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
activeField?.resignFirstResponder()
return true
}
}
I'm creating a today extension that grows/shrinks to save space. in the Notification Center, but I am having problems with the NSNotificationCenter. If I call the visibility() function, the view shrinks and grows normally, but if I try posting a notification, the extension fails and attempts to reload instead(at least the first time, the second time the extension just says "Unable to load". Why is this?
var NSNotificationDidChoose = "NSNotificationDidChoose"
#IBOutlet var tableView: UITableView!
#IBOutlet var activityIndicator: UIActivityIndicatorView!
#IBAction func shrink(sender: AnyObject) {
//visibility(["bool":false])works fine here
NSNotificationCenter.defaultCenter().postNotificationName(NSNotificationDidChoose, object: nil, userInfo: ["bool":false])
//Crashes and the extension reloads
}
#IBAction func unshrink(sender: AnyObject) {
//visibility(["bool":true]) works fine here
NSNotificationCenter.defaultCenter().postNotificationName(NSNotificationDidChoose, object: nil, userInfo: ["bool":true])
//Crashes and the extension reloads
}
#IBOutlet var buttonview: UIView!
func visibility(boole:[NSObject:AnyObject]) {
var bool = boole["bool"] as Bool
println(bool)
tableView.hidden = !bool
activityIndicator.hidden = !bool
if bool {
self.preferredContentSize = CGSize(width: 350, height: 420)
} else {
self.preferredContentSize = CGSize(width: 350, height: buttonview.frame.height+25)
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "visibility:", name: NSNotificationDidChoose, object: nil)
}
The argument of notification method is NSNotification. Try this.
func visibility(notif: NSNotification) {
let boole = notif.userInfo!
var bool = boole["bool"] as Bool
....
}
I am using the following code from "Programming iOS 8". I have a subview with constraints that contains a simple textfield. This view has top and bottom to superview constraints, which I have outlets for. I have an outlet for the subview as well. The goal here is that when the keyboard appears, it pushes this subview up. I get an error on the line "let f = self.fr!.frame" Thread 1: EXC_BAD_INSTRUCTION. Does it have to do with needing to unwrap the optional? Could it be an issue with my constraints? Any help would be much appreciated. Thanks.
import UIKit
class ViewController: UIViewController {
#IBOutlet var topSpace: NSLayoutConstraint!
#IBOutlet var bottomSpace: NSLayoutConstraint!
#IBOutlet var slidingView: UIView!
var fr: UIView?
override func viewDidLoad() {
NSNotificationCenter.defaultCenter().addObserver(
self, selector: "keyboardShow:",
name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(
self, selector: "keyboardHide:",
name: UIKeyboardWillHideNotification, object: nil)
super.viewDidLoad()
}
func textFieldDidBeginEditing(tf: UITextField) {
self.fr = tf // keep track of the first responder
}
func textFieldShouldReturn(tf: UITextField) -> Bool {
tf.resignFirstResponder()
self.fr = nil
return true
}
func keyboardShow(n:NSNotification) {
let d = n.userInfo!
var r = (d[UIKeyboardFrameEndUserInfoKey] as NSValue).CGRectValue()
r = self.slidingView.convertRect(r, fromView:nil)
let f = self.fr!.frame
let y : CGFloat =
f.maxY + r.size.height - self.slidingView.bounds.height + 5
if r.origin.y < f.maxY {
self.topSpace.constant = -y
self.bottomSpace.constant = y
self.view.layoutIfNeeded()
}
}
func keyboardHide(n:NSNotification){
self.topSpace.constant = 0
self.bottomSpace.constant = 0
self.view.layoutIfNeeded()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
If I'm not mistaken, the keyboard shows before you start editing, so your self.fr is still nil when your keyboard is shown. Check to see if it's nil. It shouldn't have to do anything with the optional unwrapping. It only fails when you unwrap a null.