2011-04-15 15 views
14

मुझे निम्न समस्या है:आईओएस - मैप व्यू को किसी विशिष्ट क्षेत्र में कैसे सीमित करें?

मेरे पास एक "खींचा नक्शा" (छवि) है जिसे मैं MapView में ओवरले के रूप में जोड़ता हूं। इसके साथ कोई समस्या नहीं है .. लेकिन मुझे ओवरव्यू के क्षेत्र में MapView को सीमित करने की आवश्यकता है, इसलिए कोई उपयोगकर्ता इस क्षेत्र के बाहर स्क्रॉल/ज़ूम करने में सक्षम नहीं है .. लेकिन "सीमाओं के अंदर स्क्रॉल/ज़ूम करना संभव होना चाहिए "ओवरले का मतलब है - इसका मतलब है कि मैं MapView के लिए बस ज़ूम/स्क्रॉलिंग अक्षम नहीं कर सकता।

क्या इस विषय पर कोई विचार/समाधान है? MapView/-Kit का उपयोग करने का कारण यह है कि मुझे कस्टम मानचित्र में विभिन्न पीओआई जोड़ने की आवश्यकता है। कस्टम मानचित्र पेश करने के लिए केवल एक छवि दृश्य + स्क्रॉलव्यू का उपयोग करते समय यह अधिक जटिल हो सकता है।

मैंने इस विषय पर बहुत कुछ शोध किया है, लेकिन मुझे कोई अच्छा समाधान नहीं मिला।

किसी भी मदद की सराहना की जाती है!

शुभकामनाओं सहित, ईसाई

संपादित करें: आप की आपूर्ति एक topleft और एक bottomright नक्शा सीमित करने के लिए समन्वय: यह हमारी समाधान है। (न्यूनतम) ज़ूमलेवल भी सीमित है। मैंने गति को निष्क्रिय कर दिया है और आप मानचित्र के थोड़ा सा बाउंस करने में सक्षम हैं (बेहतर प्रदर्शन/ux के लिए)। मैंने ओवरले में ~ 1 किमी ग्रे ग्रे सीमा जोड़ा ताकि उपयोगकर्ता Google के ऑरगनल वर्ल्डमैप को देखने में सक्षम न हो।

LimitedMapView.h:

#import <Foundation/Foundation.h> 
#import <MapKit/MapKit.h> 


@interface LimitedMapView : MKMapView <UIScrollViewDelegate>{ 

} 

@property (nonatomic, assign) CLLocationCoordinate2D topLeftCoordinate; 
@property (nonatomic, assign) CLLocationCoordinate2D bottomRightCoordinate; 


@end 

LimitedMapView.m:

#import "LimitedMapView.h" 

@implementation LimitedMapView 

@synthesize topLeftCoordinate, bottomRightCoordinate; 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView{ 

    if([super respondsToSelector:@selector(scrollViewDidZoom:)]) [super scrollViewDidZoom:scrollView]; 

    if ([self region].span.latitudeDelta > 0.002401f || [self region].span.longitudeDelta > 0.003433f) { 

     CLLocationCoordinate2D center = self.centerCoordinate; 
     MKCoordinateSpan span = MKCoordinateSpanMake(0.002401f, 0.003433f); 

     self.region = MKCoordinateRegionMake(center, span); 

    } 

} 

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 

    if([super respondsToSelector:@selector(scrollViewDidEndDragging:)]) [super scrollViewDidEndDragging:scrollView willDecelerate:decelerate]; 

    MKCoordinateRegion currentRegion = self.region; 
    bool changeRegionLong = YES; 
    bool changeRegionLat = YES; 

    // LONGITUDE  
    if((currentRegion.center.longitude - (currentRegion.span.longitudeDelta/2)) < self.topLeftCoordinate.longitude) { 

     currentRegion.center.longitude = (topLeftCoordinate.longitude + (currentRegion.span.longitudeDelta/2)); 

    } else if((currentRegion.center.longitude + (currentRegion.span.longitudeDelta/2)) > self.bottomRightCoordinate.longitude) { 

     currentRegion.center.longitude = (bottomRightCoordinate.longitude - (currentRegion.span.longitudeDelta/2)); 

    } else { 

     changeRegionLong = NO; 

    } 

    // LATITUDE  
    if((currentRegion.center.latitude + (currentRegion.span.latitudeDelta/2)) > self.topLeftCoordinate.latitude) { 

     currentRegion.center.latitude = (topLeftCoordinate.latitude - (currentRegion.span.latitudeDelta/2)); 

    } else if((currentRegion.center.latitude - (currentRegion.span.latitudeDelta/2)) < self.bottomRightCoordinate.latitude) { 

     currentRegion.center.latitude = (bottomRightCoordinate.latitude + (currentRegion.span.latitudeDelta/2)); 

    } else { 

     changeRegionLat = NO; 

    } 

    if(changeRegionLong || changeRegionLat) [self setRegion:currentRegion animated:YES]; 

} 

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{ 

    [scrollView setContentOffset:scrollView.contentOffset animated:YES]; 
} 

@end 
+0

मेरी समाधान जोड़ा। – cweinberger

+0

