Binding a button (UIView) to keyboard that works in multiple textfields (Swift 4.2)
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
Sorry if any similar question(s) has been answered. But, I just can't seem to figure this one out.
I have reached my goal, to bind the "Log In" button to the keyboard, basically pushing it from the bottom of the screen to the top of the keyboard using an extension below.
picture: Initial view without keyboard.
picture: keyboard has been launched.
My UIView
extension:
import UIKit
extension UIView{
func bindToKeyboard(){
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardWillChange(_ notification: NSNotification){
let duration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt
let beginningFrame = (notification.userInfo![UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let endFrame = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = endFrame.origin.y - beginningFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}
}
and I called bindToKeyboard()
to loginBtn
in the viewDidLoad()
of my LoginVC like so:
loginBtn.bindToKeyboard()
The problem here is, after the first tap to the textfield (either email or password field), the button disappears. After the keyboard is closed, the button is actually back to its initial position just like in the first picture. Then calling the keyboard again by tapping one of those textfields, the button works properly. But the second and so forth tap, it does not.
The point of my question:
- how can I implement the extension to be able to work properly with multiple textfields/textviews?
- If that's not possible, how should I approach this problem?
I am sorry if my explanation and or English is unclear.
Thank you so much.
ios swift uiview swift4.2
add a comment |
Sorry if any similar question(s) has been answered. But, I just can't seem to figure this one out.
I have reached my goal, to bind the "Log In" button to the keyboard, basically pushing it from the bottom of the screen to the top of the keyboard using an extension below.
picture: Initial view without keyboard.
picture: keyboard has been launched.
My UIView
extension:
import UIKit
extension UIView{
func bindToKeyboard(){
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardWillChange(_ notification: NSNotification){
let duration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt
let beginningFrame = (notification.userInfo![UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let endFrame = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = endFrame.origin.y - beginningFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}
}
and I called bindToKeyboard()
to loginBtn
in the viewDidLoad()
of my LoginVC like so:
loginBtn.bindToKeyboard()
The problem here is, after the first tap to the textfield (either email or password field), the button disappears. After the keyboard is closed, the button is actually back to its initial position just like in the first picture. Then calling the keyboard again by tapping one of those textfields, the button works properly. But the second and so forth tap, it does not.
The point of my question:
- how can I implement the extension to be able to work properly with multiple textfields/textviews?
- If that's not possible, how should I approach this problem?
I am sorry if my explanation and or English is unclear.
Thank you so much.
ios swift uiview swift4.2
add a comment |
Sorry if any similar question(s) has been answered. But, I just can't seem to figure this one out.
I have reached my goal, to bind the "Log In" button to the keyboard, basically pushing it from the bottom of the screen to the top of the keyboard using an extension below.
picture: Initial view without keyboard.
picture: keyboard has been launched.
My UIView
extension:
import UIKit
extension UIView{
func bindToKeyboard(){
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardWillChange(_ notification: NSNotification){
let duration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt
let beginningFrame = (notification.userInfo![UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let endFrame = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = endFrame.origin.y - beginningFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}
}
and I called bindToKeyboard()
to loginBtn
in the viewDidLoad()
of my LoginVC like so:
loginBtn.bindToKeyboard()
The problem here is, after the first tap to the textfield (either email or password field), the button disappears. After the keyboard is closed, the button is actually back to its initial position just like in the first picture. Then calling the keyboard again by tapping one of those textfields, the button works properly. But the second and so forth tap, it does not.
The point of my question:
- how can I implement the extension to be able to work properly with multiple textfields/textviews?
- If that's not possible, how should I approach this problem?
I am sorry if my explanation and or English is unclear.
Thank you so much.
ios swift uiview swift4.2
Sorry if any similar question(s) has been answered. But, I just can't seem to figure this one out.
I have reached my goal, to bind the "Log In" button to the keyboard, basically pushing it from the bottom of the screen to the top of the keyboard using an extension below.
picture: Initial view without keyboard.
picture: keyboard has been launched.
My UIView
extension:
import UIKit
extension UIView{
func bindToKeyboard(){
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardWillChange(_ notification: NSNotification){
let duration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt
let beginningFrame = (notification.userInfo![UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let endFrame = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = endFrame.origin.y - beginningFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}
}
and I called bindToKeyboard()
to loginBtn
in the viewDidLoad()
of my LoginVC like so:
loginBtn.bindToKeyboard()
The problem here is, after the first tap to the textfield (either email or password field), the button disappears. After the keyboard is closed, the button is actually back to its initial position just like in the first picture. Then calling the keyboard again by tapping one of those textfields, the button works properly. But the second and so forth tap, it does not.
The point of my question:
- how can I implement the extension to be able to work properly with multiple textfields/textviews?
- If that's not possible, how should I approach this problem?
I am sorry if my explanation and or English is unclear.
Thank you so much.
ios swift uiview swift4.2
ios swift uiview swift4.2
asked Nov 16 '18 at 18:47
Sean SaoirseSean Saoirse
84
84
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
In this animation, if you use frame to control the position of button, the button is supposed to be free of constrains in vertical direction.
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
I use this animation well after removing all the constraints from UIButton. Otherwise, self.frame.origin.y += deltaY
should be replaced with constraint constant.
Good lucky with moving buttons.
This answer is invalid. If the button isn't connected to UIViewController's bottom safe area as is the question asked, the button is hanging in the air and can't be moved with the keyboard at all.
– Mohsin Khubaib Ahmed
Mar 1 at 10:06
add a comment |
I had the exact same problem and initially I tried handling it via the UIKeyboardNotification
method but the problem was when the different UITextField
was being edited when the Keyboard had changed its state, it won't register for any state change as it was already active. Therefore after much exploring I handled it via creating an accessoryView with a new button that is a duplication of my actual button. So basically, consider you have a UIButton
which is sticking at the bottom of the UIViewController
and you have 2 UITextField
which when switched interchangeably, cannot feel that the UIButton
was ever moved elsewhere but remain stuck on the keyboard. This following piece of code explains how to cater this problem:
@IBOutlet weak var signInBtn: UIButton!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
var accessoryViewKeyboard:UIView?
var btnAccessory:UIButton?
override func viewDidLoad() {
super.viewDidLoad()
passwordTextField.delegate = self
emailTextField.delegate = self
accessoryViewKeyboard = UIView(frame: signInBtn.frame)
//Inputting the "accessoryViewKeyboard" here as the "inputAccessoryView" is of
//utmost importance to help the "signInBtn" to show up on tap of different "UITextFields"
emailTextField.inputAccessoryView = accessoryViewKeyboard
passwordTextField.inputAccessoryView = accessoryViewKeyboard
setupBtnWithKeyboard()
}
func setupBtnWithKeyboard() {
btnAccessory = UIButton(frame: CGRect(x: signInBtn.frame.origin.x, y: signInBtn.frame.origin.y, width: self.view.frame.size.width, height: signInBtn.frame.size.height))
accessoryViewKeyboard?.addSubview(btnAccessory!)
btnAccessory?.translatesAutoresizingMaskIntoConstraints = false
btnAccessory?.frame = CGRect(x: (accessoryViewKeyboard?.frame.origin.x)!,
y: (accessoryViewKeyboard?.frame.origin.y)!,
width: self.view.frame.size.width,
height: (accessoryViewKeyboard?.frame.size.height)!)
btnAccessory?.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 108/255, alpha: 1)
btnAccessory?.setTitle("Sign In", for: .normal)
btnAccessory?.titleLabel?.font = .systemFont(ofSize: 22)
btnAccessory?.titleLabel?.textColor = UIColor.white
btnAccessory?.titleLabel?.textAlignment = .center
btnAccessory?.isEnabled = true
btnAccessory?.addTarget(self, action: #selector(SignIn.signInBtnPressed), for: .touchUpInside)
NSLayoutConstraint.activate([
btnAccessory!.leadingAnchor.constraint(equalTo:
accessoryViewKeyboard!.leadingAnchor, constant: 0),
btnAccessory!.centerYAnchor.constraint(equalTo:
accessoryViewKeyboard!.centerYAnchor),
btnAccessory!.trailingAnchor.constraint(equalTo:
accessoryViewKeyboard!.trailingAnchor, constant: 0),
btnAccessory!.heightAnchor.constraint(equalToConstant: signInBtn.frame.size.height),
])
}
And you're done. This will keep the UIButton
always present on the Keyboard. Important thing is no matter how many instances of UITextField
you introduce, always input the accessoryViewKeyboard
as its inputAccessoryView
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53343726%2fbinding-a-button-uiview-to-keyboard-that-works-in-multiple-textfields-swift-4%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
In this animation, if you use frame to control the position of button, the button is supposed to be free of constrains in vertical direction.
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
I use this animation well after removing all the constraints from UIButton. Otherwise, self.frame.origin.y += deltaY
should be replaced with constraint constant.
Good lucky with moving buttons.
This answer is invalid. If the button isn't connected to UIViewController's bottom safe area as is the question asked, the button is hanging in the air and can't be moved with the keyboard at all.
– Mohsin Khubaib Ahmed
Mar 1 at 10:06
add a comment |
In this animation, if you use frame to control the position of button, the button is supposed to be free of constrains in vertical direction.
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
I use this animation well after removing all the constraints from UIButton. Otherwise, self.frame.origin.y += deltaY
should be replaced with constraint constant.
Good lucky with moving buttons.
This answer is invalid. If the button isn't connected to UIViewController's bottom safe area as is the question asked, the button is hanging in the air and can't be moved with the keyboard at all.
– Mohsin Khubaib Ahmed
Mar 1 at 10:06
add a comment |
In this animation, if you use frame to control the position of button, the button is supposed to be free of constrains in vertical direction.
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
I use this animation well after removing all the constraints from UIButton. Otherwise, self.frame.origin.y += deltaY
should be replaced with constraint constant.
Good lucky with moving buttons.
In this animation, if you use frame to control the position of button, the button is supposed to be free of constrains in vertical direction.
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
I use this animation well after removing all the constraints from UIButton. Otherwise, self.frame.origin.y += deltaY
should be replaced with constraint constant.
Good lucky with moving buttons.
answered Nov 19 '18 at 1:10
E.ComsE.Coms
3,4542416
3,4542416
This answer is invalid. If the button isn't connected to UIViewController's bottom safe area as is the question asked, the button is hanging in the air and can't be moved with the keyboard at all.
– Mohsin Khubaib Ahmed
Mar 1 at 10:06
add a comment |
This answer is invalid. If the button isn't connected to UIViewController's bottom safe area as is the question asked, the button is hanging in the air and can't be moved with the keyboard at all.
– Mohsin Khubaib Ahmed
Mar 1 at 10:06
This answer is invalid. If the button isn't connected to UIViewController's bottom safe area as is the question asked, the button is hanging in the air and can't be moved with the keyboard at all.
– Mohsin Khubaib Ahmed
Mar 1 at 10:06
This answer is invalid. If the button isn't connected to UIViewController's bottom safe area as is the question asked, the button is hanging in the air and can't be moved with the keyboard at all.
– Mohsin Khubaib Ahmed
Mar 1 at 10:06
add a comment |
I had the exact same problem and initially I tried handling it via the UIKeyboardNotification
method but the problem was when the different UITextField
was being edited when the Keyboard had changed its state, it won't register for any state change as it was already active. Therefore after much exploring I handled it via creating an accessoryView with a new button that is a duplication of my actual button. So basically, consider you have a UIButton
which is sticking at the bottom of the UIViewController
and you have 2 UITextField
which when switched interchangeably, cannot feel that the UIButton
was ever moved elsewhere but remain stuck on the keyboard. This following piece of code explains how to cater this problem:
@IBOutlet weak var signInBtn: UIButton!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
var accessoryViewKeyboard:UIView?
var btnAccessory:UIButton?
override func viewDidLoad() {
super.viewDidLoad()
passwordTextField.delegate = self
emailTextField.delegate = self
accessoryViewKeyboard = UIView(frame: signInBtn.frame)
//Inputting the "accessoryViewKeyboard" here as the "inputAccessoryView" is of
//utmost importance to help the "signInBtn" to show up on tap of different "UITextFields"
emailTextField.inputAccessoryView = accessoryViewKeyboard
passwordTextField.inputAccessoryView = accessoryViewKeyboard
setupBtnWithKeyboard()
}
func setupBtnWithKeyboard() {
btnAccessory = UIButton(frame: CGRect(x: signInBtn.frame.origin.x, y: signInBtn.frame.origin.y, width: self.view.frame.size.width, height: signInBtn.frame.size.height))
accessoryViewKeyboard?.addSubview(btnAccessory!)
btnAccessory?.translatesAutoresizingMaskIntoConstraints = false
btnAccessory?.frame = CGRect(x: (accessoryViewKeyboard?.frame.origin.x)!,
y: (accessoryViewKeyboard?.frame.origin.y)!,
width: self.view.frame.size.width,
height: (accessoryViewKeyboard?.frame.size.height)!)
btnAccessory?.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 108/255, alpha: 1)
btnAccessory?.setTitle("Sign In", for: .normal)
btnAccessory?.titleLabel?.font = .systemFont(ofSize: 22)
btnAccessory?.titleLabel?.textColor = UIColor.white
btnAccessory?.titleLabel?.textAlignment = .center
btnAccessory?.isEnabled = true
btnAccessory?.addTarget(self, action: #selector(SignIn.signInBtnPressed), for: .touchUpInside)
NSLayoutConstraint.activate([
btnAccessory!.leadingAnchor.constraint(equalTo:
accessoryViewKeyboard!.leadingAnchor, constant: 0),
btnAccessory!.centerYAnchor.constraint(equalTo:
accessoryViewKeyboard!.centerYAnchor),
btnAccessory!.trailingAnchor.constraint(equalTo:
accessoryViewKeyboard!.trailingAnchor, constant: 0),
btnAccessory!.heightAnchor.constraint(equalToConstant: signInBtn.frame.size.height),
])
}
And you're done. This will keep the UIButton
always present on the Keyboard. Important thing is no matter how many instances of UITextField
you introduce, always input the accessoryViewKeyboard
as its inputAccessoryView
.
add a comment |
I had the exact same problem and initially I tried handling it via the UIKeyboardNotification
method but the problem was when the different UITextField
was being edited when the Keyboard had changed its state, it won't register for any state change as it was already active. Therefore after much exploring I handled it via creating an accessoryView with a new button that is a duplication of my actual button. So basically, consider you have a UIButton
which is sticking at the bottom of the UIViewController
and you have 2 UITextField
which when switched interchangeably, cannot feel that the UIButton
was ever moved elsewhere but remain stuck on the keyboard. This following piece of code explains how to cater this problem:
@IBOutlet weak var signInBtn: UIButton!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
var accessoryViewKeyboard:UIView?
var btnAccessory:UIButton?
override func viewDidLoad() {
super.viewDidLoad()
passwordTextField.delegate = self
emailTextField.delegate = self
accessoryViewKeyboard = UIView(frame: signInBtn.frame)
//Inputting the "accessoryViewKeyboard" here as the "inputAccessoryView" is of
//utmost importance to help the "signInBtn" to show up on tap of different "UITextFields"
emailTextField.inputAccessoryView = accessoryViewKeyboard
passwordTextField.inputAccessoryView = accessoryViewKeyboard
setupBtnWithKeyboard()
}
func setupBtnWithKeyboard() {
btnAccessory = UIButton(frame: CGRect(x: signInBtn.frame.origin.x, y: signInBtn.frame.origin.y, width: self.view.frame.size.width, height: signInBtn.frame.size.height))
accessoryViewKeyboard?.addSubview(btnAccessory!)
btnAccessory?.translatesAutoresizingMaskIntoConstraints = false
btnAccessory?.frame = CGRect(x: (accessoryViewKeyboard?.frame.origin.x)!,
y: (accessoryViewKeyboard?.frame.origin.y)!,
width: self.view.frame.size.width,
height: (accessoryViewKeyboard?.frame.size.height)!)
btnAccessory?.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 108/255, alpha: 1)
btnAccessory?.setTitle("Sign In", for: .normal)
btnAccessory?.titleLabel?.font = .systemFont(ofSize: 22)
btnAccessory?.titleLabel?.textColor = UIColor.white
btnAccessory?.titleLabel?.textAlignment = .center
btnAccessory?.isEnabled = true
btnAccessory?.addTarget(self, action: #selector(SignIn.signInBtnPressed), for: .touchUpInside)
NSLayoutConstraint.activate([
btnAccessory!.leadingAnchor.constraint(equalTo:
accessoryViewKeyboard!.leadingAnchor, constant: 0),
btnAccessory!.centerYAnchor.constraint(equalTo:
accessoryViewKeyboard!.centerYAnchor),
btnAccessory!.trailingAnchor.constraint(equalTo:
accessoryViewKeyboard!.trailingAnchor, constant: 0),
btnAccessory!.heightAnchor.constraint(equalToConstant: signInBtn.frame.size.height),
])
}
And you're done. This will keep the UIButton
always present on the Keyboard. Important thing is no matter how many instances of UITextField
you introduce, always input the accessoryViewKeyboard
as its inputAccessoryView
.
add a comment |
I had the exact same problem and initially I tried handling it via the UIKeyboardNotification
method but the problem was when the different UITextField
was being edited when the Keyboard had changed its state, it won't register for any state change as it was already active. Therefore after much exploring I handled it via creating an accessoryView with a new button that is a duplication of my actual button. So basically, consider you have a UIButton
which is sticking at the bottom of the UIViewController
and you have 2 UITextField
which when switched interchangeably, cannot feel that the UIButton
was ever moved elsewhere but remain stuck on the keyboard. This following piece of code explains how to cater this problem:
@IBOutlet weak var signInBtn: UIButton!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
var accessoryViewKeyboard:UIView?
var btnAccessory:UIButton?
override func viewDidLoad() {
super.viewDidLoad()
passwordTextField.delegate = self
emailTextField.delegate = self
accessoryViewKeyboard = UIView(frame: signInBtn.frame)
//Inputting the "accessoryViewKeyboard" here as the "inputAccessoryView" is of
//utmost importance to help the "signInBtn" to show up on tap of different "UITextFields"
emailTextField.inputAccessoryView = accessoryViewKeyboard
passwordTextField.inputAccessoryView = accessoryViewKeyboard
setupBtnWithKeyboard()
}
func setupBtnWithKeyboard() {
btnAccessory = UIButton(frame: CGRect(x: signInBtn.frame.origin.x, y: signInBtn.frame.origin.y, width: self.view.frame.size.width, height: signInBtn.frame.size.height))
accessoryViewKeyboard?.addSubview(btnAccessory!)
btnAccessory?.translatesAutoresizingMaskIntoConstraints = false
btnAccessory?.frame = CGRect(x: (accessoryViewKeyboard?.frame.origin.x)!,
y: (accessoryViewKeyboard?.frame.origin.y)!,
width: self.view.frame.size.width,
height: (accessoryViewKeyboard?.frame.size.height)!)
btnAccessory?.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 108/255, alpha: 1)
btnAccessory?.setTitle("Sign In", for: .normal)
btnAccessory?.titleLabel?.font = .systemFont(ofSize: 22)
btnAccessory?.titleLabel?.textColor = UIColor.white
btnAccessory?.titleLabel?.textAlignment = .center
btnAccessory?.isEnabled = true
btnAccessory?.addTarget(self, action: #selector(SignIn.signInBtnPressed), for: .touchUpInside)
NSLayoutConstraint.activate([
btnAccessory!.leadingAnchor.constraint(equalTo:
accessoryViewKeyboard!.leadingAnchor, constant: 0),
btnAccessory!.centerYAnchor.constraint(equalTo:
accessoryViewKeyboard!.centerYAnchor),
btnAccessory!.trailingAnchor.constraint(equalTo:
accessoryViewKeyboard!.trailingAnchor, constant: 0),
btnAccessory!.heightAnchor.constraint(equalToConstant: signInBtn.frame.size.height),
])
}
And you're done. This will keep the UIButton
always present on the Keyboard. Important thing is no matter how many instances of UITextField
you introduce, always input the accessoryViewKeyboard
as its inputAccessoryView
.
I had the exact same problem and initially I tried handling it via the UIKeyboardNotification
method but the problem was when the different UITextField
was being edited when the Keyboard had changed its state, it won't register for any state change as it was already active. Therefore after much exploring I handled it via creating an accessoryView with a new button that is a duplication of my actual button. So basically, consider you have a UIButton
which is sticking at the bottom of the UIViewController
and you have 2 UITextField
which when switched interchangeably, cannot feel that the UIButton
was ever moved elsewhere but remain stuck on the keyboard. This following piece of code explains how to cater this problem:
@IBOutlet weak var signInBtn: UIButton!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
var accessoryViewKeyboard:UIView?
var btnAccessory:UIButton?
override func viewDidLoad() {
super.viewDidLoad()
passwordTextField.delegate = self
emailTextField.delegate = self
accessoryViewKeyboard = UIView(frame: signInBtn.frame)
//Inputting the "accessoryViewKeyboard" here as the "inputAccessoryView" is of
//utmost importance to help the "signInBtn" to show up on tap of different "UITextFields"
emailTextField.inputAccessoryView = accessoryViewKeyboard
passwordTextField.inputAccessoryView = accessoryViewKeyboard
setupBtnWithKeyboard()
}
func setupBtnWithKeyboard() {
btnAccessory = UIButton(frame: CGRect(x: signInBtn.frame.origin.x, y: signInBtn.frame.origin.y, width: self.view.frame.size.width, height: signInBtn.frame.size.height))
accessoryViewKeyboard?.addSubview(btnAccessory!)
btnAccessory?.translatesAutoresizingMaskIntoConstraints = false
btnAccessory?.frame = CGRect(x: (accessoryViewKeyboard?.frame.origin.x)!,
y: (accessoryViewKeyboard?.frame.origin.y)!,
width: self.view.frame.size.width,
height: (accessoryViewKeyboard?.frame.size.height)!)
btnAccessory?.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 108/255, alpha: 1)
btnAccessory?.setTitle("Sign In", for: .normal)
btnAccessory?.titleLabel?.font = .systemFont(ofSize: 22)
btnAccessory?.titleLabel?.textColor = UIColor.white
btnAccessory?.titleLabel?.textAlignment = .center
btnAccessory?.isEnabled = true
btnAccessory?.addTarget(self, action: #selector(SignIn.signInBtnPressed), for: .touchUpInside)
NSLayoutConstraint.activate([
btnAccessory!.leadingAnchor.constraint(equalTo:
accessoryViewKeyboard!.leadingAnchor, constant: 0),
btnAccessory!.centerYAnchor.constraint(equalTo:
accessoryViewKeyboard!.centerYAnchor),
btnAccessory!.trailingAnchor.constraint(equalTo:
accessoryViewKeyboard!.trailingAnchor, constant: 0),
btnAccessory!.heightAnchor.constraint(equalToConstant: signInBtn.frame.size.height),
])
}
And you're done. This will keep the UIButton
always present on the Keyboard. Important thing is no matter how many instances of UITextField
you introduce, always input the accessoryViewKeyboard
as its inputAccessoryView
.
answered Mar 2 at 19:02
Mohsin Khubaib AhmedMohsin Khubaib Ahmed
7771322
7771322
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53343726%2fbinding-a-button-uiview-to-keyboard-that-works-in-multiple-textfields-swift-4%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown