how to avoid keyboard in textfields - swift

I use a couple of buttons '0123456789.' (and some others) as an alternative for a keyboard. They are connected to (several) texfields. I made them all programmatically, so without storyboard. I also use UITextFieldDelegate. That works as expected, and I can input my text into the textfields.
I use the following code for my buttons:
func textFieldDidBeginEditing(textField: UITextField) {
activeField = textField
}
#IBAction func Pressed(sender: UIButton) {
if (activeField != nil) {
switch sender.tag {
case 0:
activeField!.text = activeField!.text+"0"
case 1:
The problem is that every-time I click in a textfield, the keyboard opens up too. I want to avoid that... since I made an alternative for input with the buttons. How can I get rid of the keyboard when I click in a textfield?

Just return NO from textFieldShouldBeginEditing: from the delegate you mention you are already using.
When the user performs an action that would normally initiate an editing session, the text field calls this method first to see if editing should actually proceed. In most circumstances, you would simply return YES from this method to allow editing to proceed.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField == /* a text field that is using your custom layout */)
return NO;
}
[Source]
Though why don't you just use [textField setKeyboardType:UIKeyboardTypeNumberPad];

You should make your custom keypad the inputView of the textField. It will then be shown instead of the built-in keyboard.
i.e.:
textField.inputView = yourCustomKeypad;

I've made a similar input interface, using custom buttons...why not instead of a UITextField, use a UILabel to display the "8,900"(input).
Then just make the buttons manipulate the UILabel.text.

Related

How to prevent right-click textfield renaming in NSOutlineView

I am having a NSOutlineView in which the textfield is editable by either pressing return or using the right click. I am also overriding the menu(for event: NSEvent) -> NSMenu? to menu based on which row is clicked
When I right click on the textfield, it opens the correct menu as expected but it also makes the textfield to go into edit mode. Is there a way to handle this behaviour?
However, when I click outside the textfield then it works without setting the textfield in edit mode:
I have a similar NSTableView where right-clicking is supported to display a menu, but the fields are also directly editable. I took a look to see why/how the editing doesn't seem to be a problem in my case, and I narrowed the behavior down to the presence of this line of code in my NSTableView subclass:
// This trick convinces the accessibility system to bother checking whether
// we have a menu to export to e.g. VoiceOver.
[self setMenu:[[NSMenu alloc] init]];
As you can see from the comment, the rationale for this "setting an empty menu" was for a different reason than avoiding the editing behavior you're seeing, but it appears to have the side-effect of also fixing that.
So, please try adding a line like the above to your NSOutlineView subclass and see if it fixes the problem!
I ran into this same problem trying to get my Swift-based app on Monterey working. I was surprised there was not a more simple/obvious solution, but here is what I came up with:
class MyOutlineView: NSOutlineView {
// prevent text field from becoming editable when context menu is used
override func validateProposedFirstResponder(_ responder: NSResponder,
for event: NSEvent?) -> Bool
{
guard let validEvent = event,
contextMenuTriggered(event: validEvent),
selectedRow != -1,
selectedRow == row(at: convert(validEvent.locationInWindow, from: nil))
else {
return super.validateProposedFirstResponder(responder, for: event)
}
return false
}
private func contextMenuTriggered(event: NSEvent) -> Bool {
return event.modifierFlags.contains(.control)
&& (event.type == .leftMouseDown || event.type == .leftMouseUp)
}
}
This detects if a control-click happened on the selected row in the outline view, then blocks it from receiving focus so the text field does not become editable.
Credit for this approach goes to the answer provided by #strangetimes here: Disable editing of a NSTextFieldCell on right clicking on a row

Is it possible use different instance of UIMenuController for UITextField in Swift?

