setRegion () не работает, если я создаю экземпляр V C напрямую, но работает, если я добираюсь до V C через segue Swift 4 - PullRequest
0 голосов
/ 07 января 2020

Я экспериментирую со странным (на мой взгляд) изменением поведения функции в зависимости от того, как я добираюсь до V C, который ее содержит. Когда пользователь нажимает на действие удаленного уведомления, приложение переходит от фона к переднему плану, с go до NewMapViewController, загружает маршрут, отображает его как MKPolyline и устанавливает регион на основе MKPolyline MapRect. Теперь проблема, с которой я сталкиваюсь, заключается в том, что setRegion() не работает в зависимости от того, как я добираюсь до NewMapViewController. Если в действии я создаю экземпляр UINavigationController и добираюсь до NewMapController с помощью перехода, то setRegion в displayRoute() работает, как и ожидалось, но я вижу loginVC перед его показом. Поэтому, чтобы не показывать loginVC, я вместо этого создаю экземпляр NewMapViewController напрямую, но при этом setRegion в displayRoute() больше не увеличивает MKPolyline. Почему это может происходить? Сначала я подумал, что вызывается configureMap (карта центров по местоположению пользователя), но нет, все распечатки показывают, что когда NewMapViewController загружается с этим счетчиком в 1, он никогда не вызывается. Я попытался использовать setVisibleMapRect() вместо setRegion(), но это не имело никакого значения. Это известная ошибка? Есть ли другой способ добраться до newMapViewController, который я должен попробовать? Как всегда, большое спасибо за ваше время и помощь.

Обновление:

После нескольких попыток я решил вызвать checkAlerts() непосредственно из тела действия вместо viewWillApper() контр-проверки. Это привело к нулевой ошибке при добавлении MKPolyline в displayRoute(). Немного поиска я обнаружил, что это проблема с потоками, поэтому, добавив ее в очередь DispatchQueue.main.async, все снова заработало, как и ожидалось. Это работает независимо от того, звоню ли я checkAlerts() из тела действия или из viewWillApper() контр-проверки. Кажется, что когда я создаю экземпляры от UINavigationController и go до NewMApController через переход, у него есть время загрузить маршрут и вычислить ломаную линию, но при непосредственном создании экземпляра NewMapController нет. Я хотел бы понять это немного лучше, имеет ли это смысл для вас?

Это действие:

case Id.checkActionIdentifier:
            print("Check tapped")
            let userInfo = response.notification.request.content.userInfo
            if let routeToCheck = userInfo[NSLocalizedString("Route", comment: "")] as? String {
                RoutesArray.routeName = routeToCheck
//                print("rotta is: \(routeToCheck)")
            }
//            let content = response.notification.request.content
//            print(" Body \(content.body)")
//            print(" Title \(content.title)")
            NewMapViewController.routeCheckCounter = 1

            //  Goes to NewMapViewController but showing the loginVc first
//            let storyboard = UIStoryboard(name: "Main", bundle: nil)
//            let initialViewController : UINavigationController = storyboard.instantiateViewController(withIdentifier: "MainNavigationController") as! UINavigationController
//            self.window?.rootViewController = initialViewController
//            self.window?.makeKeyAndVisible()
//            let vc = initialViewController.viewControllers[0]
//            vc.performSegue(withIdentifier: "alertToMapSegue", sender: nil)

            // setRegion in displayRoute() not working ???
            if let navigationVC = self.window?.rootViewController as? UINavigationController {
                let main = UIStoryboard(name: "Main", bundle: nil)
                let newMapVC = main.instantiateViewController(withIdentifier: "NewMapViewController") as! NewMapViewController
                navigationVC.pushViewController(newMapVC, animated: true)
            }

, и эта функция отображает MKPolyline:

func displayRoute() {
        print("displayRoute called")
        var coordinateArray: [CLLocationCoordinate2D] = []
        for point in MapArray.actualRouteInUseCoordinatesArray {
            let location = CLLocationCoordinate2D(latitude: point.coordinate.latitude, longitude: point.coordinate.longitude)
            coordinateArray.append(location)
        }
        // tracked CLLocations route
        routePolyline = MKGeodesicPolyline(coordinates: coordinateArray, count: coordinateArray.count)
        mapView.add(routePolyline, level: MKOverlayLevel.aboveRoads)
        let startRouteAnnotation: RouteAnnotation = RouteAnnotation(title: "Route Start", coordinate: MapArray.actualRouteInUseCoordinatesArray.first!.coordinate)
        self.mapView.addAnnotation(startRouteAnnotation)

        let endRouteAnnotation = RouteAnnotation(title: "Route End", coordinate: MapArray.actualRouteInUseCoordinatesArray.last!.coordinate)
        self.mapView.addAnnotation(endRouteAnnotation)

        print("MapArray.actualRouteInUseCoordinatesArray.count is: \(MapArray.actualRouteInUseCoordinatesArray.count)")


        // full display
        let region = MKCoordinateRegionForMapRect(routePolyline!.boundingMapRect)
        mapView.setRegion(region, animated: true)

        // padded in
//        self.mapView.setRegion(MKCoordinateRegionForMapRect(padMapRect(rect: routePolyline.boundingMapRect)), animated: true)
    }

вот как я могу вызвать функцию на viewWillAppear(): (checkAlerts() чем вызов displayRoute().

// if loading vc from an scheduled alert check notification
        print(" CheckCounter is: \(NewMapViewController.routeCheckCounter ?? 0)")
        if NewMapViewController.routeCheckCounter ?? 0 > 0 {
            print("checkAlerts called in viewDidLoad")
            // load the route and call displayRoute()
            checkAlerts()
        } else {
            // just center map on user location
            configureMap()
            return
        }

1 Ответ

0 голосов
/ 07 января 2020

После попыток, описанных в части моего вопроса об обновлении, здесь есть модифицированная функция, которая работает так, как и ожидалось:

func displayRoute() {
        print("displayRoute called")
        var coordinateArray: [CLLocationCoordinate2D] = []
        for point in MapArray.actualRouteInUseCoordinatesArray {
            let location = CLLocationCoordinate2D(latitude: point.coordinate.latitude, longitude: point.coordinate.longitude)
            coordinateArray.append(location)
        }
        DispatchQueue.main.async {
        // tracked CLLocations route
        self.routePolyline = MKGeodesicPolyline(coordinates: coordinateArray, count: coordinateArray.count)
        self.mapView.add(self.routePolyline, level: MKOverlayLevel.aboveRoads)

        let startRouteAnnotation: RouteAnnotation = RouteAnnotation(title: "Route Start", coordinate: MapArray.actualRouteInUseCoordinatesArray.first!.coordinate)
        self.mapView.addAnnotation(startRouteAnnotation)

        let endRouteAnnotation = RouteAnnotation(title: "Route End", coordinate: MapArray.actualRouteInUseCoordinatesArray.last!.coordinate)
        self.mapView.addAnnotation(endRouteAnnotation)

        print("MapArray.actualRouteInUseCoordinatesArray.count is: \(MapArray.actualRouteInUseCoordinatesArray.count)")
//        self.mapView.setRegion(MKCoordinateRegionForMapRect(padMapRect(rect: routePolyline.boundingMapRect)), animated: true)

        self.mapView.setVisibleMapRect(self.padMapRect(rect: self.routePolyline.boundingMapRect), animated: true)
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...