2012-08-06 16 views
21

ज़ूमिंग scrollEnabled उपयोगकर्ता MKMapView में पिनिंग शुरू करने के बाद ब्रेक करने योग्य प्रतीत होता है।एक MKMapView में स्क्रॉलिंग को रोकें, जब

आप अभी भी एक उंगली से स्क्रॉल नहीं कर सकते हैं, लेकिन यदि आप ज़ूम इन और आउट करते समय दो अंगुलियों से स्क्रॉल करते हैं, तो आप मानचित्र को स्थानांतरित कर सकते हैं।

मैं कोशिश की है:

  • इसके अंदर पुस्तक देखने को निष्क्रिय करने के MKMapKit उपवर्गीकरण।
  • कार्यान्वयन - mapView:regionWillChangeAnimated: केंद्र को लागू करने के लिए।
  • scrollEnabled को अक्षम करना।

लेकिन बिना किसी किस्मत के।

क्या कोई मुझे केवल MKMapView में ज़ूम करने का एक निश्चित तरीका बता सकता है, तो केंद्र बिंदु हमेशा मध्य में रहता है?

+2

मुझे इसे पहले करना था लेकिन इसे एक अलग तरीके से संभाला था। मैंने MKMapView के साथ बातचीत को अक्षम कर दिया और इसके ऊपर एक दृश्य में चुटकी इशारा पहचानकर्ता जोड़ा। फिर मैंने पिंच जेस्चर को इसी ज़ूम स्तर पर परिवर्तित कर दिया। तो अपने खुद के चुटकी-टू-ज़ूम को कार्यात्मक रूप से बहुत रोलिंग करना। यह देखकर यह आपके प्रश्न का सीधे जवाब नहीं देता है, अगर यह आपके लिए एक व्यवहार्य विकल्प है तो मैं कोड के साथ उत्तर में पोस्ट करूंगा। – random

उत्तर

29

आप एक UIPinchGestureRecognizer का उपयोग कर चुटकी इशारों खुद को संभालने के लिए कोशिश कर सकते हैं:

पहले सेट scrollEnabled और zoomEnabledNO करने और इशारा पहचानकर्ता बनाएँ:

UIPinchGestureRecognizer* recognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self 
                       action:@selector(handlePinch:)]; 
[self.mapView addGestureRecognizer:recognizer]; 

पहचानकर्ता हैंडलर में के अनुसार MKCoordinateSpan समायोजित ज़ूम स्केल:

- (void)handlePinch:(UIPinchGestureRecognizer*)recognizer 
{ 
    static MKCoordinateRegion originalRegion; 
    if (recognizer.state == UIGestureRecognizerStateBegan) { 
     originalRegion = self.mapView.region; 
    }  

    double latdelta = originalRegion.span.latitudeDelta/recognizer.scale; 
    double londelta = originalRegion.span.longitudeDelta/recognizer.scale; 

    // TODO: set these constants to appropriate values to set max/min zoomscale 
    latdelta = MAX(MIN(latdelta, 80), 0.02); 
    londelta = MAX(MIN(londelta, 80), 0.02); 
    MKCoordinateSpan span = MKCoordinateSpanMake(latdelta, londelta); 

    [self.mapView setRegion:MKCoordinateRegionMake(originalRegion.center, span) animated:YES]; 
} 

यह ऐप्पल के कार्यान्वयन की तरह पूरी तरह से काम नहीं कर सकता है लेकिन इसे आपकी समस्या का समाधान करना चाहिए।

+1

मुझे नहीं लगता कि यह समाधान बहुत अच्छा है। यह सेब द्वारा प्रदान किए गए डिफ़ॉल्ट ज़ूम की तुलना में बहुत घबराहट महसूस करता है। उदाहरण के लिए, चुटकी और स्क्रीन अद्यतन के बीच एक अंतराल है। –

+0

यह बिल्कुल काम नहीं करता है। – Haitao

+0

एनिमेटेड बदलें: एनिमेटेड में हाँ: अंतिम पंक्ति [self.mapView setRegion: MKCoordinateRegionMake (originalRegion.center, span) एनिमेटेड: हाँ]; और यह आसानी से काम कर रहा है। –

1

अपने मानचित्र दृश्य के प्रतिनिधि में –mapView:regionWillChangeAnimated: या –mapView:regionDidChangeAnimated: लागू करने का प्रयास करें ताकि मानचित्र हमेशा आपके पसंदीदा स्थान पर केंद्रित हो।

+0

कोशिश की ... इसका कोई प्रभाव नहीं है। –

1

मैंने पहले इस बारे में पढ़ा है, हालांकि मैंने वास्तव में कभी कोशिश नहीं की है। सीमाओं के साथ एक MKMapView के बारे में इस आलेख पर एक नज़र डालें। यह देखने के लिए कि उपयोगकर्ता द्वारा दृश्य स्क्रॉल किया गया है, यह दो प्रतिनिधि तरीकों का उपयोग करता है।

http://blog.jamgraham.com/blog/2012/04/29/adding-boundaries-to-mkmapview

लेख एक दृष्टिकोण है जो तुम क्या कोशिश की है के समान है का वर्णन करता है, इसलिए, खेद अगर आप पहले से इस पर ठोकर खाई है।

1

मेरे पास इनमें से किसी भी उत्तर के साथ बहुत भाग्य नहीं था। अपने खुद के चुटकी करना सिर्फ इतना संघर्ष किया। मैं ऐसे मामलों में दौड़ रहा था जहां सामान्य ज़ूम मेरे अपने चुटकी के साथ ज़ूम कर सकता था।

