Reputation: 1873
I am quite new to swift and IOS development.
I would like to ask experienced members what is the correct way of creating mapview and tableview in one viewcontroller and populating them.
The logic of application is the following:
Both mapview and tableview are in the same viewcontroller.
in viewDidLoad I am getting users location.
in viewwillappear I am running functions to read plist file and calculate distances between POIs and user.
Everything is working but it is not stable ... sometimes it might show user's location but table will be empty. So I doubt that I am doing everything correctly. Also probably it is not correct to put both map and table inside one class?
Update
Here is the code:
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var theMapView: MKMapView!
@IBOutlet weak var tableView: UITableView!
var locationManager: CLLocationManager!
var branches = [Branch]()
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
tableView.dataSource = self
tableView.delegate = self
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
//mapview setup to show user location
theMapView.delegate = self
theMapView.showsUserLocation = true
theMapView.mapType = MKMapType(rawValue: 0)!
theMapView.userTrackingMode = MKUserTrackingMode(rawValue: 2)!
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
readFromPlist()
}
//MARK: UITableView methods
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return branches.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: MapCustomCell = tableView.dequeueReusableCellWithIdentifier("mapCell") as! MapCustomCell
let brnch = branches[indexPath.row]
cell.mapSetupCell(brnch.cityName, AddressLabel: brnch.address, DistanceLabel: brnch.distance)
return cell
}
//MARK: FUNC TO CALCULATE DISTANCE
func calculateDistance (lat1 lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> String {
return "100km"
}
func locationManager (manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let myCoordinates = locations.last
let myLat = myCoordinates!.coordinate.latitude
let myLong = myCoordinates!.coordinate.longitude
let myCoordinates2D = CLLocationCoordinate2DMake(myLat, myLong)
let myLatDelta = 0.10
let myLongDelta = 0.10
let mySpan = MKCoordinateSpanMake(myLatDelta, myLongDelta)
let myRegion = MKCoordinateRegion(center: myCoordinates2D, span: mySpan)
theMapView.setRegion(myRegion, animated: true)
let myAnno = MKPointAnnotation()
myAnno.coordinate = myCoordinates2D
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("error:" + error.localizedDescription)
}
func readFromPlist() {
//read plist file to extract banks coordinates
let path = NSBundle.mainBundle().pathForResource("poi", ofType: "plist")
let POIarrays = NSArray(contentsOfFile: path!)
for arr in POIarrays! {
var ctName : String!
var brnchAddress : String!
var wrkngHours : String!
var lat : Double!
var long : Double!
ctName = arr.objectForKey("cityName")! as! String
brnchAddress = arr.objectForKey("address")! as! String
wrkngHours = arr.objectForKey("workingHours")! as! String
lat = Double(arr.objectForKey("latitude")! as! String)
long = Double(arr.objectForKey("longitude")! as! String)
let latitude: CLLocationDegrees = lat
let longitude : CLLocationDegrees = long
let bankLocation : CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let annotation = MKPointAnnotation()
annotation.coordinate = bankLocation
annotation.title = bnkName
annotation.subtitle = brnchAddress
self.theMapView.addAnnotation(annotation)
let myLatitude = self.locationManager.location?.coordinate.latitude
let myLongitude = self.locationManager.location?.coordinate.longitude
if myLatitude != nil {
let dist = calculateDistance(lat1: latitude, lon1: longitude, lat2: myLatitude!, lon2: myLongitude!)
let b = Branch(cityName: ctName!, address: brnchAddress!, distance: dist)
branches.append(b)
}
}
}
}
Sometimes I got an error
"error:The operation couldn’t be completed. (kCLErrorDomain error 0.)"
and current location doesn't appear on my map.
Upvotes: 2
Views: 408