Change UIAlertController Background Tint - ios

Yes, I know. You can't change the appearance of a UIAlertController. I don't want to change the background of the UIAlertController itself, I want to change the tint of the view's background. You know how it's like a transparent black color? I want to change that color to clear. How would I do this?

For swift 3 UIAlertController change background color.
let alert = UIAlertController(title: "validate",message: "Check the process", preferredStyle: .alert)
let dismissAction = UIAlertAction(title: "Dismiss", style: .destructive, handler: nil)
alert.addAction(dismissAction)
self.present(alert, animated: true, completion: nil)
// change the background color
let subview = (alert.view.subviews.first?.subviews.first?.subviews.first!)! as UIView
subview.layer.cornerRadius = 1
subview.backgroundColor = UIColor(red: (195/255.0), green: (68/255.0), blue: (122/255.0), alpha: 1.0)

No you cannot change the transparent background color. That does not belong to part of UIAlertController variable that you can control.
You will have to fix it by presenting a new view controller with a transparent background and a faked alert-controller-like UI element.
To further approve you does not have control for the alert controller, create another view with frame origin on 0,0 and then add to your alert controller's view. It will show on the top left corner of your pop up window, not the window of your window

You can change the background colour as follows:
let alert = UIAlertController(title: "TITLE", message: "My message", preferredStyle: .alert)
if let subview = alert.view.subviews.first?.subviews.first?.subviews.first {
subview.backgroundColor = .red
}
alert.view.tintColor = UIColor.black

Try this..
[alert.view setBackgroundColor:[UIColor whiteColor]];
Try changing whiteColor to whatever colour u wish.
To fix the corner extra color, add corner radius and run.
Hope this helps!

You can create CustomAlertController, set your color in method viewWillAppear and show this controller instead of default UIAlertController. It's bad but working solution.
final class CustomAlertController: UIAlertController {
//MARK: - Lifecycle
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.superview?.backgroundColor = yourColor
}
}

Related

Reposition UIAlertView

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

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
}

UIAlertViewController flickers/blinks briefly

I'm using this swift code to display an alert dialog from a UIViewController
import UIKit
class TestViewController: UIViewController {
#IBAction func onTestClick(sender: UIButton) {
let alertController = UIAlertController(title: "title", message: "message", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
}
When the alert is shown from a view with a dark (e.g. black) background, it briefly "flickers" (appears white and then instantly change to a color slightly darker than white).
This doesn't seem to happen on other apps and the system OS.
What's the problem here?
I was able to reproduce what you are saying and I don't think you are actually doing something wrong. If you turn slow animations on the simulator (cmd + t) you will see the alert controller being positioned in the center of the screen in a fade animation. When the animation is in progress the alert controller has a white background (and this is Apple's code, it's fine) and when the animation finishes the alert controller has a transparent background which will change according to the colour of the view behind it. You don't notice anything when the view is white because white + white = white! :)
I hope that helps.

How do I make a snapshot without the navigation bar in iOS with Swift?

I'm using this function I've found in this site but it saves the whole screen with the navigation bar but no the status bar.
func screenShotMethod() {
let layer = UIApplication.sharedApplication().keyWindow!.layer
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
layer.renderInContext(UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
let alertSaved = UIAlertController(title: "Saved", message: "", preferredStyle: .ActionSheet)
alertSaved.addAction(UIAlertAction(title: "Ok", style: .Default, handler: {action in
self.view.removeGestureRecognizer(self.gesture)
}))
presentViewController(alertSaved, animated: true, completion: nil)
}
What I need is just take a snapshot from the end of the navigation bar to the bottom.
If you change the layer you are attempting to screenshot from the keyWindow's view to your view controller's view, the navigation bar (assuming you have your view controller embedded in a navigation controller rather than adding a nav bar as a subview of your view) and the status bar will be omitted from the screenshot.
let layer = view.layer
If you have blank space at the top where the navigation bar was, you can adjust the frame to cut this out.

How to create modal list in Swift/iOS

I'm trying to recreate a modal list popover in Swift, similar to the ones found in other several popular applications. See below for examples.
My current attempt looks like this:
#IBAction func showListOptions(sender: AnyObject) {
// segue set to "Present Modally"
// Presentation set to "Over Current Context"
self.performSegueWithIdentifier("ShowListItems", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var vc = segue.destinationViewController as! UIViewController
vc.view.backgroundColor = UIColor(red:0, green:0, blue:0, alpha:0.3)
}
The next view is a regular ViewController with a few buttons with their layout relative to the bottom of the screen.
A few things to note, when I set the Presentation style of the segue to "Full Screen", the background turns full black (instead of the desired alpha (rgba(0, 0, 0, 0.3)).
Setting the Presentation to "Over Current Context", I at least get the alpha color background, but I'm still able to click around on my tabbar at the bottom... which then turns my modal back to a black screen.
Help is much appreciated! Thank you.
In the second example is an UIActionSheet (easier to implement).
The first one is an UIView with low alpha (about a BlackColor with 0.5 alpha) with an UITableView constrained to bottom, trailing and leading. That with a keyframe animation. Using a UIViewController isn't the easiest approx. on this situation.
If you are targeting iOS 7.0 and up then you can do UIActionSheet
let myActionSheet = UIActionSheet()
myActionSheet.delegate = self
myActionSheet.addButtonWithTitle("Add event")
myActionSheet.addButtonWithTitle("close")
myActionSheet.cancelButtonIndex = 1
myActionSheet.showInView(self.view)
func actionSheet(myActionSheet: UIActionSheet!, clickedButtonAtIndex buttonIndex: Int){
if(myActionSheet.tag == 1){
if (buttonIndex == 0){
println("Do something")
}
}
}
if you are targeting iOS 8.0 and up then do UIAlertController
let myAlertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
let otherAction = UIAlertAction(title: "other", style: .Default, handler: otherHandler)
myAlertController.addAction(cancelAction)
myAlertController.addAction(otherAction)
self.presentViewController(myAlertController, animated: true, completion: nil)
func otherHandler(alertAction: UIAlertAction) {
//Do something when other button is tapped
}
Thanks to #pbush25 - what I am really looking for is a UIAlertController of type ActionSheet. This ultimately does all the work for you :)
The tutorial (written in Swift for iOS 8) can be found here http://ioscreator.com/tutorials/action-sheet-tutorial-ios8-swift

Resources