Reposition UIAlertView - ios

I am want to simple a UIAlertView on the bottom of the screen when opening a ViewController.
Right now, I create an alert view, show it after 2 seconds and hide the alert.
However, the alert view only shows in the center of the screen.
How do I reposition it on the bottom of the screen?
Here is my code:
let alert = UIAlertController(title: "", message: "Please Swipe To Refresh After 2 seconds", preferredStyle: .alert)
alert.view.frame.origin.x = 150
alert.view.frame.origin.y = 250
self.present(alert, animated: true, completion: nil)
let indicator = UIActivityIndicatorView(frame: alert.view.bounds)
indicator.autoresizingMask = [.flexibleWidth, .flexibleHeight]
alert.view.addSubview(indicator)
indicator.isUserInteractionEnabled = false
indicator.startAnimating()
let when = DispatchTime.now() + 2
DispatchQueue.main.asyncAfter(deadline: when) {
alert.dismiss(animated: true, completion: nil)
}

You can't move and UIAlertControllerwith its presentation style set and even if there will be a workaround don't use it. In order to achieve what you want you have different options:
Use a simple UIView subclass that simply requires in the show method the view you want to use as a super view
Create a UIViewController subclass and present it using a UIPresentationController, this could be pretty hard if you are new to iOS development
Use one of the already available libraries on github, for instance this

Use (.... , preferredStyle: .actionSheet) in the constructor of UIAlertController

Related

Adding an activity indicator to a UIAlertController

I implemented the accepted answer from here How to display activity indicator in center of UIAlertController?
But it doesn't work, all that is displayed is the title "Creating New User" and no activity indicator is displayed. While running in the debugger I noticed that with the posted code indicator by default has its visibility set to false, so I explicitly added a line to set it to true, but it made no difference.
Here then is the code from the accepted answer, with that additional line added. Why is the activity indicator not displayed?
func displaySignUpPendingAlert() -> UIAlertController
{
//create an alert controller
let pending = UIAlertController(title: "Creating New User", message: nil, preferredStyle: .alert)
let indicator = UIActivityIndicatorView(frame: pending.view.bounds)
indicator.autoresizingMask = [.flexibleWidth, .flexibleHeight]
//add the activity indicator as a subview of the alert controller's view
pending.view.addSubview(indicator)
indicator.isUserInteractionEnabled = false // required otherwise if there buttons in the UIAlertController you will not be able to press them
indicator.isHidden = false
indicator.startAnimating()
self.present(pending, animated: true, completion: nil)
return pending
}

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.

Swift - How do I place a page-view within a UIAlertController?

I am using Swift 3, Xcode 8.2.
I have an application where the user launches the iPhone camera and I give them a popup with instructions on how to take a good picture. I want there to be a way to create pages within the UIAlertController. I did a quick sketch of what I want to achieve.
Code wise, I am not sure what to do:
func displayInstructions() {
let insController = UIAlertController(title: "Instructions", message: "Step 1: Do this.", preferredStyle: .alert)
let actionDone = UIAlertAction(title: "OK", style: .cancel) { (action:UIAlertAction) in
//This is called when the user presses the cancel button.
print("You've pressed the done button");
}
//Add the buttons
errorController.addAction(actionDone)
// Some way to addSubviews here??
let pageViewController: UIPageViewController
insController.addSubview(pageViewController)
//Present the instruction controller
self.present(insController, animated: true, completion: nil)
}
Any help would be greatly appreciated. Thank you!
There is a property on UIAlertController, not advertised in public API but that seem usable without trouble going through the app store review. So, using KVC, you can set the contentViewController of the alert controller.
let pageViewController: UIPageViewController
// configure pageViewController...
insController.setValue(pageViewController, forKey: "contentViewController")
You can also set the size of the contentViewController by setting preferredContentSize.height on it
pageViewController.preferredContentSize.height = 180
This is what the result looks like with an empty page view controller

Trouble with UIAlerts

I have been having some trouble making UIAlerts work. I have looked at a couple SO questions that seem to solve this issue yet I still have a problem. The alert view seems to not be presented. Here is my code:
var inputTextField: UITextField?
let actionSheetController: UIAlertController = UIAlertController(title: "Create a password", message: "", preferredStyle: .Alert)
let save: UIAlertAction = UIAlertAction(title: "Save", style: .Default) { action -> Void in
if !(inputTextField?.text=="password"){
println(inputTextField?.text)
}else{
println("You have a really bad password")
}
}
actionSheetController.addAction(save)
actionSheetController.addTextFieldWithConfigurationHandler { textField -> Void in
inputTextField = textField
}
self.presentViewController(actionSheetController, animated: true, completion: nil)
Here is the error:
Attempt to present <UIAlertController: 0x7fa7016305e0> on <PassProtect.ViewController: 0x7fa701576600> whose view is not in the window hierarchy!
Does anybody know why this is not being presented?
Any help or advice is greatly appreciated!
It's to do with the fact that when you make the call to present the UIAlertController, self.view is not on screen. If you are writing this code in the viewDidLoad() section, this won't work as self.view is still off screen.
You can make this call once self.view is available, for example in viewDidAppear() or from any sort of UI action like clicking a button. Basically, anything that will occur before viewDidDisappear().
There is a similar question with similar information if you want to read it and also here for a more generalised case, i.e. trying to present any sort of view controller which isn't in the view hierarchy.

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