According to link we should use a singleton UIMenuController instance which is referred to the editing menu.
The problem is I want to show extra items in different situations. For instance, I want to just show "copy" item when keyboard is up. and show "copy" and "reply" when tapping on a tableview row.
When I add "reply" to the UIMenuController instance it is shown when tapping on UITextField too. therefore, I added these codes:
func textViewDidBeginEditing(_ textView: UITextView) {
var nonReplyMenuItems: [UIMenuItem] = []
if let allMenuItems = UIMenuController.shared.menuItems {
for menuItem in allMenuItems {
if menuItem.title != "reply".localized {
nonReplyMenuItems.append(menuItem)
}
}
}
UIMenuController.shared.menuItems = nonReplyMenuItems
UIMenuController.shared.setMenuVisible(true, animated: true)
}
It fixed the problem in most situations, but not all.
when keyboard is up and tapping on a row in tableview "reply" will be added. Then when I tap on UITextView the reply will be shown there too.
It seems your scenario is like it:
tap on textfield ----> shows copy
tap on tableview ---> shows copy and reply
tab on textfield ----> shows copy and reply (you want only copy shows)
As I know the textViewDidBeginEditing calls when your text filed is not editing and you tap on that; So if you have two textfileds by switching on that method calls every time but when you are switching between a text filed and another action base object your text field is editing and its state has not changed.
When you touch on tableview you must call textfield.resignFirstResponder() so when you tap on text field again the textViewDidBeginEditing calls again, the problem of this is hiding keyboard; The better way I preferو is adding function to touch down of text field or on gesture to do what you write on textViewDidBeginEditing method

Custom keyboard in swift iOS 10

How do I create outlets for my keys in a custom keyboard to switch from letters to numbers and symbols? I am trying to create a custom keyboard and I don't know how to create outlets for my keys to switch back and forth from letters to numerals and symbols.
So, I gather from your comment, that this is what you are looking for. The type of keyboard input, is determined by setting the 'keyboardType' property of the keyboard's delegate. If you want to switch and update a view, I think you'll have to dismiss the keyboard and recall it. I find this unsafe, and would highly suggest using a normal keyboard (which has all the characters you need), trusting your user, and sanitizing the input. But the following does work, if you must. In the following, 'txtField' is a UITextField with the UIViewController set as its delegate, the IBAction is wired to a UIButton, and 'isNumbers' is a Bool property of the UIViewController.
#IBAction func switchKeyboards(_ sender: Any) {
if isNumbers {
txtField.keyboardType = UIKeyboardType.alphabet
isNumbers = false
} else {
txtField.keyboardType = UIKeyboardType.numberPad
isNumbers = true
}
txtField.resignFirstResponder()
txtField.becomeFirstResponder()
}

what is the exact difference between textFieldDidBeginEditing and textFieldShouldBeginEditing

what is the exact difference between textFieldDidBeginEditing and textFieldShouldBeginEditing. and i want to know in which scenario we use them(I know that they are called when we enter any thing into textfield. i want to know the exact time in which they are called when we use both in our program)
A "shouldBegin" something allows you to say NO on the return value to prohibit the action.
A "didBegin" something says it has just started to happen and you need to take whatever actions you need to do at that point in time.
A textFieldShouldBeginEditing method requests permission from the delegate to allow the textField to be edited when, say, a user taps on it.
On the other hand, textFieldDidBeginEditing is called when a textField begins editing content (i.e. right after textFieldShouldBeginEditing, if allowed).
Example: you want to make a non-editable text field, so you return NO:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return NO;
}
About textFieldDidBeginEditing:
Discussion
This method notifies the delegate that the specified text field just became the first responder. You can use this method to update your delegate’s state information. For example, you might use this method to show overlay views that should be visible while editing.
So let's say that you have a text field subclass (and you want it to be editable) that while the user edits the contents changes the graphic (example: it wants to display a different focus ring while the user types), so you use it to do these things.
if you set the tags (from Storyboard) for "username" and "password" fields to 0 and 1 respectively and then try to catch acitve field inside func textFieldDidBeginEditing, it does not work!
**func textFieldDidBeginEditing(_ textField: UITextField) -> Bool
{
activeTextField = textField
return true
}**
**func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
let value = activeTextField.tag
switch value
{
case 0:
// for username field it should execute this case
case 1:
// for password field it should execute this case
}
}**
the same function is working and providing correct results when called as #objc func textFieldDidBeginEditing, without "objc" word it is not picking the active field. I just want to know, why is so...
**#objc func textFieldDidBeginEditing(_ textField: ) -> Bool
{
activeTextField = textField
return true
}**

