Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to use MapboxNavigation within a UIView (instead of UIViewController)? #1814

Closed
paul019 opened this issue Nov 6, 2018 · 8 comments

Comments

@paul019
Copy link

paul019 commented Nov 6, 2018

Hi!

For some reason I want to use MapboxNavigation within a UIView, because I have no access to its UIViewController. Is it possible to use the Turn-by-turn navigation within such a UIView?

In all your examples the map is used within a UIViewController, e.g.:

import Foundation
import UIKit
import MapboxCoreNavigation
import MapboxNavigation
import MapboxDirections
 
class BasicViewController: UIViewController { 
...
@frederoni
Copy link
Contributor

Yes. There are a couple of options.

1: Simple: Use NavigationViewController’s view in an arbitrary view controller.UIViewController.addChildViewController(_:) to add an instance of NavigationViewController to your own view controller. Then add the navigationViewController’s view anywhere you want and set up the layout according to your needs. The NavigationViewController will be pass the data to and from router <> UI.

2: Intermediate: Use the NavigationView. The NavigationView encapsulates all views in the NavigationViewController but it's up to the developer to pass data from the router onto every view when picking this option.

@paul019
Copy link
Author

paul019 commented Nov 6, 2018

Thank you for the fast answer. I don't know if I've understood you quite right, because I'm not really deep into Xcode.

In the following code you can see the UIView I want to attach the Turn-by-turn window to. In the extension UIView I search for the parent UIViewController of my UIView. In its init function I then try to attach an instance of NavigationViewController to my UIViewController.

import Foundation
import UIKit
import MapboxCoreNavigation
import MapboxNavigation
import MapboxDirections

@objc(TurnByTurnView)
class TurnByTurnView : UIView {
    var params:NSDictionary;
    weak var viewController: UIViewController?
    
    override init(frame: CGRect) {
        self.params = [:];
        super.init(frame: frame);
        self.frame = frame;
        
        let navigationService = MapboxNavigationService(route: route, simulating: .always)
        let navigationController = NavigationViewController(for: route, navigationService: navigationService)
        viewController.addChildViewController(navigationController);
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setParams(params: NSDictionary) {
        self.params = params;
    }
}

extension UIView {
    var parentViewController: UIViewController? {
        var parentResponder: UIResponder? = self
        while parentResponder != nil {
            parentResponder = parentResponder!.next
            if let viewController = parentResponder as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}

Unfortunately, when I do this, Xcode prints the following error: Command failed due to signal: Abort trap: 6. When printing the error, it refers to my init function.

I tried removing the line viewController.addChildViewController(navigationController);, but this didn't change anything; the error is still there. So one of the following lines of code has to be responsible for the error:

let navigationService = MapboxNavigationService(route: route, simulating: .always)
        let navigationController = NavigationViewController(for: route, navigationService: navigationService) 

Do you have any idea, what's going on here? I'm sorry if my code is complete bullshit...

@frederoni
Copy link
Contributor

viewController.addChildViewController(navigationController)

looks correct so far but you also need to add the view

addSubview(navigationController.view)

@paul019
Copy link
Author

paul019 commented Nov 6, 2018

Thank you! Nevertheless, there's still the above mentioned error (Command failed due to signal: Abort trap: 6)...

@frederoni
Copy link
Contributor

viewController.addChildViewController(navigationController)

your viewController is most likely nil at this point.

@paul019
Copy link
Author

paul019 commented Nov 6, 2018

I've now put the critical lines of code into another function:

override func viewDidAppear(animated: Bool) {
        let navigationService = MapboxNavigationService(route: route, simulating: .always)
        let navigationController = NavigationViewController(for: route, navigationService: navigationService)
        viewController.addChildViewController(navigationController);
        viewController.addSubview(navigationController.view);
    }

But I'm still getting the same error.

@paul019
Copy link
Author

paul019 commented Nov 6, 2018

Maybe this error results out of my hacky solution for this issue: mapbox/mapbox-events-ios#85. There I had several problems too install MapboxNavigation via CocoaPods. After the installation I always got the following error in Xcode:

bildschirmfoto 2018-11-05 um 20 40 35

To solve this issue I commented out the line of code that created the error (#import <MapboxDirections/MapboxDirections.h>) without getting other errors. But maybe this comment-out leads to the error I'm experiencing now. Can this be the case?

@paul019
Copy link
Author

paul019 commented Nov 6, 2018

@frederoni Do you have any idea to solve my error (Command failed due to signal: Abort trap: 6)? Unfortunately, I found nothing helpful on the internet to solve it...

@paul019 paul019 closed this as completed Nov 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants