How to manage code in ViewWillDisappear? - ios

I am working in xamarin.ios. I want to show a confirmation popup when user click at back navigation button at top that if user is sure he wants to go back previous screen.
I override the ViewWillDisappear method and called my popup there, but still screen go back to previous screen, before user confirm it from the popup.
Popup shows and behind that screen get move to previous screen.
How I can manage it so that screen can't move until user confirm it from popup?

viewWillDisappear is a function which is already part of a transition, which you can't cancel.
What you can do instead, is hide the backBarButton and instead of it, provide a custom navigationItem.leftBarButton which also has a #IBAction assigned to it.
In the #IBAction you implement the required functionality, like presenting the popup.

You can't do what you want to do in viewWillDissappear. Instead, you can assign a custom action to your back button like this:
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .Done, target: self, action:#selector(self.displayConfirmation(sender:)))
Implement the selector:
func displayConfirmation(sender: AnyObject) {
let alert = UIAlertController(title: "", message: "Go back?", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default, handler: nil))
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default, handler: { action in
self.navigationController?.popViewController(animated: true)
}))
self.present(alert, animated: true, completion: nil)
}

Related

iOS Swift: UIAlertController ignores maximumContentSizeCategory

I'm trying to limit the dynamic text sizes of the UIAlertControllers in my app.
I have tried this:
let alertController = UIAlertController(title: "Test", message: nil, preferredStyle: .actionSheet)
alertController.view.maximumContentSizeCategory = UIContentSizeCategory.extraExtraExtraLarge
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alertController, animated: true, completion: nil)
but the maximumContentSizeCategory is ignored. How can I set a maximum dynamic font size for UIAlertController?
You can't customize a UIAlertController very much. Since it is just a presented view controller, simply write your own custom presented view controller whose view looks like an alert.

Cancel Button is not tappable in custom action sheet

Refer to link UIAlertController - add custom views to actionsheet
for my UI layout.
I have the same layout of custom action sheet in my app. The code is written in the same way. I noticed that in swift4 the "Cancel" button does not perform any action. When I tap on "Cancel" button in code below
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {(alert: UIAlertAction!) in
print("Cancel")
})
The code: print(Cancel") does not execute.
I think you have a problem with a frame of the custom view.
Run you application on a simulator and press "Debug View Hierarchy":
After that you'll can exam frames of views.
Try this handler
UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) -> Void in
print("cancel")
}))

AlertViewController within UIPageViewController

I am building a Swift 3 app with the following Storyboard:
On the left (in green) is a UIPageViewController that holds the 2 NavigationController as 2 pages. This allows the user to swipe between 2 subparts of the app.
The problem is the following. I'm trying to display an alert in tha black UIViewController.
Here is the code to display the alert:
override func viewDidAppear(_ animated: Bool) {
let alert = UIAlertController(title: "Hello", message: "World", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { action in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
It works but I always get the the below warning:
Presenting view controllers on detached view controllers is discouraged
I also tried with DispatchQueue.main.async to present the view but I ran into the same warning.
However what I found is, if I set the NavigationController (bottom one) as the initial view controller, it works without the warning.
So, does using a UIPageViewController mean the pages will be kind of detached ?
What am I missing here ? Do I forgot to link stuff ?
You can try following.
[self.view.window.rootViewController presentViewController:alert animated:YES completion:nil];
When you are done you can dismiss it.
[self dismissViewControllerAnimated:YES completion:nil];
Let me know if this works.

UIAlertController Slow to Appear and Dismiss - Swift

I am developing an iOS app, using Swift, and am having two issues with the UIAlertController being quite slow!
1 - Slow and jittery to appear
I have set up a UITableViewController, and when I tap a cell, it fires the following code:
let alertController = UIAlertController(title: "Enter Exam Grade", message: nil, preferredStyle:UIAlertControllerStyle.Alert)
alertController.addTextFieldWithConfigurationHandler({(textField: UITextField) in
textField.placeholder = "Earned"
textField.keyboardType = .NumberPad
})
alertController.addTextFieldWithConfigurationHandler({(textField: UITextField) in
textField.placeholder = "Out of"
textField.keyboardType = .NumberPad
})
alertController.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.Default, handler: {
(alert: UIAlertAction) in
if let gradeTextField = alertController.textFields!.first as UITextField? {
if let outOfTextField = alertController.textFields!.last as UITextField? {
if (gradeTextField.text != "" && outOfTextField.text != "") {
print(gradeTextField.text)
print(outOfTextField.text)
}
}
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
When I navigate to the view, and tap the cell for the first time, I get a jittery and slow load of the alert, as you can see in the GIF below. Interestingly, subsequent taps load generally smoothly and quickly.
EDIT: The GIF has a framerate a little too slow, so I have attached some stills taken from a slowed down video of it:
a) First tap of "Grade Exam", the alert begins to appear in centre of the screen, but then shifts up (in a jolt) to the correct position).
b) Subsequent taps, the alert appears in the correct upper position from the beginning.
2 - Keyboard slow to dismiss when Alert dismisses
I have seen this issue all around StackOverflow, with no real satisfactory solutions. When you tap the Cancel button, the Alert will dismiss quickly, but then the keyboard takes a long time to dismiss also. This should be instantaneous, as the hanging keyboard leaves a bad impression with users.
The launching of your keyboard seems to be "normal" from the gif files you have provided. However assuming if it is slow, maybe you could try this if it does load faster.
Just to mention I've not tried this code and typing off from here.
For slow display of keyboard.
textField.placeholder = "Out of"
textField.keyboardType = .NumberPad
textField.becomeFirstResponder()
For slow hiding of keyboard.
alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: {
(alert: UIAlertAction) in
self.view.endEditing(true)
}))

Swift, iOS: How to use UIButton to trigger UIAlertController

I want to use an UIButton to trigger a UIAlertController... in Swift
So in this example I have an "Agree" button below some text, and I want the user to click Agree and have a pop-up alert with 2 options confirming/canceling the agreement. How would I go about connecting the UIButton and the UIAlertController. Also if the user cancels, I want the alert to dismiss and remain on the current VC. If the user agrees, I want it to segue to another view controller.
I fairly new to Swift, so if the answer could be detailed that would be extremely appreciated!
You need to add an IBAction (Control drag from your UIButton on your XIB/Storyboard, to the viewController implementation to link the button to the method). Inside the method that you link to the action you need to present the viewController, similar to the below:
func showAlert(sender: UIButton!)
{
var alert = UIAlertController(title: "Title", message: "Some Message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Agree", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}

Resources