Navigate from current location to marker - ios

Hello i have multiple markers like this:
var Groningen = GMSMarker()
marker.position = CLLocationCoordinate2DMake(...., .....)
marker.title = "...."
marker.icon = UIImage(named: "...")
marker.snippet = "....."
marker.map = mapView
var marker1= GMSMarker()
marker1.position = CLLocationCoordinate2DMake(...., .....)
marker1.title = "...."
marker1.icon = UIImage(named: "...")
marker1.snippet = "....."
marker1.map = mapView
In want to add a button in the InfoWindow or in a label below the map that will set directions from the current location to de selected marker.
When the user click on the button its get question like this:
func mapView(mapView: GMSMapView!, didTapInfoWindowOfMarker marker: GMSMarker!) {
let actionSheetController: UIAlertController = UIAlertController(title: "Navigeer", message: "Kies een optie!", preferredStyle: .ActionSheet)
//Create and add the Cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
//Do some stuff
}
actionSheetController.addAction(cancelAction)
//Create and add first option action
let GoGoogleMaps: UIAlertAction = UIAlertAction(title: "Google Maps", style: .Default) { action -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"https://maps.google.com/?daddr=Amsterdam")!);
}
//Do some other stuff
}
actionSheetController.addAction(GoGoogleMaps)
//Create and add a second option action
let GoAppleMaps: UIAlertAction = UIAlertAction(title: "Apple Maps", style: .Default) { action -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"http://maps.apple.com")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.apple.com/?daddr=Amsterdam")!)
} else {
NSLog("Can't use Apple Maps");
}
//Do some other stuff
}
actionSheetController.addAction(GoAppleMaps)
//We need to provide a popover sourceView when using it on iPad
actionSheetController.popoverPresentationController?.sourceView = sender as! UIView;
//Present the AlertController
self.presentViewController(actionSheetController, animated: true, completion: nil)
}
Is this possible in a way.

Based on this Stackoverflow answer, there is no easy way to add a touch event on a button in custom info window.
(You could instead implement GMSMapViewDelegate's -didTapInfoWindowOfMarker: delegate method to check if the infowindow was tapped.
(the drawback is that the entire infowindow becomes one button))
But if you want to add an UILabel in your MapView, you need to set the consumesGesturesInView to be false. So the UILabel can receive touch events.
Sample Code of adding an UILabel with touch event:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let label = UILabel(frame: CGRectMake(view.frame.size.width - 100, view.frame.size.height - 40, 80, 30))
label.backgroundColor = UIColor.whiteColor()
label.text = "direction"
label.textAlignment = .Center
label.layer.cornerRadius = 10
label.clipsToBounds = true
label.userInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: "directionTapped")
label.addGestureRecognizer(tap)
mapView!.settings.consumesGesturesInView = false
mapView!.addSubview(label)
mapView!.bringSubviewToFront(label)
}
Sample Code of showing Maps direction options:
func directionTapped() {
let openMapsActionSheet = UIAlertController(title: "Open in Maps", message: "Choose a maps application", preferredStyle: .ActionSheet)
openMapsActionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(self.mapView!.selectedMarker.position.latitude, self.mapView!.selectedMarker.position.longitude), addressDictionary: nil)
let item = MKMapItem(placemark: placemark)
let options = [MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: true]
item.openInMapsWithLaunchOptions(options as [NSObject : AnyObject])
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Google Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?saddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)&daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.google.com/maps?saddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)&daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
}
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(openMapsActionSheet, animated: true, completion: nil)
}

Related

My Camera crash on ipad 12.1.4 but works fine on iphone