Disable UITextField keyboard?

I put a numeric keypad in my app for inputing numbers into a text view, but in order to input numbers I have to click on the text view. Once I do so, the regular keyboard comes up, which I don't want.
How can I disable the keyboard altogether? Any help is greatly appreciated.
The UITextField's inputView property is nil by default, which means the standard keyboard gets displayed.
If you assign it a custom input view, or just a dummy view then the keyboard will not appear, but the blinking cursor will still appear:
UIView* dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
myTextField.inputView = dummyView; // Hide keyboard, but show blinking cursor
If you want to hide both the keyboard and the blinking cursor then use this approach:
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return NO; // Hide both keyboard and blinking cursor.
}
For Swift 2.x, 3.x, 4.x, 5.x
textField.inputView = UIView()
does the trick
If it's a UITextField, you can set it's enabled property to NO.
If it's a UITextView, you can implement -textViewShouldBeginEditing: in its delegate to return NO, so that it'll never start editing. Or you can subclass it and override -canBecomeFirstResponder to return NO. Or you could take advantage of its editing behavior and put your numeric buttons into a view which you use as the text view's inputView. This is supposed to cause the buttons to be displayed when the text view is edited. That may or may not be what you want.
Depending on how you have your existing buttons working this could break them, but you could prevent the keyboard from showing up setting the textView's editable property to NO
myTextView.editable = NO
I have the same problem when had 2 textfields on the same view. My purpose was to show a default keyboard for one textfield and hide for second and show instead a dropdown list.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
method simply did not work as I expected for 2 textfields , the only workaround I found was
UIView* dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
myTextField.inputView = dummyView;
myTextField.inputAccessoryView = dummyView;
myTextField.tintColor = myTextField.backgroundColor; //to hide a blinking cursor
This will totally hide the keyboard for a target textField (DropDownList in my case) and show a default one when user switches to the 2nd textfield (Account number on my screenshot)
There is a simple hack to it. Place a empty button
(No Text) above the keyboard and have a action Event assign to it. This will stop keyboard coming up and you can perform any action you want in the handle for the button click
To disable UITextField keyboard:
Go to Main.Storyboard
Click on the UITextField to select it
Show the Attributes inspector
Uncheck the User Interaction Enabled
To disable UITextView keyboard:
Go to Main.Storyboard
Click on the UITextView to select it
Show the Attributes inspector
Uncheck the Editable Behavior
I used the keyboardWillShow Notification and textField.endEditing(true):
lazy var myTextField: UITextField = {
let textField = UITextField()
// ....
return textField
}()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
}
#objc func keyboardWillShow(_ notification: Notification) {
myTextField.endEditing(true)
// if using a textView >>> myTextView.endEditing(true) <<<
}
private void TxtExpiry_EditingDidBegin(object sender, EventArgs e)
{
((UITextField)sender).ResignFirstResponder();
}
In C# this worked for me, I don't use the storyboard.
In Xcode 8.2 you can do it easily by unchecking state "enabled" option.
Click on the textField you want to be uneditable
Go to attirube inspector on right side
Uncheck "enabled" for State
Or if you want to do it via code. You can simply create an #IBOutlet of this text field, give it a name and then use this variable name in the viewDidLoad func (or any custom one if you intent to) like this (in swift 3.0.1):
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
myTextField.isEditable = false
}