MonoTouch.Dialog: Dismissing keyboard by touching anywhere in DialogViewController - xamarin.ios

NOTE: There are two similar SO questions (1) (2), but neither of them provides an answer.
TL;DR: How can one dismiss the keyboard in a MonoTouch.Dialog by letting the user touch any empty space in the view?
I'm writing an app using MonoTouch.Dialog and a UITabBarController. One of my tabs is "Settings"...
When the user starts typing, the keyboard obstructs the tabbar...
Using MonoTouch.Dialog, the only way to dismiss the keyboard is to go to the last field and press the "return" key. Considering the fact that the user cannot press any tab until the keyboard is gone, I would like a better way to do it. Namely, to dismiss if the user taps anywhere else on the screen.
Without MonoTouch.Dialog, it's a snap: simply override TouchesBegan and call EndEditing. But this doesn't work with MT.D. I've tried subclassing DialogViewController and overriding TouchesBegan there, but it doesn't work. I'm currently at a loss.
Or, I wonder, would I be better off ditching the tabbar so I can use a UINavigationController with a "Back" button on top, which won't be hidden by the keyboard?

I suggest you use a tap gesture recognizer that will not cause interference with the TableView event handlers:
var tap = new UITapGestureRecognizer ();
tap.AddTarget (() => dvc.View.EndEditing (true));
dvc.View.AddGestureRecognizer (tap);
tap.CancelsTouchesInView = false;

You missed my question about it also: Can the keyboard be dismissed by touching outside of the cell in MonoTouch.Dialog?
:-)
This is my #1 feature request for MonoTouch.Dialog.
To answer your question: No. It is not possible. I have searched and asked around and have not found any answers.
I assume because it is just a sectioned (grouped) table and if it wasn't sectioned, there wouldn't be any spot to click. However, that is just my speculation.
I wish that miguel or someone that works on monotouch would answer this and say if it is even possible. Possibly a future enhancement?

I figured out a workaround that satisfies me well enough, so I'm answering my own question.
// I already had this code to set up the dialog view controller.
var bc = new BindingContext (this, settings, "Settings");
var dvc = new DialogViewController (bc.Root, false);
// **** ADD THIS ****
dvc.TableView.DraggingStarted += (sender, e) => {
dvc.View.EndEditing (true);
};
This will dismiss the keyboard whenever the user drags the view a little bit. There's no touch event I could find associated with the tableview, so this is the next best thing. I'd welcome any other ideas. Cheers!

One workaround to use the dragging gesture instead of the tap as proposed (that do not interfere with the table view gestures) is to override MonoTouch.Dialog.DialogViewController.SizingSource (or MonoTouch.Dialog.DialogViewController.Source if you don't want uneven rows) and give it to the DialogViewController. I don't know if it is very clean or safe.
public class CustomTableViewSource : MonoTouch.Dialog.DialogViewController.SizingSource
{
public CustomTableViewSource(MonoTouch.Dialog.DialogViewController dvc) : base(dvc)
{
}
public override void DraggingStarted(UIScrollView scrollView)
{
base.DraggingStarted(scrollView);
if (scrollView != null)
{
scrollView.EndEditing(true);
}
}
}

Related

Entering newline in a cedit control

A very straightforward question....
How do you enter a new line in a CEdit control box without it triggering OK and closing the dialog box altogether? What I mean is when you hit the enter key it automatically selects OK, even if your cursor is still in the CEdit control. Is what I am trying to do possible? Or do i have to use some other control
PS: It is a modal dialog box btw.
There are various solutions for this problem.
Basically what you need is the ES_WANTRETURN style on the edit control.
Another solution is to check the message and key in PreTranslateMessage (since it has been commented upon this is not the recommended way, I'm just mentioning it for possibilities):
BOOL CYouDialog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN &&
GetFocus() == youcontrol)
{
return TRUE;
}
return FALSE;
}
The other solution is to handle WM_GETDLGCODE. You should subclass the edit control and do this:
UINT CYourEdit::OnGetDlgCode()
{
return CEdit::OnGetDlgCode() | DLGC_WANTALLKEYS;
}
UPDATE: FYI, also have a look at Just because you're a control doesn't mean that you're necessarily inside a dialog box.
The default dialog processing, as you've discovered, is to close a dialog box when enter is pressed. MFC actually executes the OnOK processing, but you can override that. Here's and old explanation, but, it's still relevant.

MonoTouch tracking movement over controls