I am using the camera to take photo, it is working fine in iphone, but it crashes when i run it on ipad.
#IBAction func uploadPhotoButtonPressed(_ sender: UIButton) {
let camera = Camera(delegate_: self)
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let takePhoto = UIAlertAction(title: "Take Photo", style: .default) { (alert: UIAlertAction!) -> Void in
camera.PresentPhotoCamera(self, canEdit: true)
}
let sharePhoto = UIAlertAction(title: "Photo Library", style: .default) { (alert: UIAlertAction!) -> Void in
camera.PresentPhotoLibrary(self, canEdit: true)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (alert : UIAlertAction!) -> Void in
print("Cancel")
}
optionMenu.addAction(takePhoto)
optionMenu.addAction(sharePhoto)
optionMenu.addAction(cancelAction)
self.present(optionMenu, animated: true, completion: nil)
}
I think your error in UIAlertController because in iPad you need to pass source view.
Please check UIAlertController code for iPad
if let popoverController = yourAlert.popoverPresentationController {
popoverController.sourceView = self.view //to set the source of your alert
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) // you can set this as per your requirement.
popoverController.permittedArrowDirections = [] //to hide the arrow of any particular direction
}
You can check this code also in your simulator, please check first and resubmit your build.
Since Apple announce iOS app should run proper in ipad as well. so, we need to make sure when we capture photo from camera and select from photo library we also need to update code for iPad regarding UIImagePickerViewController. I am attaching code which works in both iPhone and iPad.
let actionSheetController: UIAlertController = UIAlertController(title: "Select Photo", message: "", preferredStyle: .actionSheet)
let cancelActionButton: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
print("Cancel")
}
actionSheetController.addAction(cancelActionButton)
let saveActionButton: UIAlertAction = UIAlertAction(title: "Photolibrary", style: .default)
{ action -> Void in
self.picker.allowsEditing = true
self.picker.sourceType = .photoLibrary
self.present(self.picker, animated: true, completion: nil)
}
actionSheetController.addAction(saveActionButton)
let deleteActionButton: UIAlertAction = UIAlertAction(title: "Camera", style: .default)
{ action -> Void in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)
{
self.picker.allowsEditing = true
self.picker.sourceType = .camera
self.present(self.picker, animated: true, completion: nil)
}
}
actionSheetController.addAction(deleteActionButton)
if let popoverController = actionSheetController.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
self.present(actionSheetController, animated: true, completion: nil)

Show UIAlertController every time view controller launches

Currently, the UIAlertController appears when the user taps on the HeaderButton. I am trying to make the UIAlertController automatically appear every time the view controller initially launches. Any suggestions?
// MARK: - RestaurantListTableViewHeaderDelegate
extension RestaurantListViewController: RestaurantListTableViewHeaderDelegate {
func didTapHeaderButton(_ headerView: RestaurantListTableViewHeader) {
let locationPicker = UIAlertController(title: "Select location", message: nil, preferredStyle: .actionSheet)
for location in RestaurantListViewController.locations {
locationPicker.addAction(UIAlertAction(title: location, style: .default) { [weak self] action in
guard let `self` = self else { return }
self.currentLocation = action.title
self.tableView.reloadData()
})
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
locationPicker.addAction(cancelAction)
present(locationPicker, animated: true)
}
}
I kept the extension for when the Header Button gets tapped and I added the following to viewDidLoad:
// Code for showing alert
let locationPicker = UIAlertController(title: "Select location", message: nil, preferredStyle: .actionSheet)
for location in RestaurantListViewController.locations {
locationPicker.addAction(UIAlertAction(title: location, style: .default) { [weak self] action in
guard let `self` = self else { return }
self.currentLocation = action.title
self.tableView.reloadData()
})
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
locationPicker.addAction(cancelAction)
present(locationPicker, animated: true)
It's not an elegant solution but it will work:
var alertAlreadyShown = false
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if !alertAlreadyShown {
alertAlreadyShown = true
/* Code for showing alert */
}
}

Add a statement for a function in Swift

I have a label named "direction". I have a map with a lot of pins. When i click on one pin and tap the label "direction" it give me two options and works fine. But when i do not click on a Pin and tap de label "direction" the app crash.
i want to setup an statement when the a pin is not selected an alert show that the user first select a pin to get directions.
Hope someone can look at code to make this possible:
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, GMSMapViewDelegate {
#IBOutlet weak var mapView: GMSMapView!
#IBAction func MapType(sender: AnyObject) {
let segmentedControl = sender as! UISegmentedControl
switch segmentedControl.selectedSegmentIndex {
case 0:
mapView.mapType = kGMSTypeNormal
case 1:
mapView.mapType = kGMSTypeSatellite
case 2:
mapView.mapType = kGMSTypeHybrid
default:
mapView.mapType = mapView.mapType
}
}
let locationManager = CLLocationManager()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
//3
mapView.delegate = self
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
var Marker= GMSMarker()
Marker.position = CLLocationCoordinate2DMake(5.2317, 4.5708 )
Marker.title = "1"
Marker.snippet = "1"
Marker.appearAnimation = kGMSMarkerAnimationPop
Marker.map = mapView
var Marker1= GMSMarker()
Marker1.position = CLLocationCoordinate2DMake(5.2317, 8.5708 )
Marker1.title = "2"
Marker1.snippet = "2"
Marker1.map = mapView
let label = UILabel(frame: CGRectMake(view.frame.size.width - 100, view.frame.size.height - 40, 80, 30))
label.backgroundColor = UIColor.whiteColor()
label.text = "direction"
label.textAlignment = .Center
label.layer.cornerRadius = 10
label.clipsToBounds = true
label.userInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: "directionTapped")
label.addGestureRecognizer(tap)
mapView!.settings.consumesGesturesInView = false
mapView!.addSubview(label)
mapView!.bringSubviewToFront(label)
self.view.addSubview(label)
}
func directionTapped() {
let openMapsActionSheet = UIAlertController(title: "Open in Maps", message: "Choose a maps application", preferredStyle: .ActionSheet)
openMapsActionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(self.mapView!.selectedMarker.position.latitude, self.mapView!.selectedMarker.position.longitude), addressDictionary: nil)
let item = MKMapItem(placemark: placemark)
let options = [MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: true]
item.openInMapsWithLaunchOptions(options as [NSObject : AnyObject])
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Google Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.google.com/maps?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
}
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(openMapsActionSheet, animated: true, completion: nil)
}
// 1
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
// 2
if status == .AuthorizedWhenInUse {
// 3
locationManager.startUpdatingLocation()
//4
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
}
// 5
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
if let location = locations.first as? CLLocation {
// 6
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 6, bearing: 1, viewingAngle: 1)
// 7
locationManager.stopUpdatingLocation()
}
}
}
In absence of the complete code, here is what i can extrapolate:
I am assuming you have a mapView that is already set.
I am assuming mapView!.selectedMarker gets populated only when the user selects the pin, else it is nil (or some other value u choose) then,
Now, directionTapped should be:
if self.mapView!.selectedMarker != nil {
<Your current Code>
} else {
<Code to Show the new alert about pin not selected>
}
with this code it worked from me:
func directionTapped(){
//code input from Apple-and-Oranges
if self.mapView!.selectedMarker != nil {
//current code
let openMapsActionSheet = UIAlertController(title: "Open in Maps", message: "Choose a maps application", preferredStyle: .ActionSheet)
openMapsActionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(self.mapView!.selectedMarker.position.latitude, self.mapView!.selectedMarker.position.longitude), addressDictionary: nil)
let item = MKMapItem(placemark: placemark)
let options = [MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: true]
item.openInMapsWithLaunchOptions(options as [NSObject : AnyObject])
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Google Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.google.com/maps?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
}
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(openMapsActionSheet, animated: true, completion: nil)
}
//Added a alert message
else {
let alertController = UIAlertController(title: "Choose Pin!", message: "\nChoose Pin to get navigation from current location", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action: UIAlertAction!) in
}))
presentViewController(alertController, animated: true, completion: nil)
}
}

