how to show UITableview in UIAlertcontroller in swift iOS? - ios

I am very new to swift coding so I want to know that is there any way to show tableview in alertcontroller using swift.

var alrController = UIAlertController(title: "\n\n\n\n\n\n", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
let margin:CGFloat = 8.0
let rect = CGRectMake(margin, margin, alrController.view.bounds.size.width - margin * 4.0, 100.0)
var tableView = UITableView(frame: rect)
tableView.delegate = self
tableView.dataSource = self
tableView.backgroundColor = UIColor.greenColor()
alrController.view.addSubview(tableView)
let somethingAction = UIAlertAction(title: "Something", style: UIAlertActionStyle.Default, handler: {(alert: UIAlertAction!) in println("something")})
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: {(alert: UIAlertAction!) in println("cancel")})
alrController.addAction(somethingAction)
alrController.addAction(cancelAction)
self.presentViewController(alrController, animated: true, completion:{})

private var alertController = UIAlertController()
private var tblView = UITableView()
private func setupCitySelectionAlert() {
let alertVC = UIViewController.init()
let rect = CGRect(x: 0.0, y: 0.0, width: 300.0, height: 300.0)
alertVC.preferredContentSize = rect.size
tblView = UITableView(frame: rect)
tblView.delegate = self;
tblView.dataSource = self;
tblView.tableFooterView = UIView(frame: .zero)
tblView.separatorStyle = .singleLine
alertVC.view.addSubview(tblView)
alertVC.view.bringSubviewToFront(tblView)
alertVC.view.isUserInteractionEnabled = true
tblView.isUserInteractionEnabled = true
tblView.allowsSelection = true
self.alertController = UIAlertController(title: "Title", message: nil, preferredStyle: .alert)
alertController.setValue(alertVC, forKey: "contentViewController")
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}

Related

Popoverview is not centred on iPad rotation

