2010-04-14 11 views
9

मैं एनोटेशन के साथ एक MKMapView (यह भी एक UIPopoverControllerDelegate) है। इस मानचित्र दृश्य में MKTestMapView.h फ़ाइल, UIPopoverController* popoverController @interface में परिभाषित किया गया है और @interface अनुभाग के बाहर परिभाषित किया गया है। इस नियंत्रक MKTestMapView.m फ़ाइल में @synthesized है और यह - (void)dealloc खंड में जारी किया गया है।MKMapView (SDK3.2) में UIPopoverController साथ आईपैड पर dismissPopoverAnimated कैसे

- (void)mapView:(MKMapView *)mapView2 annotationView:(MKAnnotationView *)aview calloutAccessoryControlTapped:(UIControl *)control{ 

... 

CGPoint leftTopPoint = [mapView2 convertCoordinate:aview.annotation.coordinate toPointToView:mapView2]; 

int boxDY=leftTopPoint.y; 
int boxDX=leftTopPoint.x; 
NSLog(@"\nDX:%d,DY:%d\n",boxDX,boxDY); 

popoverController = [[UIPopoverController alloc] initWithContentViewController:controller]; 
popoverController.delegate = self; 
CGSize maximumLabelSize = CGSizeMake(320.0f,600.0f); 

popoverController.popoverContentSize = maximumLabelSize; 

CGRect rect = CGRectMake(boxDX, boxDY, 320.0f, 600.0f); 

[popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES]; 


... 

} 

अब यहाँ मज़ा हिस्सा आता है: इस MapView में एनोटेशन rightCalloutAccessoryView रों निम्नलिखित करने के लिए परिभाषित किया है। सबसे पहले, मुझे यकीन नहीं है कि मुझे maximumLabelSize और rect एक ही आकार के लिए चाहिए। मैं .. पॉपओवर शो popovercontroller तो मैं कान से इस खेल रहा हूँ करने के लिए नया हूँ,

ठीक है। अब इसे खारिज करने के लिए। मैं mapView2 पर कहीं भी क्लिक कर सकता हूं और पॉपओवर चला जाता है ... लेकिन अगर उपयोगकर्ता कुछ भी बदलता है तो मुझे दृश्य में बटन क्लिक करने की आवश्यकता होती है। Urgh!

डॉक्स दिखाने:

एक पॉपओवर प्रोग्राम के रूप में खारिज करने के लिए कॉल dismissPopoverAnimated: पॉपओवर नियंत्रक के विधि।

ठीक है, यहाँ समस्या है: कैसे popoverController काम करता है की परिभाषा के अनुसार, आप प्रदर्शित पॉपओवर को देखते अंदर क्लिक कर रहे हैं (बटन पर क्लिक करें), लेकिन नियंत्रक के dismissPopoverAnimated: विधि को गति प्रदान करने के लिए है कि MKTestMapView.m फाइल के अंदर, इस पॉपओवर दृश्य का शुभारंभ किया, मेरे मामले में popoverController

अब, कहा है कि सभी, याद है, [popoverController release] नहीं होता है जब तक:

- (void)dealloc { 
[popoverController release]; 
[mapView release]; 
    [super dealloc]; 
} 

तो, मैं बस बटन के अंदर निम्नलिखित करते हैं (गन्दा लेकिन काम कर सकते हैं):

(मेरी पॉपओवर दृश्य मान लिया जाये कि एक tableview) में है:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
MKTestMapView * mKTestMapView = [[MKTestMapView alloc] init]; 
[[mKTestMapView popoverController].dismissPopoverAnimated:YES]; 
} 

यहाँ मेरी समस्या नहीं है: मैं पता लगाएँ कि क्या ऊपर कर मुझे एक reference देता है समझ नहीं सकता (यदि वहाँ ऐसी है एक बात) मौजूदा स्क्रीन पर है - और इसलिए दृश्य जो उस पॉपओवर नियंत्रक का मालिक है। अगर ऐसा है के रूप में सरल रूप में

[[[self parentView] popoverController].dismissPopoverAnimated:YES]; 

मैं अपने आप को गोली मार होगा क्योंकि मुझे नहीं लगता है कि या तो सही सिंटैक्स है है!

यह आसान होना चाहिए ... अभी तक मैं हार रहा हूँ। (शायद मैं इतने सारे आईपैड मतभेदों से निराश हूं जो मैं सीख रहा हूं)।

किसी को भी और अधिक व्याख्या कर सकते हैं?

उत्तर

18

मुझे एक ही समस्या थी ... मेरे पास पॉपओवर द्वारा लोड किए गए मेरे दृश्य के शीर्ष में एक साफ "बंद" बटन (एक्स) था, लेकिन यह काम नहीं किया। मेरे सार्वभौमिक ऐप में इसे एक नए दृश्य के रूप में प्रस्तुत किया जाएगा, ताकि कोड रहना चाहिए।

अब मैं क्या किया है कि मैं (देखें पॉपओवर भार) मेरी detailedPinView के लिए निम्न जोड़ा था:

