MKMapView가 드래그되었는지 확인하는 방법이 있습니까?
사용자가 사용하여지도를 끌 때마다 중심 위치를 얻고 싶지만 사용자가지도를 CLLocationCoordinate2D centre = [locationMap centerCoordinate];
탐색하자마자 실행되는 델리게이트 메서드 또는 무언가가 필요합니다.
미리 감사드립니다
답변
상기 봐 MKMapViewDelegate의 참조입니다.
특히 다음 방법이 유용 할 수 있습니다.
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
해당 메서드가 호출되도록 맵 뷰의 대리자 속성이 설정되어 있는지 확인합니다.
답변
어떤 이유로 든 지역이 변경되면 수락 된 답변의 코드가 실행됩니다. 지도 끌기를 제대로 감지하려면 UIPanGestureRecognizer를 추가해야합니다. Btw, 이것은 드래그 제스처 인식기입니다 (패닝 = 드래그).
1 단계 : viewDidLoad에 제스처 인식기 추가 :
-(void) viewDidLoad {
[super viewDidLoad];
UIPanGestureRecognizer* panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didDragMap:)];
[panRec setDelegate:self];
[self.mapView addGestureRecognizer:panRec];
}
2 단계 : UIGestureRecognizerDelegate 프로토콜을 뷰 컨트롤러에 추가하여 델리게이트로 작동합니다.
@interface MapVC : UIViewController <UIGestureRecognizerDelegate, ...>
3 단계 : UIPanGestureRecognizer가 MKMapView의 기존 제스처 인식기와 함께 작동하도록 다음 코드를 추가합니다.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
4 단계 : 메서드를 드래그 당 50 번 대신 한 번 호출하려는 경우 선택기에서 “드래그 종료”상태를 감지합니다.
- (void)didDragMap:(UIGestureRecognizer*)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
NSLog(@"drag ended");
}
}
답변
이것은 사용자가 시작한 확대 / 축소 변경과 이동을 감지하는 유일한 방법입니다.
- (BOOL)mapViewRegionDidChangeFromUserInteraction
{
UIView *view = self.mapView.subviews.firstObject;
// Look through gesture recognizers to determine whether this region change is from user interaction
for(UIGestureRecognizer *recognizer in view.gestureRecognizers) {
if(recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateEnded) {
return YES;
}
}
return NO;
}
static BOOL mapChangedFromUserInteraction = NO;
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
mapChangedFromUserInteraction = [self mapViewRegionDidChangeFromUserInteraction];
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
답변
(그냥) @mobi의 탁월한 솔루션의 Swift 버전 :
private var mapChangedFromUserInteraction = false
private func mapViewRegionDidChangeFromUserInteraction() -> Bool {
let view = self.mapView.subviews[0]
// Look through gesture recognizers to determine whether this region change is from user interaction
if let gestureRecognizers = view.gestureRecognizers {
for recognizer in gestureRecognizers {
if( recognizer.state == UIGestureRecognizerState.Began || recognizer.state == UIGestureRecognizerState.Ended ) {
return true
}
}
}
return false
}
func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
mapChangedFromUserInteraction = mapViewRegionDidChangeFromUserInteraction()
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
답변
위 의 Jano의 답변에 대한 Swift 3 솔루션 :
ViewController에 프로토콜 UIGestureRecognizerDelegate 추가
class MyViewController: UIViewController, UIGestureRecognizerDelegate
에서 UIPanGestureRecognizer를 viewDidLoad
만들고 delegate
self로 설정 합니다.
viewDidLoad() {
// add pan gesture to detect when the map moves
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.didDragMap(_:)))
// make your class the delegate of the pan gesture
panGesture.delegate = self
// add the gesture to the mapView
mapView.addGestureRecognizer(panGesture)
}
제스처 인식기가 기존 MKMapView 제스처와 함께 작동하도록 프로토콜 메서드를 추가합니다.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
이동 제스처에서 선택기가 호출 할 메서드를 추가합니다.
func didDragMap(_ sender: UIGestureRecognizer) {
if sender.state == .ended {
// do something here
}
}
답변
내 경험상 “입력하는 동안 검색”과 유사하게 타이머가 가장 신뢰할 수있는 솔루션이라는 것을 알았습니다. 이동, 집기, 회전, 두드리기, 두 번 두드리기 등을위한 제스처 인식기를 추가 할 필요가 없습니다.
해결책은 간단합니다.
- 지도 지역이 변경되면 타이머 설정 / 초기화
-
타이머가 실행되면 새 지역의 마커를로드합니다.
import MapKit class MyViewController: MKMapViewDelegate { @IBOutlet var mapView: MKMapView! var mapRegionTimer: NSTimer? // MARK: MapView delegate func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) { setMapRegionTimer() } func setMapRegionTimer() { mapRegionTimer?.invalidate() // Configure delay as bet fits your application mapRegionTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "mapRegionTimerFired:", userInfo: nil, repeats: false) } func mapRegionTimerFired(sender: AnyObject) { // Load markers for current region: // mapView.centerCoordinate or mapView.region } }
답변
또 다른 가능한 해결책은 다음과 같이지도보기를 보유하는보기 컨트롤러에서 touchesMoved : (또는 touchesEnded : 등)를 구현하는 것입니다.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
for (UITouch * touch in touches) {
CGPoint loc = [touch locationInView:self.mapView];
if ([self.mapView pointInside:loc withEvent:event]) {
#do whatever you need to do
break;
}
}
}
경우에 따라 제스처 인식기를 사용하는 것보다 더 간단 할 수 있습니다.