click on a label in Swift

I want to make the label that on click on it to make call to number. I know that iOS has this option, but how can I do it in Swift?
I found just how to do it in ObjC:
-(IBAction)callPhone:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:2135554321"]];
}
Can anyone help me with it?
UIApplication.sharedApplication().openURL(NSURL(string: "tel://2135554321"))
example
if let CallURL:NSURL = NSURL(string:"tel://\(yourMobileNUmber)") {
let application:UIApplication = UIApplication.sharedApplication()
if (application.canOpenURL( CallURL)) {
application.openURL( CallURL);
}
else
{
// your number not valid
let tapAlert = UIAlertController(title: "Alert!!!", message: "Your mobile number is invalid", preferredStyle: UIAlertControllerStyle.Alert)
tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
self.presentViewController(tapAlert, animated: true, completion: nil)
}
}
Type-2
// add gesture to your Label
var tapGesture = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
yourLabelName.userInteractionEnabled=true
yourLabelName.addGestureRecognizer(tapGesture)
// handle the function of UILabel
func handleTap(sender:UITapGestureRecognizer){
if let CallURL:NSURL = NSURL(string:"tel://\(yourMobileNUmber)") {
let application:UIApplication = UIApplication.sharedApplication()
if (application.canOpenURL( CallURL)) {
application.openURL( CallURL);
}
else
{
// your number not valid
let tapAlert = UIAlertController(title: "Alert!!!", message: "Your mobile number is invalid", preferredStyle: UIAlertControllerStyle.Alert)
tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
self.presentViewController(tapAlert, animated: true, completion: nil)
}
}
}

Check on UIAlertController TextField for enabling the button