detailedPinView.h फ़ाइल में

:

@interface detailedPinView : UIViewController { 
    [...] 
    UIPopoverController *popover; 
    [...] 
} 

-(void)setPopover:(UIPopoverController*)aPopover; 

detailedPinView.m फ़ाइल में:

- (void)setPopover:(UIPopoverController*)aPopover 
{ 
    popover = aPopover; 
} 

X बटन एक IBAction का उपयोग कर दृश्य बंद कर देता है, यह क्या मैं वहाँ किया है:

detailedPinView.m फ़ाइल में:

[...] 
-(void)mapView:(MKMapView *)theMapView annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control 
{ 
    UIViewController *detailController = [[detailedPinView alloc] initWithNibName:@"detailedPinView" 
                      bundle:nil 
                    annotationView:pin]; 

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
    { 

     UIPopoverController* aPopover = [[UIPopoverController alloc] initWithContentViewController:detailController]; 
     [aPopover setDelegate:self]; 
     [aPopover setPopoverContentSize:CGSizeMake(320, 320) animated:YES]; 

     [detailController setPopover:aPopover]; 
     [detailController release]; 

     [mapView deselectAnnotation:pin.annotation animated:YES]; 

     self.popoverController = aPopover; 

     [mapView setCenterCoordinate:pin.annotation.coordinate animated:YES]; 

     [self.popoverController presentPopoverFromRect:CGRectMake(382,498,0,0) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; 
    } 
    else 
    { 
     [self presentModalViewController: detailController animated:YES]; 
    } 


    [detailController release]; 
} 
[...] 

अगर जवाब था आप मुझे नहीं पता है:

-(IBAction)releaseDetailedView:(UIButton *)sender 
{ 
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
    { 
     if (popover != nil) 
     { 
      [popover dismissPopoverAnimated:YES]; 
     } 
     else { 
      NSLog(@"Nothing to dismiss"); 
     } 
    } 
    else{ 
     [self.parentViewController dismissModalViewControllerAnimated: YES]; 
    } 
} 

वर्ग लोड हो रहा है मेरे मानचित्र और पॉपओवर दृश्य मैं निम्नलिखित कोड जोड़ा उम्मीद कर रहे थे, मुझे लगता है कि यह करने के लिए यह एक गन्दा तरीका हो सकता है ... लेकिन समय सारिणी देने से यह एक आकर्षण की तरह काम करता है :)

+0

जितना मैं इस नफरत के रूप में: अगर (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) क्योंकि आप इसे यूनिवर्सल ऐप में या प्री-3.2 ऐप में उपयोग नहीं कर सकते हैं, मैं इसे उत्तर के रूप में चिह्नित कर रहा हूं: [विस्तार नियंत्रक सेटपोपर: एपोपर]; मुझे क्या चाहिए Thx – Jann

+1

हाँ, मैं सहमत हूं। मेरे टाइम शेड्यूल को ज्यादा पसंद नहीं किया गया था लेकिन इसे "भविष्य में" बदल देगा। मैं खुशी से मदद कर सकता है! सम्मान, पॉल –

+1

@Jann "क्योंकि आप इसे यूनिवर्सल ऐप में या प्री-3.2 ऐप में उपयोग नहीं कर सकते हैं"। हाँ तुम कर सकते हो। जब तक आपका बेस एसडीके 3.2 हो, तब तक यह प्री-3.2 उपकरणों पर तैनात होने पर सही ढंग से चलाया जाएगा। – user102008

1

यहां एक और आसान समाधान है।

मुझे पता चला कि हमें पॉपओवर को स्पष्ट रूप से खारिज करने के लिए निम्नलिखित चरणों का पालन करना चाहिए।

  1. एक पॉपओवर को खारिज कर दिया।
  2. पॉपओवर द्वारा लोड किया गया एक दृश्य जारी करें।

आईओएस 8 से पहले, हम सभी लगभग एक पॉपओवर द्वारा लोड किए गए दृश्य को जारी कर सकते हैं, और फिर हम प्रोग्रामर रूप से पॉपओवर को खारिज कर देते हैं। हालांकि, आईओएस 8 में, हम रिवर्स में कदम उठाते हैं।

iOS8 पहले

, एक पॉपओवर

// creating a popover loading an image picker 
picker = [[UIImagePickerController alloc] init]; 
... 
pickerPopover = [[UIPopoverController alloc] initWithContentViewController:picker]; 
[pickerPopover presentPopoverFromRect:aFrame inView:aView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 

// dismissing the popover 
[picker.view removeFromSuperview]; // (1) release a view loaded by a popover 
[picker release], picker = nil; 

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
    [pickerPopover dismissPopoverAnimated:YES]; // (2) dismiss the popover 
} 

iOS8 में, खारिज कोड भाग के रूप में नीचे बदला जाना चाहिए खारिज की मेरी कोड,

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
    [pickerPopover dismissPopoverAnimated:YES]; // (2) dismiss the popover first 
} 

[picker.view removeFromSuperview]; // (1) and then release the view loaded by the popover 
[picker release], picker = nil;