iOS Swift: UIAlertController ignores maximumContentSizeCategory - ios

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.

Related

How to manage code in ViewWillDisappear?

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)
}

Display alert from custom cell in swift 3

I have designed custom cells in listViewCell.swift and listViewCell.xib. In which i have textfield. When the user enters a number more than 100 then i want to show alert.
I have tableView in HomeViewController.
let alert = UIAlertController(
title: "Error",
message: "Please Insert value less than 100",
preferredStyle: UIAlertControllerStyle.alert
)
alert.addAction(UIAlertAction(
title: "Click",
style: UIAlertActionStyle.default,
handler: nil
))
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
then it gives me Attempt to present <UIAlertController: 0x7f945a5a67d0> on <ProjName.LoginController: 0x7f945a407e70> whose view is not in the window hierarchy!
and when i change the code to
let alert = UIAlertController(
title: "Error", message: "Please Insert value less than 100",
preferredStyle: UIAlertControllerStyle.alert
)
alert.addAction(UIAlertAction(
title: "Click",
style: UIAlertActionStyle.default,
handler: nil
))
HomeViewController().present(alert, animated: true, completion: nil)
then it gives me unexpectedly found nil while unwrapping an Optional value
and points to
override func viewDidLoad() {
super.viewDidLoad()
**tableViewList.delegate = self**
tableViewList.dataSource = self
searchBar.delegate = self
}
How can i show a alert from a custom cell? or how can we create a common alert function in HomeViewController and show it form any swift file?
Thanks in Advance
You could go with making delegates of your custom cell. Set the delegate of your custom cells, let's say didEnterInvalidValue didEnterValidValue, to your HomeViewController. From those delegate implementations, show your UIAlertController with custom messages.
Or you can iterate over your self.navigationController?.viewControllers to find the top view controller and show UIAlertController on that view controller's view.
Most easiest would be
Step 1:
From your View controller where you have used your custom Cell, make a common delegate function for your textField which purpose is to notify you about text length.
You may need to extend UITextFieldDelegate for this.
Or u can assign a target function to your textField(Not sure if it works though)
How do you catch Specific TextField?
You need to assign a tag for every textField using indexPath and catch that specific textField using that tag.
Step 2:
In that function you can show your alert by only using
self.present(alert, animated: true, completion: nil)
I would go for the delegate answer. But for a faster solution, at several projects I create a singleton from the rootViewController (generally the UINavigationController) at AppDelegate so it can get the rootController any time. Using keyWindow, it's not very recommended since the keyWindow it's not always the one controlled by who, for example, alert dialog redefine it.
Another projects I create a AlertClass singletone, where it's initialised by the rootController, and it's always invoked from it.

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.

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)
}

iOS UIAlertview with uitextview editable

I'm searching for a way of putting an UITextView editable inside an UIAlertView.
I know how to put a simple textfield with :
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
But this isn't what i want. I want a bigger text input so a user can write a comment after a news for example.
Is this possible ?
Unfortunately what you are after isn't possible with a UIAlertView.
Apple don't allow developers to modify the view hierarchy of a UIAlertView or subclass it. Check out the Apple Documentation for UIAlertView. Under the section marked Subclassing note you will find
The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.
Unfortunately though because UIAlertView still has the addSubview: method so it contradicts what Apple are actually telling us but the reason this is still here is because UIAlertView is a subclass of UIView which has this method. So what Apple have done is they have overridden this method so that it does absolutely nothing so when you call [myAlertView addSubview:myView]; will do nothing and no view will be added to the UIAlertView.
So to get the behavior you are after you will need to implement a Custom AlertView (Check out Google search for Custom UIAlertView).
Fortunately in iOS 8 Apple introduced a new class called UIAlertController that allows you to get the behavior that you are after and they have deprecated the UIAlertView class.
Add a custom view into the alert view.
Change preferredStyle to .alert and .actionsheet as per the requirement.
func showPopUpWithTextView() {
let alertController = UIAlertController(title: "\n\n\n\n\n\n", message: nil, preferredStyle: .actionSheet)
let margin:CGFloat = 8.0
let rect = CGRect(x: margin, y: margin, width: alertController.view.bounds.size.width - margin * 4.0, height: 100.0)
let textView = UITextView(frame: rect)
textView.backgroundColor = .clear
alertController.view.addSubview(textView)
let submitAction = UIAlertAction(title: "Something", style: .default, handler: {(alert: UIAlertAction!) in print("Submit")
print(textView.text)
})
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {(alert: UIAlertAction!) in print("cancel")})
alertController.addAction(submitAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion:{})
}

Resources