In following code popover on iPad is not centred for second alert (cities) when iPad is rotated. It works fine for first alert (countries) though. I've printed the values and it's same for both alerts. It seems that despite having correct value for coordinates it doesn't present it in centre on device rotation for second alert.
Why it doesn't show in centre for second alert? How to fix it?
class MyVC: UIViewController {
var popoverController:UIPopoverPresentationController?
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
self.tableView.reloadData()
if self.popoverController != nil {
popoverController?.sourceView = self.view
print("viewWillTransition():width: x: \(UIScreen.main.bounds.size.width*0.5), y: \(UIScreen.main.bounds.size.height*0.5)")
popoverController?.sourceRect = CGRect(x: UIScreen.main.bounds.size.width*0.5, y: UIScreen.main.bounds.size.height*0.5, width: 0, height: 0)
popoverController?.permittedArrowDirections = []
}
}
#IBAction func countryButtonClicked(_ sender: UIBarButtonItem) {
displayCountries()
}
func displayCountries() {
let alert = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let titleAttributedText = NSMutableAttributedString(
string: "Select Country",
attributes: [
NSAttributedString.Key.paragraphStyle: paragraphStyle
]
)
alert.setValue(titleAttributedText, forKey: "attributedMessage")
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: countryHandler))
for list in Countries {
alert.addAction(UIAlertAction(title: list, style: .default, handler: countryHandler))
}
// For iPad
if let poController = alert.popoverPresentationController {
popoverController = poController
popoverController?.sourceView = self.view
print("displayCountries():width: x: \(UIScreen.main.bounds.size.width*0.5), y: \(UIScreen.main.bounds.size.height*0.5)")
popoverController?.sourceRect = CGRect(x: UIScreen.main.bounds.size.width*0.5, y: UIScreen.main.bounds.size.height*0.5, width: 0, height: 0)
popoverController?.permittedArrowDirections = []
}
alert.view.addSubview(UIView())
present(alert, animated: false, completion: nil)
}
#IBAction func cityButtonClicked(_ sender: Any) {
showCities()
}
func showCities(){
let alert = UIAlertController(title: "Select City", message: nil, preferredStyle: .actionSheet)
for listItem in Cities {
alert.addAction(UIAlertAction(title: listItem.title, style: .default, handler: cityHandler))
}
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: cityHandler))
if let popoverController = alert.popoverPresentationController {
popoverController.sourceView = self.view
print("showCities():width: x: \(UIScreen.main.bounds.size.width*0.5), y: \(UIScreen.main.bounds.size.height*0.5)")
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.size.width*0.5, y: UIScreen.main.bounds.size.height*0.5, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
alert.view.addSubview(UIView())
present(alert, animated: false, completion: nil)
}
}
popoverController must be also assigned in second alert:
if let popoverController = alert.popoverPresentationController {
self.popoverController = popoverController
...

How to add UILabel into UIAlertController

I tried to add UILabel into AlertController but it couldnt display on Alert.
I can make it for UIImageView but I couldnt it for UILabel. This followings are my code snippet
let alert = UIAlertController(title: meta.name!, message: "", preferredStyle: .alert)
alert.addAction( UIAlertAction(title: "OK", style: .default, handler: nil) )
var sizeLabel = UILabel(frame: CGRect(x: 10, y: 10, width: 50, height: 50))
sizeLabel.numberOfLines = 0
sizeLabel.lineBreakMode = .byWordWrapping
sizeLabel.sizeToFit()
sizeLabel.preferredMaxLayoutWidth = alert.view.frame.size.width
sizeLabel.font = UIFont(name: "Avenir-Light", size: 20)
sizeLabel.text = "Hello IOS"
alert.view.addSubview(sizeLabel)
So after some quick research it looks like you can't directly add a label to a UIAlertController. You can, however, use AttributedStrings. I used the answer from https://stackoverflow.com/a/30661824/8722754 for my inspiration and updated it to Swift 3:
let attributedString = NSAttributedString(string: "My Message",
attributes: [NSAttributedStringKey.font : UIFont(name: "Avenir-Light", size: 20)!])
let alert = UIAlertController(title: "Title", message: "", preferredStyle: .alert)
alert.setValue(attributedString, forKey: "attributedMessage")
let cancelAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(cancelAction)
present(alert, animated: true, completion: nil)

move up UIAlertController style Alert with UITextView when keyboard is present

i have an AlertController with UITextView.
when UITexView become first responder the alter doesn't move up with the keyboard.
this is my code:
#IBAction func showAlert(sender: AnyObject) {
let alertController = UIAlertController(title: "Hello, I'm alert! \n\n\n\n\n\n\n", message: "", preferredStyle: .alert)
let rect = CGRect(x: 15, y: 15, width: 240, height: 150)//CGRectMake(15, 50, 240, 150.0)
let textView = UITextView(frame: rect)
textView.font = UIFont(name: "Helvetica", size: 15)
textView.textColor = UIColor.lightGray
textView.backgroundColor = UIColor.white
textView.layer.borderColor = UIColor.lightGray.cgColor
textView.layer.borderWidth = 1.0
textView.text = "Enter message here"
textView.delegate = self
alertController.view.addSubview(textView)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let action = UIAlertAction(title: "Ok", style: .default, handler: { action in
let msg = (textView.textColor == UIColor.lightGray) ? "" : textView.text
print(msg!)
})
alertController.addAction(cancel)
alertController.addAction(action)
self.present(alertController, animated: true, completion: {
textView.becomeFirstResponder()
})
}
and this is my result:
there is a solution?
thanks in advance
just addTextField and then remove it
alert.addTextField { field in
field.translatesAutoresizingMaskIntoConstraints = false
field.heightAnchor.constraint(equalToConstant: 0).isActive = true
}
let inCntrlr = alert.childViewControllers[0].view!
inCntrlr.removeFromSuperview()
and then you could add your own views. here is a
result
After presenting alert controller. Open keyboard for TextView and move alert controller up.
I hope this will suite for you.
self.present(alertController, animated: true, completion: {
textView.becomeFirstResponder()
UIView.animate(withDuration: 0.5, animations: {
alertController.view.frame.origin.y = 100
})
})
UIAlertController by default will slide up when they keyboard is shown. The problem here is that you have added a subview to the alert controller. From the UIAlertController docs:
The UIAlertController 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.
Adding your own subview to the alert goes against what the docs say and is likely what is causing your problem. If you need an alert with a text view in it, your best bet is to create your own view and manage it yourself.
I created this drop-in replacement, also customizable for any special needs of course. It's pretty simple and 'just works'!
https://gist.github.com/unixb0y/42a1ae0fb707bdb5e1e484bafd33d44a
It is a subclass of UIAlertController with a UITextView inside.
When it is initialized, it observes keyboard changes and adjusts its view.frame.origin.y accordingly.
var keyboardHeight: CGFloat = 100 {
didSet {
let height = UIScreen.main.bounds.height
let menu = self.view.frame.height
let keyb = self.keyboardHeight
self.view.frame.origin.y = height-menu-keyb-20
}
}
...
...
...
#objc func keyboardChange(sender: Notification) {
guard let userInfo = sender.userInfo else { return }
let endFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
keyboardHeight = endFrame?.height ?? 100
}
It's like. You open keyboard and change alert position.
var alertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.alert)
var alertControllerPositon:CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
#IBAction func showAlert(sender: AnyObject) {
let alertController = UIAlertController(title: "Hello, I'm alert! \n\n\n\n\n\n\n", message: "", preferredStyle: .alert)
let rect = CGRect(x: 15, y: 15, width: 240, height: 150)//CGRectMake(15, 50, 240, 150.0)
let textView = UITextView(frame: rect)
textView.font = UIFont(name: "Helvetica", size: 15)
textView.textColor = UIColor.lightGray
textView.backgroundColor = UIColor.white
textView.layer.borderColor = UIColor.lightGray.cgColor
textView.layer.borderWidth = 1.0
textView.text = "Enter message here"
textView.delegate = self
alertController.view.addSubview(textView)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let action = UIAlertAction(title: "Ok", style: .default, handler: { action in
let msg = (textView.textColor == UIColor.lightGray) ? "" : textView.text
print(msg!)
})
alertController.addAction(cancel)
alertController.addAction(action)
self.present(alertController, animated: true, completion: {
textView.becomeFirstResponder()
})
alertControllerPositon = alertController.view.frame.origin.y
}
#objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
alertControllerPositon = alertController.view.frame.origin.y
let result = self.view.frame.height - (alertController.view.frame.height + alertController.view.frame.origin.y) - 20
self.alertController.view.frame.origin.y -= (keyboardSize.height - result)
}
}
#objc func keyboardWillHide(notification: NSNotification) {
if self.alertController.view.frame.origin.y != alertControllerPositon {
self.alertController.view.frame.origin.y = alertControllerPositon
}
}

How to add a UIStepper to AlertView

I want to add a UIStepper to my alerView but the stepper is not showing here is my code
var alert = UIAlertView(title: "Hello works", message: "\n\n", delegate: nil, cancelButtonTitle: "OK", otherButtonTitles: "")
var stepper = UIStepper()
stepper.frame = CGRect(x: CGFloat(12.0), y: CGFloat(5.0), width: CGFloat(100), height: CGFloat(10))
alert.addSubview(stepper)
alert.show()
UIAlertView is deprecated. You should use UIAlertController instead. Here is an answer that explains how you can implement what you want using a UIAlertController:
UIAlertController - add custom views to actionsheet
// Below is code for implementing UIAlertView Using UIAlertController in swift and add your custom views on it .
let logoutAlert = UIAlertController(title: "Alert", message: "DemoAlert", preferredStyle: UIAlertControllerStyle.alert)
logoutAlert.addAction(UIAlertAction(title: "cancel", style: .default, handler: nil))
logoutAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in
// Write your code here
}))
var stepper = UIStepper()
stepper.frame = CGRect(x: CGFloat(12.0), y: CGFloat(5.0), width: CGFloat(100), height: CGFloat(10))
// You can add any view on UIAlert controller using below code:
logoutAlert.popoverPresentationController?.sourceRect = stepper.frame
logoutAlert.popoverPresentationController?.sourceView = stepper
self.present(logoutAlert, animated: true, completion: nil)

Choose different images in one View with UIImagePickerController [duplicate]

