Example of UITextField ResignFirstResponder with Monotouch - iphone

I'm a newbie. I can't figure out how and where to call ResignFirstResponder to get rid of the keyboard when the user finished entering the text in an UITextField. I'm a bit confused by the UIResponder class. Mono documentation says: "To dismiss the keyboard, send the UIResponder.ResignFirstResponder message to the text field that is currently the first responder." How to do so? Can someone post a simple working example? There are many examples in Obj-C but none in C#. Many thanks.

Here's an example I've done recently:
private UITextField _textField;
public override void ViewDidLoad()
{
_textField = new UITextField();
_textField.Text = "King Alfonso III";
_textField.Bounds = bounds;
_textField.Placeholder = "Username";
_textField.ShouldReturn = delegate
{
_textField.ResignFirstResponder();
return true;
};
View.AddSubview(_textField);
}
Also if you are submitted a form with a button, make sure you resign all the textfields in the button click, to avoid getting responder errors.
public void ButtonClick(object sender, EventArgs e)
{
_textField.ResignFirstResponder();
// All other textboxes
// Other button logic
}

Related

Have webview selection and swipe at the same time

I have a webview containing some text. I need to be able to swipe on the webview and make text selection at the same time. The problem is after I have implemented the swipe overriding the onTouchEvent method, the other features of the webview seem to have freezed, links in the webview aren't clickable anymore, and the text selection (after longClick) doesn't work anymore, I need to make to implement the swipe and preserve the other features of the webview.
I tried to override the longClick click method as well and use the following method to implement text selection:
public void selectAndCopyText() {
try {
Method m = WebView.class.getMethod("emulateShiftHeld", null);
m.invoke(MyWebView.this, null);
}
catch (Exception e1) {
e1.printStackTrace();
KeyEvent shiftPressEvent = new KeyEvent(0,0,KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_SHIFT_LEFT,0,0);
shiftPressEvent.dispatch(this);
}
}
but it didn't work for when this method is called I only get the upper bar for copy/ paste/ search/ websearch... but no actual selection on the webview occur.

Monotouch Achievements and leaderboard viewcontrollers

Im having an odd issue with dismissing my achievements and leaderboard viewcontrollers.
The viewcontrollers display correctly and can be dismissed using the done button but only if you press it within about 15 secs of it being displayed, if you press done anytime after that my app just crashes. In the debugger i get a "unrecognized selector sent to instance" error.
I was guessing maybe the viewcontrollers are being garbage collected or something? I'd really appreciate any advice.
heres my code
public void checkAchievements(UIViewController view)
{
GKAchievementViewController gkview = new GKAchievementViewController();
view.PresentModalViewController(gkview,true);
gkview.Delegate = new gkviewdelegate();
}
public class gkviewdelegate : GKAchievementViewControllerDelegate
{
public override void DidFinish (GKAchievementViewController viewController)
{
viewController.DismissModalViewControllerAnimated(true);
Console.WriteLine("Dismiss Leaderboard");
}
}
Your gkview is getting garbage collected. Change it to an instance variable instead in your class to keep a reference to it.
So your code should look a little like;
GKAchievementViewController gkview;
public void checkAchievements(UIViewController view)
{
gkview = new GKAchievementViewController();
view.PresentModalViewController(gkview,true);
gkview.Delegate = new gkviewdelegate();
}

Why does my UIButton delegate have to execute entirely before changes are shown in view?

I'm doing some MonoTouch development, and I really can't figure out an problem I've run into
I'm having an ViewController containing a UIButton. I have added a delegate to the TouchDown event of this button. In this delegate I'm calling a WebService and trying to change the colour and title of the button. However nothing happens to the button before the entire delegate have been executed. The thing is that the webservice is rather slow, so I want to give the users a waiting message by changing the colour and title of the button.
The code:
public override void ViewDidLoad ()
{
View.BackgroundColor = UIColor.Black;
bookButton = new UIButton( new RectangleF(10,100,this.View.Frame.Width-10 ,40) );
bookButton.BackgroundColor = UIColor.Clear;
setButton();
bookButton.TouchDown += delegate {
gymClass.book();
setButton();
tableView.ReloadData();
NavigationController.PopViewControllerAnimated( true );
};
this.View.AddSubview( bookButton );
}
Anyone, please?
The delegate is executed on the main thread which is responsible for rendering, so you are blocking the renderer until you return.

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
}

How to detect keyboard events on hardware keyboard on iPhone (iOS)

I have an app with a login page that has three fields for three different random characters. When the user leaves the last field, the soft keyboard disappears and the user can touch a "login" button on screen.
When there is a hardware keyboard (bluetooth or physical) attached, I'd like to be able to hit "enter" on it. However because the user is not in a field, I can't see how to detect this key being pressed.
Would anyone have advice on which class handles key press events? Presumably there is a delegate that I can use to receive these but my searches through the SDK haven't found anything.
Thanks
For iOS 7.0 or later, you can return UIKeyCommands for the keyCommands property from any UIResponder, such as UIViewController:
Objective-C
// In a view or view controller subclass:
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (NSArray *)keyCommands
{
return #[ [UIKeyCommand keyCommandWithInput:#"\r" modifierFlags:0 action:#selector(enterPressed)] ];
}
- (void)enterPressed
{
NSLog(#"Enter pressed");
}
Swift
// In a UIView/UIViewController subclass:
override var canBecomeFirstResponder: Bool {
true
}
override var keyCommands: [UIKeyCommand]? {
return [ UIKeyCommand(input: "\r", modifierFlags: [], action: #selector(enterPressed)) ]
}
#objc func enterPressed() {
print("Enter pressed")
}
One way to accomplish this is to have a hidden extra (4th in your case) text field. Make it 1x1 px in size and transparent. Then make it the first responder when any of your other 3 text fields are not, and look for text change events in that hidden field to trigger your key input event.
You might also want to check the notification for a software keyboard appearing if you don't want it to stay visible as well.
As a followup to the response by #Patrick, here is how you do it in Xamarin.iOS:
public override bool CanBecomeFirstResponder
{
get { return true; }
}
public override UIKeyCommand[] KeyCommands
{
get
{
return new[]{ UIKeyCommand.Create((NSString)"\r", (UIKeyModifierFlags)0, new ObjCRuntime.Selector("enterPressed")) };
}
}
[Export("enterPressed")]
private void OnEnterPressed()
{
// Handle Enter Key
}