How to display activity indicator in center of UIAlertController?
Be sure to set the frame property when you're creating a view.
func displaySignUpPendingAlert() -> UIAlertController {
//create an alert controller
let pending = UIAlertController(title: "Creating New User", message: nil, preferredStyle: .Alert)
//create an activity indicator
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.startAnimating()
self.presentViewController(pending, animated: true, completion: nil)
return pending
}
To @62Shark:
let pending = UIAlertController(title: "Creating New User", message: nil, preferredStyle: .Alert)
let indicator = UIActivityIndicatorView()
indicator.setTranslatesAutoresizingMaskIntoConstraints(false)
pending.view.addSubview(indicator)
let views = ["pending" : pending.view, "indicator" : indicator]
var constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[indicator]-(-50)-|", options: nil, metrics: nil, views: views)
constraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|[indicator]|", options: nil, metrics: nil, views: views)
pending.view.addConstraints(constraints)
indicator.userInteractionEnabled = false
indicator.startAnimating()
self.presentViewController(pending, animated: true, completion: nil)
How do I put a UIActivityIndicatorView in a UIAlertController?
Like JonasG mentioned here there is a property named contentViewController
and we can use KVC for access
Example :
UIViewController *v = [[UIViewController alloc] init];
v.view.backgroundColor = [UIColor redColor];
[alertController setValue:v forKey:@"contentViewController"];
So here is how your code should looks like (tested and works fine) :
- (IBAction)buttonClicked:(id)sender
{
self.alertController = [UIAlertController alertControllerWithTitle: @"Loading"
message: nil
preferredStyle: UIAlertControllerStyleAlert];
[self.alertController addAction:[UIAlertAction actionWithTitle: @"Cancel" style: UIAlertActionStyleCancel handler:nil]];
UIViewController *customVC = [[UIViewController alloc] init];
UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
[customVC.view addSubview:spinner];
[customVC.view addConstraint:[NSLayoutConstraint
constraintWithItem: spinner
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:customVC.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f]];
[customVC.view addConstraint:[NSLayoutConstraint
constraintWithItem: spinner
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:customVC.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0f
constant:0.0f]];
[self.alertController setValue:customVC forKey:@"contentViewController"];
[self presentViewController: self.alertController
animated: true
completion: nil];
}
You can override
-preferredContentSize
to return a custom size in the
view controller that you are setting ascontentViewController
.
in our case it's customVC
Result:
Want the text to be below the indicator ?
I have created a UIViewController
with an xib
to act as a custom controller for our contentViewController
in the first example we have created the view controller without xib file, Now we can add views using interface builder, I have added an Activity indicator and set the constraints to be centered horizontally and vertically and a label under the activity indicator which is centered horizontally here is my interface builder:
we have less code now:
- (IBAction)buttonClicked:(id)sender
{
self.alertController = [UIAlertController alertControllerWithTitle: nil
message: nil
preferredStyle: UIAlertControllerStyleAlert];
MyCustomViewController *v = [[MyCustomViewController alloc] init];
[self.alertController setValue:v forKey:@"contentViewController"];
[self presentViewController: self.alertController animated: true completion: nil];
}
Result :
How do I display an Activity Indicator Alert Controller while running a time-consuming function?
As the link ebby94 posted in his comment says, you should really avoid running a time-consuming task on the main thread. It freezes the UI, and the system Springboard will eventually terminate your app as hung if you take too long.
You should really run your long-running task on a background task. I can't really explain that in any detail without more information.
If you are determined to run your time-consuming task on the main thread then you need to start the activity indicator spinning, then return and give the event loop time to actually start the animation before your task begins. Something like this:
activityIndicator.startAnimating()
DispatchQueue.main.async {
//Put your long-running code here
activityIndicator.stopAnimating()
}
The code inside Dispatch will still be run on the main thread, but first the run loop will get a chance to start the activity indicator.
Adding Activity Indicator to UIAlertView
try this code!!
var alert: UIAlertView = UIAlertView(title: "Title", message: "Please wait...", delegate: nil, cancelButtonTitle: "Cancel")
var loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 50, y: 10, width: 37, height: 37)) as UIActivityIndicatorView
loadingIndicator.center = self.view.center
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
loadingIndicator.startAnimating();
alert.setValue(loadingIndicator, forKey: "accessoryView")
loadingIndicator.startAnimating()
alert.show();
I hope I helped you
swift: activity indicator after alert controller
The UI won't respond immediately after you do this:
self.view.addSubview(activityIndicator)
It will not update the UI until the next frame. During the time between this frame and the next frame, you already started to do the time-consuming function and starts it synchronously, so your UI freezes. The next frame is drawn when that finishes executing.
You need to do the work asynchronously:
DispatchQueue.main.async {
[weak self] in
self?.timeConsumingFunc()
self?.activityIndicator.stopAnimating()
}
or on a different dispatch queue altogether.
How can an activity indicator in a button be positioned a certain distance before the button text
The text is button's titleLabel
. So you can position something relative to that easily.
How to display activity indicator in center of tableview footer center?
For example you can center it programmatically like this:
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if section == 0 {
let footerView = UIView(frame: CGRect.zero)
footerView.backgroundColor = UIColor.grayColor()
let activityView = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
footerView.addSubview(activityView)
activityView.startAnimating()
activityView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(
item: activityView,
attribute: .CenterX,
relatedBy: .Equal,
toItem: footerView,
attribute: .CenterX,
multiplier: 1.0,
constant: 0.0
).active = true
NSLayoutConstraint(
item: activityView,
attribute: .CenterY,
relatedBy: .Equal,
toItem: footerView,
attribute: .CenterY,
multiplier: 1.0,
constant: 0.0
).active = true
return footerView
} else {
return nil
}
}
How use alert and spinner in same class?
If you call stopActivityIndicator
before activityIndicator
then transparentView
will be nil. So don't use implicitly unwrapped optional.
Change
var transparentView:UIView!
to
var transparentView:UIView?
and use optional chaining when using this var
self.transparentView?.removeFromSuperview()
And use guard let to get the key window
guard let window = UIApplication.shared.keyWindow else {
return
}
UIViewController Extension for Alert
extension UIViewController {
func showAlert(title: String, msg: String) {
DispatchQueue.main.async {
let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
You can call this method from any view controller like this. It will present on top of all view and navigation bar.
self.showAlert("Alert", msg: "Alert message")
Related Topics
Ios 8.1 Simulator Always Uses Us Keyboard Layout Despite German Hardware Keyboard
How to Change My iOS Applications' Entitlements
App Crashed in iOS 6 When User Changes Contacts Access Permissions
App Rejected Because of Advertisingidentifier in Facebook Sdk and Flurry Sdk
How to Find Bluetooth Audio Devices in iOS
Uitableview with Multiple Sections Using Realm and Swift
My App Was Just Rejected for Using the Ad Support Framework. Which Library Is Responsible
Pod Install -Bash: Pod: Command Not Found
Ios6 Udid - What Advantages Does Identifierforvendor Have Over Identifierforadvertising
How to Mask a Square Image into an Image with Round Corners in iOS
iOS Enterprise Distribution Through Ota
How to Use Namespaces in Swift
Why Maskstobounds = Yes Prevents Calayer Shadow
How to Fetch All Contacts Record in iOS 9 Using Contacts Framework