Is it possible use different instance of UIMenuController for UITextField in Swift? - 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

Related

How could I keep keyboard up when tableview cells are tapped?

I am a beginner learning Swift and trying to build a search page with Swift. In my search page of the app, I have added two Views in my storyboard with one View above the other.
The upper View contains a Collection View where I have two prototypes of collection view cells. The first type of the cells has Label. The second type of the cells has TextField.
The other View on the bottom half of the screen contains a dynamic Table View where I have a list of items that can be selected. Each row of the table view cells has a selection item.
So, when I tap on a table view cell, the selection item will appear in the collection view. If I type a keyword in the TextField in the collection view, table view reloads and shows all the selection items that has the keyword, so I can tap and add an item to the collection view.
I would like to keep adding by typing a keyword after I tap on a searched item in the table view. So, I made the first cell showing selected items with labels and the second cell that has the TextField separated into two sections of the collection view. So, I only reload the first section (without TextField) for each selection. But somehow the keyboard automatically resign whenever I tap on the table view cell to add an item to the collection view.
Is there any way I can keep the keyboard up even when I tap on the tableview cells?
The keyboard also resigns when I tap the collection view cells.
I would appreciate your advice. Thanks.
I hope you are having a good day.
You can try calling this method on the UITextField you would like to show the keyboard for (maybe call it after the user taps on the UITableViewCell):
textField.becomeFirstResponder()
where "textField" is the variable name of your UITextField.
Please let me know if this fixed your issue.
Edit #1
Hello! Since my previous solution did not achieve your intended behavior. There is another solution in my mind, however I have not tried it before.
As an introduction to the concept of delegation, there is a method created by Apple called "textFieldShouldEndEditing" which is called by Apple whenever any keyboard will disappear on any text field.
This method is created by Apple, but you can override it (i.e. customize it) to suit your needs and tailor its behavior.
To override this method you have to assign your class as the delegate of UITextField by adding UITextFieldDelegate to your class definition as follows:
class YourClassName: UIViewController, UITextFieldDelegate { }
Now you have to set your class as the delegate by saying textField.delegate = self For every UITextField you create in your collection views
You then can re-create the method we discussed earlier in your class:
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
//let's implement it the next steps, but for now, let's return true.
return true
}
Now instead of Apple calling their version of the method, they will call yours.
You then can create a variable in the top level of your class (I will let you know where this will be helpful later), and "maybe" name it as:
var isCellBeingClicked = false
Now upon clicking on a cell, make this variable true, I believe you are using the method didSelectRowAt (but you could be using any other method which is fine):
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
[...]
isCellBeingClicked = true
[...]
}
Now back to our customized method textFieldShouldEndEditing mentioned in step 3. You can add this implementation:
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
//If a cell is being clicked right now, please do not dismiss the keyboard.
if isCellBeingClicked {
isCellBeingClicked = false //reset the value otherwise the keyboard will always be there
return false
}
else { return true }
}
Please let me know if this fixes your issue.
Best regards

How to give the focus to the text field?

Very simple setting: I have a ViewController scene with a TextField on it. The ViewController is the text field's delegate.
I would like to have the following behavior: When the user enters the text field (i.e., taps on it), I would like to display a modal alert box with an OK button. After the users presses OK, the TextField should get the focus (i.e., cursor blinking inside it).
I can't get this working. I react on the user tapping in the text field by textFieldShouldBeginEditing(). This works in the sense that I can display the message box there. But after the user (in this case it's me ;o)) taps the OK button, the text field doesn't have the focus, and when I tap it again, the message box appears again.
How can I get rid of this?
Do you really want the modal dialog to show every time the text field is clicked? Bear in mind that putting the activation in textFieldShouldBeginEditing() will mean that re-activating the field after dismissing the dialog will re-show the dialog.
Maybe you just need to show the dialog once? In which case a simple boolean flag that is set on first showing will fix the issue. I.e. at view controller scope:
var hasShownWarningDialog = false
and then implement instead (after comments):
func textFieldShouldBeginEditing(textField: UITextField) -> Bool
{
if !hasShownWarningDialog
{
hasShownWarningDialog = true
// Create dialog here
self.present(alert, animated: true, completion: {self.textField.becomeFirstResponder()})
return false
}
else
{
return true
}
}

How to autofill the right textfield

I need to autocomplete textfields from tableview. How can i select the right textfield(where i am writing at this moment)?
code is here
If I understand correctly you have two UITextFields and a UITableView and when you tap on a cell in the table view you want to put it's text into whichever text field has your input focus.
Try this:
if firstTextField.isFirstResponder {
firstTextField.text = selectedCell.textLabel.text
}
if secondTextField.isFirstResponder {
secondTextField.text = selectedCell.textLabel.text
}
The isFirstResponder method tells you if the control has the current focus and only one of them can.

setEditing method delete button doesn't work

In my UIViewController, I have an UITableView which contains different cells with saved contents by using the NSUserDefaults. I also have a custom UIBarButtonItem which causes the UITableView to enter and leave editing mode.
This all works, but the problem is when I tap the round red button and on the right side of the cell appears the delete button, the delete button doesn't work... I can tap on it as much as I want but the cell does not get deleted.
#IBAction func EditListButton(sender: UIBarButtonItem) {
if ShoppingListTable.editing {
ShoppingListTable.setEditing(false, animated: true)
self.EditListButton.title = "Edit"
} else {
ShoppingListTable.setEditing(true, animated: true)
self.EditListButton.title = "Done"
}
}
Use UITableViewDataSource's tableView:commitEditingStyle:forRowAtIndexPath: to detect a tap on the delete button.
Then in the implementation delete the row from your data source (NSUserDefaults in your case).
So in your tableView's dataSource (ie. in the class you implemented numberOfSectionsInTableView: for example), add your custom implementation of tableView:commitEditingStyle:forRowAtIndexPath: where you delete the underlying data.

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
}