समाधान के साथ अद्यतन करने के लिए धन्यवाद। मैं बस अधिकतम ज़ूम को सीमित करना चाहता था, और केवल एक स्क्रॉल का उपयोग कर एक समस्या में भाग गया/दृश्यव्यूडिज़ ज़ूम: किसी और के लिए, सुनिश्चित करें कि आप अपनी नई अवधि को चेक अवधि के मुकाबले कम से कम सेट करें अन्यथा मैपव्यू अधिकतम पर फंस जाएगा ज़ूम। – Andrew

+0

स्विफ्ट के लिए एक बेहतर लिखित समाधान है http://stackoverflow.com/a/31799617/2814964 – cl3m

उत्तर

6

को लागू करने से:

-(void) mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated

आपको अपने विशिष्ट क्षेत्र में रीसेट करने में सक्षम होना चाहिए।

at that answer देखें कि यह कैसे करें इसका एक उदाहरण है।


एक अन्य समाधान, कि अधिक सटीक घटनाओं लाता है लेकिन अधिक जटिल(मैं वर्तमान में एक और जरूरत के लिए सफलतापूर्वक इस का उपयोग कर रहा है)MKMapView उपवर्ग और UIScrollViewDelegate प्रोटोकॉल ओवरराइड करने के लिए है।

आप ऐसा करते हैं, तो इस तरह super कार्यान्वयन कॉल करने के लिए सुनिश्चित करें:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    if ([super respondsToSelector:@selector(scrollViewWillBeginDragging:)]) 
    [super scrollViewWillBeginDragging:scrollView]; 
    // do what you want 
} 

नोट: हालांकि प्रोटोकॉल सार्वजनिक है, MKMapView कार्यान्वयन अज्ञात है और आईओएस संस्करणों के साथ अलग हो सकती है, तो यह अधिक सुरक्षित है respondsToSelector: से पहले जांचने के लिए। आप कॉल सुपर कार्यान्वयन या मानचित्र ठीक से काम नहीं करेगा

+0

हम्म .. मुझे लगता है कि जब मैं मानचित्र को स्थानांतरित करना शुरू करता हूं तो यह प्रतिनिधि आग लग जाएगा। दुर्भाग्यवश इस पल में मुझे नहीं पता कि उपयोगकर्ता मानचित्र के साथ क्या करेगा (वैध ज़ूम/स्क्रॉल इशारा हो सकता है)। और '- (शून्य) नक्शा देखें: (एमकेमैप व्यू *) नक्शा देखें क्षेत्र देखेंचंपेंजएनिमित: (बूल) एनिमेटेड 'बहुत देर हो चुकी है। या मैं इस के साथ पूरी तरह से गलत हूँ ?! – cweinberger

+0

ने एक और समाधान जोड़ा जो मदद कर सकता है;) –

+0

धन्यवाद! अच्छा लगता है, यह कोशिश करेगा :) – cweinberger

13

सीमित MKMapView के विभिन्न तरीकों की कोशिश के बाद मैंने निष्कर्ष निकाला गया है mapDidChange उपयोग कर, और रीसेट करने अगर आप केंद्र रहे हैं उस समय सीमाओं के बाहर चला जाता है, सबसे अच्छा काम करता एनिमेटेड साथ: हाँ

यहाँ कैसे मैं यह कर रहा है (का उपयोग करते हुए न्यूजीलैंड लेट/लांग अवधि/केंद्र)।

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{ 
    if ((mapView.region.span.latitudeDelta > 15.589921) || (mapView.region.span.longitudeDelta > 175.836914)) { 
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914); 

    MKCoordinateSpan spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500); 

    MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ); 

    [mapView setRegion: NZRegion animated: YES]; 
    } 

if (abs(abs(mapView.region.center.latitude) - 41.162114) > (13.589921/2)) { 
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914); 

    MKCoordinateSpan spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500); 

    MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ); 

    [mapView setRegion: NZRegion animated: YES]; 

    } 

    if (abs(abs(mapView.region.center.longitude) - 172.836914) > (14.062500/2)) { 
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914); 

    MKCoordinateSpan spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500); 

    MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ); 

    [mapView setRegion: NZRegion animated: YES]; 
    } 
} 
+1

मुझे उपरोक्त कोड का जिक्र स्तर पर एक सीमा का उल्लेख करना चाहिए। –

+0

किसी और के लिए इसे काम करने की कोशिश करने के लिए, यह निश्चित रूप से जाने का तरीका है। – Undistraction

+0

यह मेरे लिए एक अनंत रिकर्सन में बदल गया। मुझे एनआईबी से मानचित्र प्रतिनिधि को अनसेट करना पड़ा, और प्रारंभिक क्षेत्र को सेट करने के बाद प्रतिनिधि को 'viewDidLoad' में सेट किया गया। – Mazyod

0

मैं जानता हूँ कि यह एक बहुत पुराना सवाल है, लेकिन अनंत लूप से बचने के लिए आप कुछ इस तरह की कोशिश कर सकते: फिर फायरिंग यदि वह तुम थे के कॉलबैक को रोकने के लिए मूल रूप से सेट https://stackoverflow.com/a/4126011/1234011

एक ध्वज जो मूल्य निर्धारित करें।

  • केन