I am stuck in a weird scenario where I need to programmatically dismiss the active UIAlertView from the other viewcontroller by getting the instance.
Actually, I am working on AutoClose feature (working on System.Timer) where when Timer would be elapsed, I need to perform some operation (performs in View Model) and close the active UIAlertView or UIViewController window and Navigate To HomeView.
I am able to do with UIViewController but I couldn't find any way to dismiss the UIAlertView which is presented from another view controller?
Note - I understand this API is deprecated but for using UIAlertController it would lead to ample code changes, and I don't have time to make them.
I am using below method to accomplish but once the AlertView gets dismissed I am unable to click anywhere on screen.
UIWindow window = UIApplication.SharedApplication.KeyWindow;
UIViewController rootViewController=window.RootViewController;
if(rootViewController.ModalViewController is UIAlertController)
{
rootViewController.ModalViewController.DismissViewController(true,null);
}
Also, may I know how do we see the hierarchy of Views in Xamarin Studio?
Try to use the following code:
UIAlertView alertView = new UIAlertView("Title", "Content",this,"OK");
alertView.Show();
UIActivityIndicatorView indicatorView = new UIActivityIndicatorView();
indicatorView.BackgroundColor = UIColor.Red;
indicatorView.Center = new CGPoint(alertView.Bounds.Size.Width / 2,
alertView.Bounds.Size.Height - 40.0);
indicatorView.StartAnimating();
alertView.InsertSubview(indicatorView,0);
And if when you want to Dissmiss the AlertView(for emample in the following code I dissmiss it after 3 seconds):
NSTimer.CreateScheduledTimer(3, (t) =>
{
alertView.DismissWithClickedButtonIndex(0, true);
});
I have asked the same question in Xamarin Forum and I got my answer from one of the Xamarin Professional which I am sharing here.
Dismiss UIAlertView programmatically in Xamarin.iOS
I hope this may help others.
Related
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);
}
}
}
I've searched on SO & elsewhere for MvvmCross & Modal, but the one existing answer isn't helping us.
We're developing a cross-platform app using MonoTouch & MvvmCross, which seems to be pretty powerful combination. However, we're having a few issues with the navigation, which we're gradually cracking! The current problem is -
The app runs with a TabBarController, and each tab has navigation to further levels - this works fine. The client however wants the "Start" button on one of the tabs to bring up a modal view (which hides everything else, especially the tab bar), which then has its own levels working in the same manner as a UINavigationController, with the ability to pop back to the tabBarController at any time.
We've managed to bring up a single modal view, but we're stuck on loading new views from here and popping back out.
Any help/advice appreciated!
I think what you're looking to do is to customise the presenter so that it wraps your UIViewController within a UINavigationController - and then modally presents that UINavigationController?
To achieve this, the code in the recent Pull request from #DeapSquatter might help -https://github.com/slodge/MvvmCross/pull/9 - I think you can use his modal nav presenter in order to achieve the effect you are looking for:
if (view is IMvxModalTouchView)
{
if (_currentModalViewController != null)
throw new MvxException("Only one modal view controller at a time supported");
var newNav = new UINavigationController();
newNav.PushViewController(view as UIViewController, false);
_currentModalViewController = view as UIViewController;
PresentModalViewController(newNav, true);
return;
}
The architecture of mvvmcross is deliberately extensible and configurable here - while we include a few basic Presenter classes, it's very likely that people are going to want to customise how different views get presented on an app-by-app basis. Beyond the simplest of demo apps, I anticipate that most mvvmcross apps on touch will ship with a custom presenter inside.
Hope that helps
Stuart
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.
I have created storyboard using following instructions
http://docs.xamarin.com/ios/tutorials/Introduction_to_iOS_5#Storyboards
It works as expected.
Then I added new button to MonkeyController and new ViewController to storyboard. This is the code I tried to use in button's click event
partial void btnClicked (NSObject sender)
{
UINavigationController ctrl = this.ParentViewController;
var screen = new TableRowViewController();
ctrl.PushViewController(screen, true);
}
It opens TableRowViewController, but it's background is black and it does not show any modifications I made on it on storyboard.
Can you help me with this?
I'm no expert yet, but it has been my experience trying to get it to work properly that if one of the sides of the split-view is black, then there is a segue that is illegal.
Hope that helps...
I have an application which includes a login session. When the application is suspended (iOS 4), I save the current time and if the next time application becomes active is within 15 min from suspension time I want it to resume. Otherwise I want it to go back to login screen since the session is expired.
Here is what I am doing write now to implement it:
In app delegate's applicationDidBecomeActive, I check the time and present the login screen (modally) if needed. However the problem is that if the application was showing an UIAlertView or UIActionSheet when suspended, it will not dismiss it automatically when I present the login screen. The UIAlertView or UIActionSheet will then appear on the login screen which it does not belong to at all. I know I can register each UIAlertView and UIActionSheet to listen to applicationDidBecomeActive and dismiss if needed but since I have many of them all over my application it is really convenient if I can avoid that.
I was wondering if there is a way to dismiss all active views, which will stay on screen even if another view controller is presented modally.
Or if there is any better way to handle session time-outs in iOS 4?
I figured out a way to do this without Notifications (Although notifications are not as difficult as they seem to be):
I added an iVar(s) to each class showing a UIAlertView to hold the currently displaying AlertView. In AlertView's definition:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: ....
[alert show];
self.alertView = alert;
[alert release];
And cleanup the iVar when AlertView is dismissed:
- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)index {
// code goes here
self.alertView = nil;
}
Then in - (void) viewWillDisappear:(BOOL)animated or - (void)dealloc (depending on the situation) I added:
[self.alertView dismissWithClickedButtonIndex:0 animated:YES];
The same can be done for UIActionSheet. Hope this helps.
Please let me know if you have a better solution.