0

I am making a small map type application. I wish to display a popover menu once the button 'morestuff' is clicked, but it does not seem to be appearing.

I have this code so far:

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate {

var location: CLLocation!
let locationManager = CLLocationManager()

// Map variables
var searchController:UISearchController!
var annotation:MKAnnotation!
var localSearchRequest:MKLocalSearchRequest!
var localSearch:MKLocalSearch!
var localSearchResponse:MKLocalSearchResponse!
var error:NSError!
var pointAnnotation:MKPointAnnotation!
var pinAnnotationView:MKPinAnnotationView!

@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var showSearchBar: UIBarButtonItem!
@IBOutlet weak var addButton: UIBarButtonItem!
@IBOutlet weak var moreStuff: UIBarButtonItem!


@IBAction func addButton(sender: AnyObject) {
    let annotation = MKPointAnnotation()
    annotation.coordinate = CLLocationCoordinate2D(latitude: self.mapView.userLocation.coordinate.latitude, longitude: self.mapView.userLocation.coordinate.longitude)
    self.mapView.addAnnotation(annotation)

}

@IBAction func showSearchBar(sender: UIBarButtonItem!) {
    searchController = UISearchController(searchResultsController: nil)
    searchController.hidesNavigationBarDuringPresentation = false
    self.searchController.searchBar.delegate = self
    presentViewController(searchController, animated: true, completion: nil)

}

@IBAction func refresh(sender: AnyObject) {

    self.locationManager.startUpdatingLocation()
}



@IBAction func moreStuff(sender: AnyObject) {
    self.performSegueWithIdentifier("showMoreStuff", sender:self)

}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showMoreStuff"
    {
        var vc = segue.destinationViewController as! UIViewController

        var controller = vc.popoverPresentationController

        if controller != nil
        {
            controller?.delegate = self
        }

    }
}

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {

    return .None
}


@IBAction func segmentedControl(sender: UISegmentedControl!) {

    if sender.selectedSegmentIndex == 0{

        mapView.mapType = MKMapType.Standard
    }
    else if sender.selectedSegmentIndex == 1{

        mapView.mapType = MKMapType.Satellite
    }
    else if sender.selectedSegmentIndex == 2{

        mapView.mapType = MKMapType.Hybrid
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    self.locationManager.delegate = self

    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest

    self.locationManager.requestWhenInUseAuthorization()

    self.locationManager.startUpdatingLocation()

    self.mapView.showsUserLocation = true

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// location delegate methods

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let location = locations.last

    let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)

    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))

    self.mapView.setRegion(region, animated: true)

    self.locationManager.stopUpdatingLocation()

}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
    print("Error code: " + error.localizedDescription)
}

func searchBarSearchButtonClicked(searchBar: UISearchBar){

    searchBar.resignFirstResponder()
    dismissViewControllerAnimated(true, completion: nil)
    if self.mapView.annotations.count != 0{
        annotation = self.mapView.annotations[0]
        self.mapView.removeAnnotation(annotation)
    }

    localSearchRequest = MKLocalSearchRequest()
    localSearchRequest.naturalLanguageQuery = searchBar.text
    localSearch = MKLocalSearch(request: localSearchRequest)
    localSearch.startWithCompletionHandler { (localSearchResponse, error) -> Void in

        if localSearchResponse == nil{
            let alertController = UIAlertController(title: nil, message: "No Such Place", preferredStyle: UIAlertControllerStyle.Alert)
            alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
            self.presentViewController(alertController, animated: true, completion: nil)
            return
        }

        self.pointAnnotation = MKPointAnnotation()
        self.pointAnnotation.title = searchBar.text
        self.pointAnnotation.coordinate = CLLocationCoordinate2D(latitude: localSearchResponse!.boundingRegion.center.latitude, longitude:     localSearchResponse!.boundingRegion.center.longitude)


        self.pinAnnotationView = MKPinAnnotationView(annotation: self.pointAnnotation, reuseIdentifier: nil)
        self.mapView.centerCoordinate = self.pointAnnotation.coordinate
        self.mapView.addAnnotation(self.pinAnnotationView.annotation!)
    }
}

}

Any help is appreciated :) I am trying to learn the Swift language myself

2
  • You would like to show view controller in UIPopover via segue ? Commented Mar 2, 2016 at 14:39
  • You don't need to use 'self.' in Swift, unless you're inside a closure. It would make your code look a bit cleaner. Commented Mar 2, 2016 at 14:46

1 Answer 1

1

Firstly your UIButton should be linked to the popover's view controller using the Present As Popover segue type.

Than add delegate method of the UIPopoverPresentationControllerDelegate :

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {

    return UIModalPresentationNone;
}

Swift version :

func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle {
    // This *forces* a popover to be displayed on the iPhone
    return .None
}

After that add prepareForSegue:sender: to you're code

if ([segue.identifier isEqualToString:@"showMoreStuff"]) {
    UIViewController *dvc = segue.destinationViewController;
    UIPopoverPresentationController *controller = dvc.popoverPresentationController;
    if (controller) {
        controller.delegate = self;
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Where does this code go specifically? I am new to Swift sorry :(
Specifically the first section of code, I am not sure where to put this
First section should be placed in viewController that is using UIPopoverPresentationControllerDelegate
Thanks for your reply. I have only 1 viewcontroller.swift file, when I place the code in there I get an unexpected declaration under the "-". Am I doing something wrong?
Thanks, now the second block of code, I tried to replace my existing code with it but I receive errors about '@' etc. Is this swift?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.