- (void) mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { 
    MKCoordinateRegion region = mapView.region; 
    //... 
    // adjust the region.center 
    //... 
    mapView.region = region; 
} 

मैं क्या पाया गया कि कोई प्रभाव नहीं पड़ा था:

मूल रूप से, मैं की तरह कुछ करने के लिए मूल पोस्टर के रूप में की कोशिश की। मैंने NSLog के माध्यम से भी खोज की है कि जब भी मैं region या centerCoordinate प्रोग्रामेटिक रूप से सेट करता हूं तो यह विधि भी आग लग जाएगी। जिसने सवाल उठाया: "उपरोक्त नहीं, अगर यह काम करता है तो अनंत?"

तो मैं conjecturing रहा हूँ और hypothesizing अब यह है कि जब उपयोगकर्ता ज़ूम/पुस्तक/घुमा हो रहा है, MapView किसी भी तरह का दमन करता है या ध्यान नहीं देता है क्षेत्र के लिए बदल जाता है। मध्यस्थता के बारे में कुछ कार्यक्रम संबंधी समायोजन नपुंसक बना देता है।

अगर ऐसा है समस्या, तो शायद regionDidChanged: अधिसूचना के बाहर क्षेत्र समायोजन प्राप्त करने की कुंजी है। और चूंकि कोई समायोजन एक और अधिसूचना को ट्रिगर करेगा, इसलिए यह महत्वपूर्ण है कि यह निर्धारित करने में सक्षम हो कि अब समायोजित नहीं किया जाए। इससे मुझे निम्नलिखित कार्यान्वयन का सामना करना पड़ा (जहां subject केंद्र समन्वय की आपूर्ति कर रहा है कि मैं बीच में रहना चाहता हूं):

- (void) recenterMap { 
    double latDiff = self.subject.coordinate.latitude self.mapView.centerCoordinate.latitude; 
    double lonDiff = self.subject.coordinate.longitude - self.mapView.centerCoordinate.longitude; 
    BOOL latIsDiff = ABS(latDiff) > 0.00001; 
    BOOL lonIsDiff = ABS(lonDiff) > 0.00001; 
    if (self.subject.isLocated && (lonIsDiff || latIsDiff)) { 
     [self.mapView setCenterCoordinate: self.subject.coordinate animated: YES]; 
    } 
} 

- (void) mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { 
    if (self.isShowingMap) { 
     if (self.isInEdit) { 
      self.setLocationButton.hidden = NO; 
      self.mapEditPrompt.hidden = YES; 
     } 
     else { 
      if (self.subject.isLocated) { // dispatch outside so it will happen after the map view user events are done 
       dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^{ 
        [self recenterMap]; 
       }); 
      } 
     } 
    } 
} 

देरी जहां इसे वापस स्लाइड करता है, वह भिन्न हो सकता है, लेकिन यह वास्तव में बहुत अच्छी तरह से काम करता है। और जब यह हो रहा है, तो नक्शे पर बातचीत ऐप्पल-एस्क्यू रहती है।

1

मैंने कोशिश की और यह काम करता है। regionWillChangeAnimated में फिर

var originalCenter: CLLocationCoordinate2D? 

जाँच इस घटना एक UIPinchGestureRecognizer के कारण होता है, तो:

पहले एक संपत्ति बनाने के लिए, regionDidChangeAnimated में फिर

func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool) { 
    let firstView = mapView.subviews.first 
    if let recognizer = firstView?.gestureRecognizers?.filter({ $0.state == .Began || $0.state == .Ended }).first as? UIPinchGestureRecognizer { 
     if recognizer.scale != 1.0 { 
      originalCenter = mapView.region.center 
     } 
    } 
} 

अगर पिंच जेस्चर का कारण बना मूल क्षेत्र पर लौटने क्षेत्र बदल रहा है:

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) { 
    if let center = originalCenter { 
     mapView.setRegion(MKCoordinateRegion(center: center, span: mapView.region.span), animated: true) 
     originalCenter = nil 
     return 
    } 
// your other code 
} 
1

स्विफ्ट 3.0 @ पैरास जोशी का संस्करण https://stackoverflow.com/a/11954355/3754976

छोटे एनीमेशन फ़िक्स के साथ।

class MapViewZoomCenter: MKMapView { 

    var originalRegion: MKCoordinateRegion! 

    override func awakeFromNib() { 
     self.configureView() 
    } 

    func configureView() { 
     isZoomEnabled = false 
     self.registerZoomGesture() 
    } 

    ///Register zoom gesture 
    func registerZoomGesture() { 
     let recognizer = UIPinchGestureRecognizer(target: self, action:#selector(MapViewZoomCenter.handleMapPinch(recognizer:))) 
     self.addGestureRecognizer(recognizer) 
    } 

    ///Zoom in/out map 
    func handleMapPinch(recognizer: UIPinchGestureRecognizer) { 

     if (recognizer.state == .began) { 
      self.originalRegion = self.region; 
     } 

     var latdelta: Double = originalRegion.span.latitudeDelta/Double(recognizer.scale) 
     var londelta: Double = originalRegion.span.longitudeDelta/Double(recognizer.scale) 

     //set these constants to appropriate values to set max/min zoomscale 
     latdelta = max(min(latdelta, 80), 0.02); 
     londelta = max(min(londelta, 80), 0.02); 

     let span = MKCoordinateSpanMake(latdelta, londelta) 

     self.setRegion(MKCoordinateRegionMake(originalRegion.center, span), animated: false) 

    } 
} 
संबंधित मुद्दे