2010-04-13 59 views
8

我在UIPopoverController的內容中有一個按鈕。這個按鈕運行一個名爲myAction的方法。ipad - 解僱UIPopoverController

MyAction具有

- (void) myAction:(id)sender 

所以,myAction接收呼叫者按鈕的ID的形式。

現在,在這個方法中,我想關閉UIPopoverController,但我唯一擁有的是調用者按鈕的ID。請記住,該按鈕位於UIPopoverController內部。

有沒有一種方法來發現UIPopoverController的ID,給出我已經有的按鈕ID?

謝謝。

回答

19

不幸的是沒有。至少,不在標準做法內。你可能能夠通過響應堆棧來找到它,但這是一個黑客攻擊,它很麻煩,而且確實很雜亂。

如果您想通過按下按鈕來解除彈出窗口,某個相關的地方應該保留對彈窗的引用。通常這將是popover的所有者(而不是控制器顯示的popover內)。按下按鈕後,它可以向所有者控制器發送消息,然後可以解除彈出窗口。

您可能會想讓控制器在彈出窗口內顯示爲自己的彈出窗口的所有者,但這種方式的編碼很脆弱,可能會變得混亂(可能會再次),並可能導致保留循環,釋放。

+0

謝謝。我會改變代碼! – SpaceDog 2010-04-13 16:00:40

+3

第二段在這個答案中非常重要。請記住,根據iPad編程指南:「但請注意,您有責任存儲對popover控制器的引用,以便解除它,系統默認不提供。」因此,不要對其執行「釋放」(直到父視圖進入dealloc階段)。 (這是我的安全方法)。 – Jann 2010-04-14 17:04:25

+0

只需使用[self dismissViewControllerAnimated:YES completion:nil]; 「呈現視圖控制器負責解除其呈現的視圖控制器,如果您在呈現的視圖控制器本身上調用此方法,它會自動將該消息轉發給呈現視圖控制器。」 – 2014-04-03 18:44:20

4

我有這個工作,我不認爲這是一個破解。我有一個標準的拆分視圖iPad應用程序。然後我在細節控制器(彈出窗口的擁有者)上添加了一個方法來處理解僱。

在標準拆分視圖架構上,根和視圖控制器都可以通過應用程序委託來使用。所以我在彈出窗口中單擊一個按鈕來調用一個獲取應用程序委託的方法。從那裏,我稱之爲詳細控制器上的方法來消除流行音樂。

這對於在酥料餅的內部顯示在視圖控制器的方法的代碼:

- (void) exitView: (id)sender { 
    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 

    [appDelegate.detailViewController exitDrill]; 
} 

然後簡單的方法以關閉上的詳細視圖控制器:

- (void) exitDrill { 
    if(dtController != nil){ 
     [dtController dismissPopoverAnimated: YES]; 
     [dtController release]; 
    } 
} 

我喜歡能夠做到這一點,因爲它給我一種方式來向用戶展示他們如何退出流行音樂。這在未來的應用程序版本中可能不是必需的;現在,雖然這個範例對這個平臺來說仍然是新的,但我更願意讓用戶在不同的方式中對一個對象進行顯示,以確保我最大限度地減少挫折感。

5

您可以通過訪問KVC的「popoverController」來訪問呈現popoverController。

[[self valueForKey:@"popoverController"] dismissPopoverAnimated:YES] 
+1

智能,但是有這種機會被標記爲「使用私有API」,應用程序被拒絕,即使技術上它沒有使用私有API? – 2012-09-07 13:00:13

+0

是@Chintan。如果他們檢測到您的代碼正在使用其「私有API」,它可能會被AppStore拒絕。 – 2012-11-22 11:23:31

+0

@JasonMing這是我唯一的工作,我花了5小時的最佳部分試圖找到解決方案。非常感謝... – 2016-11-27 23:22:57

0

愛德馬蒂已經寫

如果您想通過按下一個按鈕駁回酥料餅,一些地方相關的應恪守酥料餅

參考這是非常真實的;但是,在顯示UIPopoverController時,打開popovercontroller的類已經保存了該資源。所以,你可以做的是使用這個類作爲你的Popover控制器的委託類。

爲此,您可以執行以下操作,在代碼中使用該操作。 在課堂上打開酥料餅,這是我的代碼:

- (void)showInformationForView:(Booking*)booking frame:(CGRect)rect 
{ 
    BookingDetailsViewController *bookingView = [[BookingDetailsViewController alloc] initWithStyle:UITableViewStyleGrouped booking:booking]; 
    [bookingView setDelegate:self]; 

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:bookingView]; 

    self.popController = [[UIPopoverController alloc] initWithContentViewController:navController]; 
    [self.popController setDelegate:self]; 
    [self.popController setPopoverContentSize:CGSizeMake(320, 320)]; 

    rect.size.width = 0; 

    [self.popController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES]; 
} 

- (void)dismissPopoverAnimated:(BOOL)animated 
{ 
    [self.popController dismissPopoverAnimated:animated]; 
} 

那麼我這裏做的是創造一個UINavigationController和設置BookingDetailsViewControllerrootViewController。然後,我還將當前班級作爲代表添加到此BookingDetailsViewController

我添加的第二件事是一種名爲dismissPopoverAnimated:animated的解僱方法。

在我BookingDetailsViewController.h添加以下代碼:

[...] 
@property (nonatomic, strong) id delegate; 
[...] 

在我BookingDetailsViewController.m我加入這個代碼:

[...] 

@synthesize delegate = _delegate; 

- (void)viewDidLoad 

{ 
    UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(closeView)]; 
    [self.navigationItem setRightBarButtonItem:closeButton]; 

    [super viewDidLoad]; 
} 

- (void)closeView 
{ 
    if ([self.delegate respondsToSelector:@selector(dismissPopoverAnimated:)]) { 
     [self.delegate dismissPopoverAnimated:YES]; 
    } 
    else { 
     NSLog(@"Cannot close the view, nu such dismiss method"); 
    } 
} 

[...] 

什麼情況是,當UINavigationController的「關閉」按鈕按下,調用方法closeView。此方法檢查代理是否響應dismissPopoverAnimated:animated,如果是,則調用它。如果它不響應這個方法,它會顯示一條日誌消息並且什麼也不做(所以它不會崩潰)。

我用ARC寫過我的代碼,因此沒有內存管理。

我希望這對你有所幫助。