I tried to make "place autocomplete" from google place and I copy paste the codes directly from the website here google developer and I already set the api key too but the problem is why the results look so odd when I typing a place as you can see on the picture it seems works but not perfect. here is my code:
import UIKit
import GoogleMaps
class FetcherSampleViewController: UIViewController {
var textField: UITextField?
var resultText: UITextView?
var fetcher: GMSAutocompleteFetcher?
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.whiteColor()
self.edgesForExtendedLayout = .None
// Set bounds to inner-west Sydney Australia.
let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366,
longitude: 151.134002)
let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725,
longitude: 151.200349)
let bounds = GMSCoordinateBounds(coordinate: neBoundsCorner,
coordinate: swBoundsCorner)
// Set up the autocomplete filter.
let filter = GMSAutocompleteFilter()
filter.type = .Establishment
// Create the fetcher.
fetcher = GMSAutocompleteFetcher(bounds: bounds, filter: filter)
fetcher?.delegate = self
textField = UITextField(frame: CGRect(x: 5.0, y: 0,
width: self.view.bounds.size.width - 5.0, height: 44.0))
textField?.autoresizingMask = .FlexibleWidth
textField?.addTarget(self, action: "textFieldDidChange:",
forControlEvents: .EditingChanged)
resultText = UITextView(frame: CGRect(x: 0, y: 45.0,
width: self.view.bounds.size.width,
height: self.view.bounds.size.height - 45.0))
resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
resultText?.text = "No Results"
resultText?.editable = false
self.view.addSubview(textField!)
self.view.addSubview(resultText!)
}
func textFieldDidChange(textField: UITextField) {
fetcher?.sourceTextHasChanged(textField.text!)
}
}
extension FetcherSampleViewController: GMSAutocompleteFetcherDelegate {
func didAutocompleteWithPredictions(predictions: [GMSAutocompletePrediction]) {
let resultsStr = NSMutableString()
for prediction in predictions {
resultsStr.appendFormat("%#\n", prediction.attributedPrimaryText)
}
resultText?.text = resultsStr as String
}
func didFailAutocompleteWithError(error: NSError) {
resultText?.text = error.localizedDescription
}
}
can anyone help me?
This is because prediction.attributedPrimaryText is an attributed string. Try the following code
func didAutocompleteWithPredictions(predictions: [GMSAutocompletePrediction]) {
let resultsStr = NSMutableAttributedString()
for prediction in predictions {
resultsStr.appendAttributedString(prediction.attributedPrimaryText)
resultsStr.appendAttributedString(NSAttributedString(string: "\n"))
}
resultText?.attributedText = resultsStr
}
Related
I have added various filed successfully using Eureka form builder for iOS but getting an error while adding locationrow
I imported following framework still getting the issue
import UIKit
import CoreLocation
import MapKit
import Eureka
is there any other way to use locationrow in eureka?
you will have to first add LocationRow in your pod file and then update your pod file so that cocoapod downloads LocationRow. build the project once to refresh the project with the new files.
and then in the above class import LocationRow
LocationRow (Included as custom row in the example project)
These words were taken from https://github.com/xmartlabs/Eureka
So far Location Row can't be included into Eureka framework cause it's required MapKit or something similar, that's why eureka community created separated class/object.
I created a separate folder/file for the location code
import Foundation
import UIKit
import MapKit
import Eureka
//MARK: LocationRow
public final class LocationRow: OptionsRow<PushSelectorCell<CLLocation>>, PresenterRowType, RowType {
public typealias PresenterRow = MapViewController
/// Defines how the view controller will be presented, pushed, etc.
public var presentationMode: PresentationMode<PresenterRow>?
/// Will be called before the presentation occurs.
public var onPresentCallback: ((FormViewController, PresenterRow) -> Void)?
public required init(tag: String?) {
super.init(tag: tag)
presentationMode = .show(controllerProvider: ControllerProvider.callback { return MapViewController(){ _ in } }, onDismiss: { vc in _ = vc.navigationController?.popViewController(animated: true) })
displayValueFor = {
guard let location = $0 else { return "" }
let fmt = NumberFormatter()
fmt.maximumFractionDigits = 4
fmt.minimumFractionDigits = 4
let latitude = fmt.string(from: NSNumber(value: location.coordinate.latitude))!
let longitude = fmt.string(from: NSNumber(value: location.coordinate.longitude))!
return "\(latitude), \(longitude)"
}
}
/**
Extends `didSelect` method
*/
public override func customDidSelect() {
super.customDidSelect()
guard let presentationMode = presentationMode, !isDisabled else { return }
if let controller = presentationMode.makeController() {
controller.row = self
controller.title = selectorTitle ?? controller.title
onPresentCallback?(cell.formViewController()!, controller)
presentationMode.present(controller, row: self, presentingController: self.cell.formViewController()!)
} else {
presentationMode.present(nil, row: self, presentingController: self.cell.formViewController()!)
}
}
/**
Prepares the pushed row setting its title and completion callback.
*/
public override func prepare(for segue: UIStoryboardSegue) {
super.prepare(for: segue)
guard let rowVC = segue.destination as? PresenterRow else { return }
rowVC.title = selectorTitle ?? rowVC.title
rowVC.onDismissCallback = presentationMode?.onDismissCallback ?? rowVC.onDismissCallback
onPresentCallback?(cell.formViewController()!, rowVC)
rowVC.row = self
}
}
public class MapViewController : UIViewController, TypedRowControllerType, MKMapViewDelegate {
public var row: RowOf<CLLocation>!
public var onDismissCallback: ((UIViewController) -> ())?
lazy var mapView : MKMapView = { [unowned self] in
let v = MKMapView(frame: self.view.bounds)
v.autoresizingMask = [.flexibleWidth, .flexibleHeight]
return v
}()
lazy var pinView: UIImageView = { [unowned self] in
let v = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
v.image = UIImage(named: "map_pin", in: Bundle(for: MapViewController.self), compatibleWith: nil)
v.image = v.image?.withRenderingMode(.alwaysTemplate)
v.tintColor = self.view.tintColor
v.backgroundColor = .clear
v.clipsToBounds = true
v.contentMode = .scaleAspectFit
v.isUserInteractionEnabled = false
return v
}()
let width: CGFloat = 10.0
let height: CGFloat = 5.0
lazy var ellipse: UIBezierPath = { [unowned self] in
let ellipse = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: self.width, height: self.height))
return ellipse
}()
lazy var ellipsisLayer: CAShapeLayer = { [unowned self] in
let layer = CAShapeLayer()
layer.bounds = CGRect(x: 0, y: 0, width: self.width, height: self.height)
layer.path = self.ellipse.cgPath
layer.fillColor = UIColor.gray.cgColor
layer.fillRule = .nonZero
layer.lineCap = .butt
layer.lineDashPattern = nil
layer.lineDashPhase = 0.0
layer.lineJoin = .miter
layer.lineWidth = 1.0
layer.miterLimit = 10.0
layer.strokeColor = UIColor.gray.cgColor
return layer
}()
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nil, bundle: nil)
}
convenience public init(_ callback: ((UIViewController) -> ())?){
self.init(nibName: nil, bundle: nil)
onDismissCallback = callback
}
public override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(mapView)
mapView.delegate = self
mapView.addSubview(pinView)
mapView.layer.insertSublayer(ellipsisLayer, below: pinView.layer)
let button = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(MapViewController.tappedDone(_:)))
button.title = "Done"
navigationItem.rightBarButtonItem = button
if let value = row.value {
let region = MKCoordinateRegion(center: value.coordinate, latitudinalMeters: 400, longitudinalMeters: 400)
mapView.setRegion(region, animated: true)
}
else{
mapView.showsUserLocation = true
}
updateTitle()
}
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let center = mapView.convert(mapView.centerCoordinate, toPointTo: pinView)
pinView.center = CGPoint(x: center.x, y: center.y - (pinView.bounds.height/2))
ellipsisLayer.position = center
}
#objc func tappedDone(_ sender: UIBarButtonItem){
let target = mapView.convert(ellipsisLayer.position, toCoordinateFrom: mapView)
row.value = CLLocation(latitude: target.latitude, longitude: target.longitude)
onDismissCallback?(self)
}
func updateTitle(){
let fmt = NumberFormatter()
fmt.maximumFractionDigits = 4
fmt.minimumFractionDigits = 4
let latitude = fmt.string(from: NSNumber(value: mapView.centerCoordinate.latitude))!
let longitude = fmt.string(from: NSNumber(value: mapView.centerCoordinate.longitude))!
title = "\(latitude), \(longitude)"
}
public func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
ellipsisLayer.transform = CATransform3DMakeScale(0.5, 0.5, 1)
UIView.animate(withDuration: 0.2, animations: { [weak self] in
self?.pinView.center = CGPoint(x: self!.pinView.center.x, y: self!.pinView.center.y - 10)
})
}
public func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
ellipsisLayer.transform = CATransform3DIdentity
UIView.animate(withDuration: 0.2, animations: { [weak self] in
self?.pinView.center = CGPoint(x: self!.pinView.center.x, y: self!.pinView.center.y + 10)
})
updateTitle()
}
}
In my form, I just added a new row like this:
<<< LocationRow("Location"){
$0.title = $0.tag
$0.value = CLLocation(latitude: -34.9124, longitude: -56.1594)
}
This is also a good resource to use.
https://fluttergeek.com/blog/eureka-locationrow/
I am new to swift. I am creating an AR app with AR annotation View, where I have created a places object to show on Annotation AR view, but I can't get different icons to show based on locations in AR view. I only get one specific icon to all the places. Please have a look at my code to help me out with this issue. Thank you very much!
Here is my code:
import UIKit
import AVFoundation
protocol AnnotationViewDelegate {
func didTouch(annotationView: AnnotationView)
}
class AnnotationView: ARAnnotationView {
var titleLabel: UILabel?
var distanceLabel: UILabel?
var delegate: AnnotationViewDelegate?
var backgroundView: UIView?
var pinImage: UIImageView?
let pinoImage = ["bakeries", "banks", "barber", "bars", "beaches", "breweries", "cardealer", "carrepair", "church", "cinema",
"coffee", "college", "dentist", "dining", "doctors", "drycleaning", "fastfood", "firetruck", "fitness", "gas",
"grocery", "hospital", "hotel", "library", "lounges", "motorcycledealers", "musicvenues", "park", "petstore",
"pharmacy", "police", "postoffice", "train", "transportation", "zoo"]
override func didMoveToSuperview() {
super.didMoveToSuperview()
loadUI()
}
func getRandomColor() -> UIColor{
let red:CGFloat = CGFloat(drand48())
let green:CGFloat = CGFloat(drand48())
let blue:CGFloat = CGFloat(drand48())
return UIColor(red:red, green: green, blue: blue, alpha: 1.0)
}
func loadUI() {
titleLabel?.removeFromSuperview()
distanceLabel?.removeFromSuperview()
backgroundView?.removeFromSuperview()
pinImage?.removeFromSuperview()
backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: 70))
backgroundView?.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.5)
backgroundView?.layer.cornerRadius = 10.0
self.addSubview(backgroundView!)
pinImage = UIImageView(frame: CGRect(x: 16, y: 8, width: 37.76, height: 54))
pinImage?.contentMode = UIViewContentMode.scaleAspectFit
self.backgroundView?.addSubview(pinImage!)
let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: 22.0))
label.font = UIFont(name: "AvenirNext", size: 3)
label.numberOfLines = 0
label.textAlignment = .center
label.textColor = UIColor.white
self.backgroundView?.addSubview(label)
self.titleLabel = label
distanceLabel = UILabel(frame: CGRect(x: 66, y: 47, width: self.frame.size.width, height: 15.0))
distanceLabel?.textColor = UIColor.black
distanceLabel?.font = UIFont(name: "Montserrat-Regular", size: 12)
self.backgroundView?.addSubview(distanceLabel!)
if let annotation = annotation as? Place {
titleLabel?.text = annotation.placeName
distanceLabel?.text = String(format: "%.2f mi", annotation.distanceFromUser * 0.000621371)
pinImage?.image = UIImage(named: "FastFood")
}
}
override func layoutSubviews() {
super.layoutSubviews()
backgroundView?.frame = CGRect(x: 0, y: 0, width: 170, height: 80)
titleLabel?.frame = CGRect(x: 50, y: 8, width: self.frame.size.width - 66, height: 22.0)
distanceLabel?.frame = CGRect(x: 50, y: 30, width: self.frame.size.width, height: 20)
pinImage = UIImageView(frame: CGRect(x: 16, y: 8, width: 37.76, height: 54))
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
delegate?.didTouch(annotationView: self)
}
}
MapViewController
import UIKit
import MapKit
import CoreLocation
class MapViewController: BaseViewController, UITabBarDelegate{
#IBOutlet weak var leadingConstraints: NSLayoutConstraint!
#IBOutlet weak var mapView: MKMapView!
fileprivate let locationManager = CLLocationManager()
fileprivate var startedLoadingPOIs = false
fileprivate var places = [Place]()
fileprivate var arViewController: ARViewController!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
var nearMeIndexSelected = NearMeIndexTitle()
var place: Place?
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
}
#IBAction func showARController(_ sender: Any) {
arViewController = ARViewController()
arViewController.dataSource = self
arViewController.maxVisibleAnnotations = 30
arViewController.headingSmoothingFactor = 0.05
arViewController.setAnnotations(places)
self.present(arViewController, animated: true, completion: nil)
}
}
extension MapViewController: CLLocationManagerDelegate, MKMapViewDelegate {
func mapView(_ mapView: MKMapView,
viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
mapView.tintColor = #colorLiteral(red: 0.08235294118, green: 0.7058823529, blue: 0.9450980392, alpha: 1)
return nil
} else {
let pin = mapView.view(for: annotation) ?? MKAnnotationView(annotation: annotation, reuseIdentifier: nil)
pin.image = UIImage(named: "pins")
return pin
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.count > 0 {
let location = locations.last!
print("Accuracy: \(location.horizontalAccuracy)")
if location.horizontalAccuracy < 100 {
manager.stopUpdatingLocation()
let span = MKCoordinateSpan(latitudeDelta: 0.013, longitudeDelta: 0.013)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.region = region
if !startedLoadingPOIs {
DispatchQueue.main.async {
self.activityIndicator.startAnimating()
}
startedLoadingPOIs = true
let loader = PlacesLoader()
loader.loadPOIS(location: location, radius: 1500) { placesDict, error in
if let dict = placesDict {
guard let placesArray = dict.object(forKey: "results") as? [NSDictionary] else { return }
for placeDict in placesArray {
let latitude = placeDict.value(forKeyPath: "geometry.location.lat") as! CLLocationDegrees
let longitude = placeDict.value(forKeyPath: "geometry.location.lng") as! CLLocationDegrees
let reference = placeDict.object(forKey: "reference") as! String
let name = placeDict.object(forKey: "name") as! String
let address = placeDict.object(forKey: "vicinity") as! String
let location = CLLocation(latitude: latitude, longitude: longitude)
let place = Place(location: location, reference: reference, name: name, address: address)
self.places.append(place)
let annotation = PlaceAnnotation(location: place.location!.coordinate, title: place.placeName)
DispatchQueue.main.async {
self.mapView.addAnnotation(annotation)
}
}
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
self.mapView.isHidden = false
}
}
}
}
}
}
}
}
extension MapViewController: ARDataSource {
func ar(_ arViewController: ARViewController, viewForAnnotation: ARAnnotation) -> ARAnnotationView {
let annotationView = AnnotationView()
arViewController.title = "MyApp"
annotationView.annotation = viewForAnnotation
annotationView.delegate = self
annotationView.frame = CGRect(x: 0, y: 0, width: 150, height: 50)
return annotationView
}
}
In Mapview class add the below code
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if (annotation is MKUserLocation) {
return nil
}
let reuseId = "reuseId"
let anView : AnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as! AnnotationView
if let annotation = annotation as? Place {
anView.titleLabel?.text = annotation.placeName
anView.distanceLabel?.text = String(format: "%.2f mi", annotation.distanceFromUser * 0.000621371)
if(annotation.placeName == "bakeries"){
anView.pinImage?.image = UIImage(named: "Bakery")
}
else{
anView.pinImage?.image = UIImage(named: "FastFood")
}
}
anView.canShowCallout = false
return anView
}
by the above the method you can change pin custom image
I'm using Google Maps SDK for iOS with a custom render function for my icons. Unfortunately when I tap into the markers, no infoWindow is shown. Here's my code:
// MyViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let renderer = GMUDefaultClusterRenderer(mapView: self.mapView, clusterIconGenerator: iconGenerator)
renderer.delegate = self
self.clusterManager = GMUClusterManager(map: self.mapView, algorithm: algorithm, renderer: renderer)
for (index, marker) in markers.enumerated() {
let markerItem = POIItem(position: marker.position, name: "Marker \(index)")
self.clusterManager.add(markerItem)
}
self.mapViewContainer.addSubview(self.mapView)
clusterManager.cluster()
}
func renderer(_ renderer: GMUClusterRenderer, willRenderMarker marker: GMSMarker) {
let pinImageView = UIImageView(image: #imageLiteral(resourceName: "pin"));
let iconView = UIView(frame: CGRect(x: 0, y: 0, width: pinImageView.frame.width, height: pinImageView.frame.height))
iconView.clipsToBounds = false
iconView.backgroundColor = .clear
iconView.addSubview(pinImageView)
iconView.layoutIfNeeded()
if let markerData = marker.userData {
if let markerClusterData = (markerData as? GMUCluster) {
let totalLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
let labelContainerView = UIView(frame: CGRect(x: 20, y: -10, width: 25, height: 25))
labelContainerView.backgroundColor = #colorLiteral(red: 0.9803921569, green: 0.7058823529, blue: 0.1176470588, alpha: 1)
totalLabel.font = totalLabel.font.withSize(12.0)
totalLabel.text = "\(markerClusterData.count)+"
totalLabel.textAlignment = .center
totalLabel.textColor = .white
labelContainerView.addSubview(totalLabel)
labelContainerView.layer.cornerRadius = 12.5
labelContainerView.layoutIfNeeded()
iconView.addSubview(labelContainerView)
iconView.bounds = iconView.frame.union(labelContainerView.frame)
}
}
marker.iconView = iconView
}
// Default POIITem implementation, exactly like Google teaches.
class POIItem: NSObject, GMUClusterItem {
var position: CLLocationCoordinate2D
var name: String!
init(position: CLLocationCoordinate2D, name: String) {
self.position = position
self.name = name
}
}
No infoWindow is shown, with or without the custom delegation method.
The marker needs a snippet to show an infowindow
Otherwise, you can create a custom infowindow in the corresponding callback
I am using the DLRadioButton library through Cocoa Pods found here
Below is my code, essentially the radio buttons appear however I am only able to click 1 of them in the group and I am unsure why. Note that I am populating the Radio Buttons based on an Int in Firebase that indicates how many to populate:
` override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference()
pollRef = ref.child("Polls").child(pass)
passLabel.text = pass
pollImage.sd_setImage(with: URL(string: passedImageURL), placeholderImage: UIImage(named: "test"))
pollRef.observe(FIRDataEventType.value, with: {(snapshot) in
self.numberOfChildren = Int(snapshot.childSnapshot(forPath: "answers").childrenCount)
self.passLabel.text = String(self.numberOfChildren)
print(self.numberOfChildren)
var buttons = [DLRadioButton]()
for x in 0..<self.numberOfChildren {
let answerLabel = snapshot.childSnapshot(forPath:
"answers").childSnapshot(forPath:
String(x+1)).childSnapshot(forPath: "answer").value
let firstRadioButton = self.createRadioButton(frame: CGRect(x:
CGFloat(x)*32, y:self.view.center.y , width: 40.0, height: 20.0),
title: answerLabel as! String, color: UIColor.black)
// firstRadioButton.translatesAutore sizingMaskIntoConstraints = false
let screenSize: CGRect = UIScreen.main.bounds
firstRadioButton.frame = CGRect(x: 0, y: 0, width: 50, height: screenSize.height * 0.2)
firstRadioButton.tag = x
buttons.append(firstRadioButton)
self.view.addSubview(firstRadioButton);
}
let groupButtons = DLRadioButton()
groupButtons.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(groupButtons)
let margins = self.view.layoutMarginsGuide
groupButtons.bottomAnchor.constraint(equalTo: margins.bottomAnchor, constant: 0).isActive = true
groupButtons.otherButtons = buttons
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func createRadioButton(frame : CGRect, title : String, color : UIColor) -> DLRadioButton {
let radioButton = DLRadioButton(frame: frame);
radioButton.titleLabel!.font = UIFont.systemFont(ofSize: 14);
radioButton.setTitle(title, for: UIControlState.normal);
radioButton.setTitleColor(color, for: UIControlState.normal);
radioButton.iconColor = color;
radioButton.indicatorColor = color;
radioButton.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left;
radioButton.addTarget(self, action: #selector(self.logSelectedButton(_:)), for: UIControlEvents.touchUpInside);
return radioButton;
}
#IBAction func logSelectedButton(_ radioButton: DLRadioButton) {
if radioButton.isMultipleSelectionEnabled {
for button: DLRadioButton in radioButton.selected() {
print("\(button.titleLabel?.text) is selected.\n")
}
}
else {
print("\(radioButton.selected()?.titleLabel?.text) is selected.\n")
}
}
`
You need to selector method of button
let firstRadioButton = self.createRadioButton(frame: CGRect(x: self.view.center.x, y: CGFloat(x)*32, width: 100.0, height: 120.0), title: answerLabel as! String, color: UIColor.green)
firstRadioButton.tag = x
firstRadioButton.addTarget(self, action: #selector(self.logSelectedButton), for: .touchUpInside)
buttons.append(firstRadioButton)
Selector method : you can change as per needs
#IBAction func logSelectedButton(_ radioButton: DLRadioButton) {
if radioButton.isMultipleSelectionEnabled {
for button: DLRadioButton in radioButton.selectedButtons {
print("\(button.titleLabel?.text) is selected.\n")
}
}
else {
print("\(radioButton.selectedButton.titleLabel?.text) is selected.\n")
}
}
I have google place autocomplete which display an GMSAutocompleteFetcher. the code is come from Google developer website but the problem is I can't find a way how to handle selection right after user seeing the words appear on the textView to display it as place ID, so far this is my code:
import UIKit
import GoogleMaps
class FetcherSampleViewController: UIViewController {
var textField: UITextField?
var resultText: UITextView?
var fetcher: GMSAutocompleteFetcher?
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: "handletap:")
self.view.backgroundColor = UIColor.whiteColor()
self.edgesForExtendedLayout = .None
// Set bounds to inner-west Sydney Australia.
let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366,
longitude: 151.134002)
let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725,
longitude: 151.200349)
let bounds = GMSCoordinateBounds(coordinate: neBoundsCorner,
coordinate: swBoundsCorner)
// Set up the autocomplete filter.
let filter = GMSAutocompleteFilter()
filter.type = .Establishment
// Create the fetcher.
fetcher = GMSAutocompleteFetcher(bounds: bounds, filter: filter)
fetcher?.delegate = self
textField = UITextField(frame: CGRect(x: 5.0, y: 0,
width: self.view.bounds.size.width - 5.0, height: 44.0))
textField?.autoresizingMask = .FlexibleWidth
textField?.addTarget(self, action: "textFieldDidChange:",
forControlEvents: .EditingChanged)
resultText = UITextView(frame: CGRect(x: 0, y: 45.0,
width: self.view.bounds.size.width,
height: self.view.bounds.size.height - 45.0))
resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
resultText?.text = "No Results"
resultText?.editable = false
resultText?.addGestureRecognizer(tap)
self.view.addSubview(textField!)
self.view.addSubview(resultText!)
}
func textFieldDidChange(textField: UITextField) {
fetcher?.sourceTextHasChanged(textField.text!)
}
func handletap (sender: UITapGestureRecognizer){
print("I dont know what to do here")
}
}
extension FetcherSampleViewController: GMSAutocompleteFetcherDelegate {
func didAutocompleteWithPredictions(predictions: [GMSAutocompletePrediction]) {
let resultsStr = NSMutableAttributedString()
for prediction in predictions {
resultsStr.appendAttributedString(prediction.attributedPrimaryText)
resultsStr.appendAttributedString(NSAttributedString(string: "\n"))
}
resultText?.attributedText = resultsStr
}
func didFailAutocompleteWithError(error: NSError) {
resultText?.text = error.localizedDescription
}
}
I use UITapGestureRecognizer but I don't know what should I do. If you can help me I would appreciate it :)
Since all the predictions are just newline-delimited rows in a text field, it's going to be difficult to tell which of them the user tapped on.
How about instead of a UITextView, you use a UITableView and have one row per prediction. This will make it easy to detect which prediction was selected.