This question already has an answer here:
Picking two different images in the same view controller using imagePickerController in Swift
(1 answer)
Closed 7 years ago.
We have the following view:
All code is running well but when I finally select a picture , the photo is placed just in one ImageView. It should works like this:
We click each button below the UIImageView and it puts the selected picture in his ImageView.
My problem now is that all buttons are placing the photo in the first UIImageView.
How to place 4 different photos?
class selectorDeFotosViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextViewDelegate {
//Outlets
#IBOutlet weak var fotoUno: UIImageView!
#IBOutlet weak var fotoDos: UIImageView!
#IBOutlet weak var fotoTres: UIImageView!
#IBOutlet weak var fotoCuatro: UIImageView!
override func viewDidLoad() {
}
//Actions
#IBAction func CamaraUno(sender: AnyObject) {
let alertPictureFrom = UIAlertController(title: "De dónde sacar la foto?", message: "", preferredStyle: UIAlertControllerStyle.ActionSheet)
presentViewController(alertPictureFrom, animated: true, completion: nil)
alertPictureFrom.popoverPresentationController?.sourceRect = CGRect(x: 350.0, y: 458.0, width: 1.0, height: 1.0)
alertPictureFrom.popoverPresentationController?.sourceView = self.view
alertPictureFrom.addAction(UIAlertAction(title: "Cámara", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .Camera
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
alertPictureFrom.addAction(UIAlertAction(title: "Galería", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .PhotoLibrary
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
}
#IBAction func camaraDos(sender: AnyObject) {
let alertPictureFrom = UIAlertController(title: "De dónde sacar la foto?", message: "", preferredStyle: UIAlertControllerStyle.ActionSheet)
presentViewController(alertPictureFrom, animated: true, completion: nil)
alertPictureFrom.popoverPresentationController?.sourceRect = CGRect(x: 350.0, y: 458.0, width: 1.0, height: 1.0)
alertPictureFrom.popoverPresentationController?.sourceView = self.view
alertPictureFrom.addAction(UIAlertAction(title: "Cámara", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .Camera
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
alertPictureFrom.addAction(UIAlertAction(title: "Galería", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .PhotoLibrary
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
}
#IBAction func camaraTres(sender: AnyObject) {
let alertPictureFrom = UIAlertController(title: "De dónde sacar la foto?", message: "", preferredStyle: UIAlertControllerStyle.ActionSheet)
presentViewController(alertPictureFrom, animated: true, completion: nil)
alertPictureFrom.popoverPresentationController?.sourceRect = CGRect(x: 350.0, y: 458.0, width: 1.0, height: 1.0)
alertPictureFrom.popoverPresentationController?.sourceView = self.view
alertPictureFrom.addAction(UIAlertAction(title: "Cámara", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .Camera
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
alertPictureFrom.addAction(UIAlertAction(title: "Galería", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .PhotoLibrary
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
}
#IBAction func camaraCuatro(sender: AnyObject) {
let alertPictureFrom = UIAlertController(title: "De dónde sacar la foto?", message: "", preferredStyle: UIAlertControllerStyle.ActionSheet)
presentViewController(alertPictureFrom, animated: true, completion: nil)
alertPictureFrom.popoverPresentationController?.sourceRect = CGRect(x: 350.0, y: 458.0, width: 1.0, height: 1.0)
alertPictureFrom.popoverPresentationController?.sourceView = self.view
alertPictureFrom.addAction(UIAlertAction(title: "Cámara", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .Camera
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
alertPictureFrom.addAction(UIAlertAction(title: "Galería", style: .Default, handler: {action in
let picker = UIImagePickerController()
picker.sourceType = .PhotoLibrary
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}))
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
fotoUno.image = image
picker.dismissViewControllerAnimated(true, completion: nil)
}
There are many ways to achieve this.
You press button1, and set a BOOL value buttonOne to YES, and you present the picker, you select the image, and to display the image, you simply check is button is selected or not in the method didFinishPickingImage,so:
if(buttonOne)
{
//set the image view 1 image
}
You do the same for all the four image views:
if(buttonOne)
{
//set the image view 1 image
}
if(buttonTwo)
{
//set the image view 2 image
} if(buttonThree)
{
//set the image view 3 image
} if(buttonFour)
{
//set the image view 4 image
}
Make sure you set the other 3 bool values to NO, when you set one value to YES.

Resources