2013-05-17 3 views
3

MKMapView에 MKUserTrackingModeFollowWithHeading이 있습니다. 하지만 뭔가 MKUserTrackingModeFollow에 userTrackingMode 또는 없음, 그래서 난 구현을 변경확대했을 때 MKMapView가있는 setUserTrackingMode에서 충돌이 발생했습니다.

- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated 
{ 
    if ([CLLocationManager locationServicesEnabled]) { 
     if ([CLLocationManager headingAvailable]) { 
      [self.myMapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:NO]; 
     }else{ 
      [self.myMapView setUserTrackingMode:MKUserTrackingModeFollow animated:NO]; 
     } 
    }else{ 
     [self.myMapView setUserTrackingMode:MKUserTrackingModeNone animated:NO]; 
    } 
} 

모든 것이 잘하지만 매번 내가 가장 상세 수준으로지도를 확대, 앱이 라인 setUserTrackingMode에 EXC_BAD_ACCESS 원인 : 위 MKUserTrackingModeFollowWithHeading .

충돌을 피하려면 어떻게해야합니까? 가능한 경우 MKUserTrackingBarButtonItem을 사용하고 싶지 않습니다.

mapViewController의 다른 부분은 아래와 같습니다.

- (void)dealloc 
{ 
    self.myMapView.delegate = nil; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    if ([CLLocationManager locationServicesEnabled]) { 
     self.myMapView.showsUserLocation = NO; 
     [_locManager stopUpdatingLocation]; 

     if ([CLLocationManager headingAvailable]) { 
      [_locManager stopUpdatingHeading]; 
     } 
    } 

    [super viewWillDisappear:animated]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    if ([CLLocationManager locationServicesEnabled]) { 
     self.myMapView.showsUserLocation = YES; 
     [_locManager startUpdatingLocation]; 

     if ([CLLocationManager headingAvailable]) { 
      [self.myMapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:NO]; 
      [_locManager startUpdatingHeading]; 
     }else{ 
      [self.myMapView setUserTrackingMode:MKUserTrackingModeFollow animated:NO]; 
     } 
    }else{ 
     [self.myMapView setUserTrackingMode:MKUserTrackingModeNone animated:NO]; 
    } 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

    self.myMapView.delegate = self; 
    [self.myMapView setFrame:self.view.frame]; 

    self.locManager = [CLLocationManager new]; 
    [self.locManager setDelegate:self]; 
    [self.locManager setDistanceFilter:kCLDistanceFilterNone]; 
    [self.locManager setDesiredAccuracy:kCLLocationAccuracyBest]; 
    [self.locManager setHeadingFilter:3]; 
    [self.locManager setHeadingOrientation:CLDeviceOrientationPortrait]; 
} 

모든 종류의 조언을 부탁드립니다. 미리 감사드립니다.

최소 샘플 코드를 github으로 업로드합니다.

+0

나는이 충돌 (MKUserTrackingModeFollowWithHeading 충돌) 다른 SO 나는 SO 만에보고 된이 충돌 – danypata

+0

에 대한 게시를 통해, 당신이보고해야 종류 SO에서의 인기가 생각 나는 찾을 수 없었다 ... 고마워. – kinamin

+0

추적 모드를 다시 설정하는 대신'scrollEnabled'를'NO'로 설정할 수 있습니까? 그렇게하면 사용자는 확대/축소 할 수 있지만 스크롤 할 수 없으므로 사용자 상호 작용의 결과로 사용자 추적 모드가 변경되어서는 안됩니다. 또한 현재 추적 모드가 아니라면 추적 모드 만 설정하면 안됩니까? 'didChangeUserTrackingMode'가 원하는 모드로 설정하면 사용자 추적 모드를 다시 설정할 필요가 없습니다. – Rob

답변

3

나는 추적 모드의 설정 등을 연기하려고 노력하는 것이 좋습니다 수 있습니다

- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated 
{ 
    dispatch_async(dispatch_get_main_queue(),^{ 
     if ([CLLocationManager locationServicesEnabled]) { 
      if ([CLLocationManager headingAvailable]) { 
       [self.myMapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:NO]; 
      }else{ 
       [self.myMapView setUserTrackingMode:MKUserTrackingModeFollow animated:NO]; 
      } 
     }else{ 
      [self.myMapView setUserTrackingMode:MKUserTrackingModeNone animated:NO]; 
     } 
    }); 
} 
나는 또한 mode 당신이 중복 setUserTrackingMode 제거, 원하는 것을 이미 있지 않은지 확인하기 위해 검사를 제안 할 수

:

- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated 
{ 
    MKUserTrackingMode newMode = MKUserTrackingModeNone; 

    if ([CLLocationManager locationServicesEnabled]) { 
     if ([CLLocationManager headingAvailable]) { 
      newMode = MKUserTrackingModeFollowWithHeading; 
     }else{ 
      newMode = MKUserTrackingModeFollow; 
     } 
    } 

    if (mode != newMode) 
    { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self.myMapView setUserTrackingMode:newMode animated:YES]; 
     }); 
    } 
} 

scrollEnabled (사용자가 우연히 추적 모드를 변경하는 것을 방지해야 함)과 결합 할 수도 있습니다.

+0

이것은 문제를 완벽하게 해결합니다! 나는 이것과'scrollEnabled = NO'를 함께 사용한다. 나는 결코 너에게 충분히 감사 할 수 없다! – kinamin

+0

@kinamin 참고로, 확대 모드 일 때'MKUserTrackingModeFollowWithHeading'로 설정하고'didChangeUserTrackingMode' 호출의 사이클을 끝내더라도 추적 모드를'MKUserTrackingModeFollow'로 설정합니다. 때로는 충돌이 발생합니다. 'regionWillChangeAnimated'와'regionDidChangeAnimated'에서 플래그를 설정해 보았습니다. 문제를 해결하는 것 같지만 여전히 적절하지 않습니다. 최종선, 문제가 있으면 알려주세요. 더 많은 제안을 할 수 있습니다. – Rob

+0

'regionWillChangeAnimated' 또는'regionDidChangeAnimated' 메소드에서 확대/축소가 감지되면 trackingMode를 MKUserTrackingModeFollowWithHeading으로 변경해야합니까? 아니면'regionWillChangeAnimated' /'regionDidChangeAnimated'에만 있지만'didChangeUserTrackingMode'에는 없습니까? 물론 확대 할 때 속도가 느린 것 같습니다. 어쩌면'didChangeUserTrackingMode' 루프가 일어난 것 같아요. – kinamin

-1

스위프트 3

func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) {   
     var newMode: MKUserTrackingMode = .none 
     if (CLLocationManager.locationServicesEnabled()) { 
      if (CLLocationManager.headingAvailable()) { 
       newMode = .followWithHeading 
      } 
      else { 
       newMode = .follow 
      } 
     } 

     if (mode != newMode) 
     { 
      DispatchQueue.main.async { 
       mapView.setUserTrackingMode(newMode, animated: true) 
      } 
     } 
} 
관련 문제