GestureRecognizer not working on its first seconds - swift

I am preventing the user from going to the loginViewController from the mainMenuViewController, and it works good.
But if i go to another viewController, pop it to the mainMenu, and press fast the menuButton, it goes to the login instead entering the gestureRecognized func.
I have this code on the viewDidLoad()
let menuPressRecognizer = UITapGestureRecognizer()
menuPressRecognizer.addTarget(self, action: #selector(menuButtonAction(recognizer:)))
menuPressRecognizer.allowedPressTypes = [NSNumber(value: UIPress.PressType.menu.rawValue)]
self.view.addGestureRecognizer(menuPressRecognizer)
And this:
#objc func menuButtonAction(recognizer:UITapGestureRecognizer) {
let allertController=UIAlertController(title: R.string.strings.closeSession(), message: "", preferredStyle: .alert)
allertController.addAction(UIAlertAction(title: R.string.strings.closeSessionConfirm(), style: .default, handler: {_ in
UserDefaults.standard.set(false, forKey: .storedAutoLogin)
self.navigationController?.popViewController()
}))
allertController.addAction(UIAlertAction(title: R.string.strings.cancel(), style: .cancel, handler: nil))
self.present(allertController, animated: true, completion: nil)
}
Tried overriding pressesBegan, but it pop to login after printing "test", so i don't know why it don't override the pop
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
if(presses.first?.type == UIPress.PressType.menu) {
NSLog("test")
} else {
super.pressesBegan(presses, with: event)
}
}

Related

Remove UIAlertController ending animation

In my case, I need to show the user the UIAlertController upside down.
At the time of present, I can avoid the opening animation with:
present(alert, animated: false, completion: {
alert.view.transform = CGAffineTransform(rotationAngle: .pi)
})
At this point, the user sees the inverted UIAlertController.
And at the time of closing, after clicking on Cancel, UIAlertController blinks in the normal position for a hundredth of a second, which slightly spoils the UX.
With this simple example, you can catch this slight blink:
let alert = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)
let action = UIAlertAction(title: "Action", style: .default, handler: { action in })
let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { action in })
alert.addAction(action)
alert.addAction(cancel)
present(alert, animated: false, completion: {
alert.view.transform = CGAffineTransform(rotationAngle: .pi)
})
I tried to call
alert.dismiss(animated: false, completion: nil)
or
alert.view.isHidden = true
inside cancel action, but it didn’t work.
Help me find a way to avoid this annoying end animation.
Just subclass UIAlertController like this:
class InstantCloseAlertController: UIAlertController {
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
UIView.setAnimationsEnabled(false)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
UIView.setAnimationsEnabled(true)
}
}

alert with UIAlertController can't dissmiss it

I'm creating an alert but I can't dismiss it when the user presses OK. I'm getting the following error:
2017-12-28 07:03:50.301947-0400 Prestamo[691:215874] API error:
<_UIKBCompatInputView: 0x10249adc0; frame = (0 0; 0 0); layer =
> returned 0 width, assuming
UIViewNoIntrinsicMetric
I was searching everywhere on the Internet but I couldn't find anything that helped me.
override func viewDidAppear(_ animated: Bool) {
createAlert(title: "Licencia2", message: "En el momento no tienes una licencia válida!")
}
func createAlert (title:String, message:String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {(action) in
alert.dismiss(animated: false, completion: nil)
}))
self.present(alert, animated: false, completion: nil)
}
Any ideas would be appreciated
You don't have to dismiss alert controller. It will automatically dismiss after the action handler has been called. Just remove the dismiss line.
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {(action) in
}))
self.present(alert, animated: false, completion: nil)
Please note the difference with this answer and you code.
You didn't invoked super.viewDidAppear(animated) and this causes problems.
Below code (this is all I used) works for me without problems (I've test it):
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
createAlert(title: "My test", message: "THis should work ok")
}
func createAlert (title:String, message:String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default) {
action in
NSLog("it is working ok");
})
present(alert, animated: true)
}
}

UIAlertController pushes navigation bar item

UIAlewrtController pushes the button in my navigation controller down (see image)
Sequence of execution:
on push + the alert controller is activated
on selecting "Take an Action" or "Request an Action" the view controller ActionDetialsVC is activated.
on showing ActionDetialsVC
on back the ActionDetialsVC is closed
The iitial controlers BACK arrow moved
When putting breakpoints on:
self.present (alert, animated: true, completion: nil)
the first Swift instruction in the 2 alert handlers
The strange navigation back button behavior is visible between these breakpoints.
The issue ONLY occurs when introducing Alert Controllers in my views !!!!!
Thank you for your help
Image of the issue:
The code:
func addPressed(_ sender: Any) {
let alert = UIAlertController (title: "Add an Action", message: nil, preferredStyle: UIAlertControllerStyle.alert)
let request = UIAlertAction (title: actionType.Request.Str(), style: UIAlertActionStyle.default, handler: {
action in
self.actionTypeTemp = actionType.Request.Str()
self.performSegue(withIdentifier: "segueActionDetailsVC", sender: nil)
} )
let take = UIAlertAction (title: actionType.Take.Str(), style: UIAlertActionStyle.default, handler: {
action in
self.actionTypeTemp = actionType.Take.Str()
self.performSegue(withIdentifier: "segueActionDetailsVC", sender: nil)
} )
let done = UIAlertAction (title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil )
alert.addAction(request)
alert.addAction(take)
alert.addAction(done)
self.present (alert, animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueActionDetailsVC" {
if let destination = segue.destination as? ActionDetailsVC {
if let action = sender as? PActions {
destination.actionToEdit = action
}
else {
if actionTypeTemp == actionType.Request.Str() {
destination.relatedContact = self.contact
destination.title = actionType.Request.Str()
}
else {
destination.relatedContact = self.contact
destination.title = actionType.Take.Str()
}
}
}
}
}

uialertcontroller and user agreement

I am trying to show a UIAlertController which will display my terms of service. I can not simply paste the terms of service into the message body, what would be the best way to achieve this. I am also only calling it once on apps first launch.
func agree(){
let alert = UIAlertController(title: "Terms of Service", message:"", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Agree", style: .default, handler: { (action: UIAlertAction) in
print("OK")
}))
self.present(alert, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
if UserDefaults.standard.bool(forKey: "Walkthrough") {
print("already shown")
// Terms have been accepted, proceed as normal
} else {
agree()
UserDefaults.standard.set(true, forKey: "Walkthrough")
}
}

UIAlertController on button click

Opening the UIAlertController on button click, the action is going to open but main issue is the UIAlertAction methods are not performed on its click. Here is Code block :
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// getData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//menuBtn is the button
#IBAction func menuBtn(sender: UIButton) {
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
let orders = UIAlertAction(title: "Orders", style: .Default, handler: { (alert: UIAlertAction!) -> Void in
let alertViewController = self.storyboard?.instantiateViewControllerWithIdentifier("OrdersViewController") as! OrdersViewController
self.presentViewController(alertViewController, animated: true, completion: nil)
})
let about = UIAlertAction(title: "About", style: .Default, handler: {(alert: UIAlertAction!) -> Void in
let aboutObject = self.storyboard?.instantiateViewControllerWithIdentifier("AboutViewController") as! AboutViewController
self.presentViewController(aboutObject, animated: true, completion: nil)
})
let contactUs = UIAlertAction(title: "Contact Us", style: .Default, handler: {(alert: UIAlertAction!) -> Void in
let alertViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContactViewController") as! ContactViewController
self.presentViewController(alertViewController, animated: true, completion: nil)
})
let login = UIAlertAction(title: "LogIn", style: .Default, handler: {(alert: UIAlertAction!) -> Void in
let alertViewController = self.storyboard?.instantiateViewControllerWithIdentifier("LoginViewController") as! LoginViewController
self.presentViewController(alertViewController, animated: true, completion: nil)
})
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
optionMenu.addAction(orders)
optionMenu.addAction(about)
optionMenu.addAction(contactUs)
optionMenu.addAction(login)
optionMenu.addAction(cancelAction)
self.presentViewController(optionMenu, animated: true, completion: nil)
}
This is code is working fine, I have checked it's opening new viewController as well.
Cross check points:
Controller class and stroybaord are connected
Storyboard ID has been assigned
IBAction must be connected to IBOutlet
On the Button click Action you have to write code.. Try This code.
let alert = UIAlertController(title: "Saved", message: "Selected Frame is Saved", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Ok", style:.Default , handler: { (UIAlertAction) in
}))
//Add action like this
self.presentViewController(alert, animated: true, completion: nil)
Still need any help feel free to ask.
First of all check if the button action is touch up inside. Make the button action as touch up inside. Below code works for me. Hope this works for you as well. Change the action title according to your need.
#IBAction func menuBtn(sender: AnyObject) {
let actionSheet = UIAlertController()
let criticalAction = UIAlertAction(title : "CRITICAL" , style : UIAlertActionStyle.Default){
(action) in
//This section will be executed when the buttons are pressed
//Do your work here.
debugPrint("CRITICAL")
}
let highAction = UIAlertAction(title : "HIGH" , style : UIAlertActionStyle.Default){
(action) in
//This section will be executed when the buttons are pressed
//Do your work here.
debugPrint("HIGH")
}
actionSheet.addAction(criticalAction)
actionSheet.addAction(highAction)
self.presentViewController(actionSheet, animated: true, completion: nil)
}