I have a simple iPhone app with a simple view and a custom view as a child. The child is just a square painted on the main view.
I need to track a touch event that enters this child view but from a touch that started outside the view.
What I've tried so far is to add the TouchesBegin/TouchesMoved events to the parent view. Also tried to add the to the child controls directly but that doesn't track any touches that are not initiated within that control.
The questions are:
a) can I get the control from Position somehow?
b) is this the best way doing this, or is there another way?
Again, I include this video of GamePlay for the game I'm trying to port (on my spare time). It's not a promotion attempt but illustrates what I'm trying to accomplish. I wrote the Win8 and WP7 version of the game so I'm not trying to copy another persons work here. :) Don't watch it if you don't want to know what game it is. The question is still valid without watching this.
http://www.youtube.com/watch?v=13IczvA7Ipo
Thanks
// Johan
I stumbled on the answer myself. In the parent I override TouchesMoved (and Begin and Ended not shown here).
I then iterate the subviews and chech if it's the view I'm looking for by type and then check if the Frame contains the point. The code below is just concept of course.
public override void TouchesMoved (NSSet touches, UIEvent evt)
{
base.TouchesMoved (touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null) {
var rp = touch.LocationInView (touch.View);
foreach(var sv in this.View.Subviews)
{
if(!(sv is LetterControl))
continue;
if(sv.Frame.Contains (rp))
{
Console.WriteLine("LetterControl found");
}
}
}
}

Hide tabbar and navigationbar when view is tapped in monotouch

I need to be able to hide the navbar and tabbar when I tap on the view and show it again when tapped again. Is this possible in Monotouch?
Anything that is possible with the native platform is possible with MonoTouch.
There are dozens of ways of achieving this. Perhaps the simplest thing to do is to create your own UIViewController that will host only the information you want and calling:
var myNewController = new MyNewController ()
myNewController.View.TouchDown += delegate {
myNewController.DismissViewControllerAnimated (false);
};
PresentModalViewController (yourNewController, false);
Then your myNewController must contain some code to add the actual contents that you want to show in full screen.

How to use UITableViewDelegate.AccessoryButtonTapped (with Monotouch)

I'm creating an IPad application using C#, Mono develop and Monotouch.
I've been using Monotouch.Dialog to create functionality similar to the wifi-settings on an iPhone. I'm using StyledStringElement with an accessory and am now trying to differentiate between tapping the row and tapping the DetailDisclosureButton.
I've been found out that I should override the UITableViewDelegate.AccessoryButtonTapped on the UITableView. I've tried to created a derived class from UITableViewDelegate and hook this into the Monotouch.Dialog. But this is where I got stuck. I didn't manage to replace the existing UITableViewDelegate with my extended version.
So my questions are:
Is this the preferred way of handling this event (to be able to differentiate between a tap on the element and a tap on the DetailDisclosureButton) ?
If not, any pointer on how to accomplish this ?
I have been searching the web for a (similar) example but have not found any yet. Any examples that you know of that could get me started ?
Thanks,
boris
event EventHandler accessoryPushed;
public override void AccessoryButtonTapped (UITableView tableView, NSIndexPath indexPath)
{
if(!accessoryPushed)
{
accessoryPushed(this,EventArgs.Empty);
}
}
You will need to add this to the DailogViewController code that you are using (this will override the tapping action). Instead of a simple function, you may want an event to be triggered, so just handle the event in your main code. That is probably your best bet.
Once you change this line, you will have to implement new functions like AccessorySelected (just mimic the path the code follows when a row is selected except with accessory).
On the other hand, you could try a different navigation method, often disclosure buttons are annoying and you don't want to click on them except to get simple information about the button (like a help feature).
I haven't found any other examples, sorry!

Can I dismiss the iPhone keyboard by touching the background of DialogViewController (MonoTouch.Dialog)? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
MonoTouch.Dialog: Dismissing keyboard by touching anywhere in DialogViewController
I'm using DialogViewController from MonoTouch.Dialogs. I'd like to be able to dismiss the keyboard by clicking on the background of the dialog.
I usually employ the technique of filling the view with a large custom button and placing it behind all the other elements. However, I can't make this work in the DialogViewController. I did this in LoadView and it just froze all the other controls.
Is there a relatively straightforward way of achieving what I want?
In view controller:
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
myField.ResignFirstResponder();
}
Edit: From what I've read, you can use the TouchesBegan event for the cell subview instead of the table itself. I'm not positive that works. Good luck :)
miguel.de.icaza answered this question on a different thread:
https://stackoverflow.com/a/10864640/1134836.
His solution:
var tap = new UITapGestureRecognizer ();
tap.AddTarget (() =>{
dvc.View.EndEditing (true);
});
dvc.View.AddGestureRecognizer (tap);

Resources