I have an AlertController with a text field and two button: CANCEL and SAVE. This is the code:
#IBAction func addTherapy(sender: AnyObject)
{
let addAlertView = UIAlertController(title: "New Prescription", message: "Insert a name for this prescription", preferredStyle: UIAlertControllerStyle.Alert)
addAlertView.addAction(UIAlertAction(title: "Cancel",
style: UIAlertActionStyle.Default,
handler: nil))
addAlertView.addAction(UIAlertAction(title: "Save",
style: UIAlertActionStyle.Default,
handler: nil))
addAlertView.addTextFieldWithConfigurationHandler({textField in textField.placeholder = "Title"})
self.presentViewController(addAlertView, animated: true, completion: nil)
}
What I want to do is implement a check on the textfield for disabling the SAVE button when the textfield is empty just like Pictures Application of iOS when you want create a NewAlbum. Please someone can explain me what to do?
There is a much simpler way without using notification center, in swift:
weak var actionToEnable : UIAlertAction?
func showAlert()
{
let titleStr = "title"
let messageStr = "message"
let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.alert)
let placeholderStr = "placeholder"
alert.addTextField(configurationHandler: {(textField: UITextField) in
textField.placeholder = placeholderStr
textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .editingChanged)
})
let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (_) -> Void in
})
let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { (_) -> Void in
let textfield = alert.textFields!.first!
//Do what you want with the textfield!
})
alert.addAction(cancel)
alert.addAction(action)
self.actionToEnable = action
action.isEnabled = false
self.present(alert, animated: true, completion: nil)
}
func textChanged(_ sender:UITextField) {
self.actionToEnable?.isEnabled = (sender.text! == "Validation")
}
I would first create the alertcontroller with the save action initially disabled. Then when adding the textfield inculde a Notification to observe its change in the handler and in that selector just toggle the save actions enabled property.
Here is what I am saying:
//hold this reference in your class
weak var AddAlertSaveAction: UIAlertAction?
#IBAction func addTherapy(sender : AnyObject) {
//set up the alertcontroller
let title = NSLocalizedString("New Prescription", comment: "")
let message = NSLocalizedString("Insert a name for this prescription.", comment: "")
let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
let otherButtonTitle = NSLocalizedString("Save", comment: "")
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
// Add the text field with handler
alertController.addTextFieldWithConfigurationHandler { textField in
//listen for changes
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleTextFieldTextDidChangeNotification:", name: UITextFieldTextDidChangeNotification, object: textField)
}
func removeTextFieldObserver() {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: alertController.textFields[0])
}
// Create the actions.
let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .Cancel) { action in
NSLog("Cancel Button Pressed")
removeTextFieldObserver()
}
let otherAction = UIAlertAction(title: otherButtonTitle, style: .Default) { action in
NSLog("Save Button Pressed")
removeTextFieldObserver()
}
// disable the 'save' button (otherAction) initially
otherAction.enabled = false
// save the other action to toggle the enabled/disabled state when the text changed.
AddAlertSaveAction = otherAction
// Add the actions.
alertController.addAction(cancelAction)
alertController.addAction(otherAction)
presentViewController(alertController, animated: true, completion: nil)
}
//handler
func handleTextFieldTextDidChangeNotification(notification: NSNotification) {
let textField = notification.object as UITextField
// Enforce a minimum length of >= 1 for secure text alerts.
AddAlertSaveAction!.enabled = textField.text.utf16count >= 1
}
I am doing this in another project - I got this pattern directly from apple examples. They have a very good example project outlining a few of these patterns in the UICatalog examples: https://developer.apple.com/library/content/samplecode/UICatalog/Introduction/Intro.html
Swift 3.0 Updated Solution given By #spoek
func showAlert()
{
let titleStr = "title"
let messageStr = "message"
let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.alert)
let placeholderStr = "placeholder"
alert.addTextField(configurationHandler: {(textField: UITextField) in
textField.placeholder = placeholderStr
textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .editingChanged)
})
let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (_) -> Void in
})
let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { (_) -> Void in
let textfield = alert.textFields!.first!
//Do what you want with the textfield!
})
alert.addAction(cancel)
alert.addAction(action)
self.actionToEnable = action
action.isEnabled = false
self.present(alert, animated: true, completion: nil)
}
func textChanged(_ sender:UITextField) {
self.actionToEnable?.isEnabled = (sender.text! == "Validation")
}
I implemented a subclass of UIAlertController for conveniently adding text fields and associated enabling and disabling of buttons. The basic logic is similar to that Sourabh Sharma but everything is encapsulated in this subclass for tidiness. This should be helpful if your project involves a lot of such alert functionalities.
public class TextEnabledAlertController: UIAlertController {
private var textFieldActions = [UITextField: ((UITextField)->Void)]()
func addTextField(configurationHandler: ((UITextField) -> Void)? = nil, textChangeAction:((UITextField)->Void)?) {
super.addTextField(configurationHandler: { (textField) in
configurationHandler?(textField)
if let textChangeAction = textChangeAction {
self.textFieldActions[textField] = textChangeAction
textField.addTarget(self, action: #selector(self.textFieldChanged), for: .editingChanged)
}
})
}
#objc private func textFieldChanged(sender: UITextField) {
if let textChangeAction = textFieldActions[sender] {
textChangeAction(sender)
}
}
}
To use it, just provide a textChangeAction block when adding the text fields:
alert.addTextField(configurationHandler: { (textField) in
textField.placeholder = "Your name"
textField.autocapitalizationType = .words
}) { (textField) in
saveAction.isEnabled = (textField.text?.characters.count ?? 0) > 0
}
For the full example, see the git page.

Resources