2014-06-30 48 views
17

我注意到在一個項目中,由於某種原因,彈出窗口在右側欄按鈕項目上的位置似乎偏離了右側。我已經嘗試使用UIButton作爲自定義視圖,然後展示該按鈕的彈出窗口,但彈出窗口似乎忽略了showFromRect,如果我實際上提供了「居中」值。UIPopover presentFromBarButton off center

Off-center popover

這背後的代碼非常簡單:現在

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"share"] style:UIBarButtonItemStylePlain target:self action:@selector(shareTap:)]; 

    self.navigationItem.rightBarButtonItem = button; 
} 

- (void)shareTap:(UIBarButtonItem *)button { 
    self.popover = [[UIPopoverController alloc] initWithContentViewController:[[UIViewController alloc] init]]; 

    [self.popover presentPopoverFromBarButtonItem:button permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; 
} 

,如果我切換到使用內部按鈕,如前所述,我看到類似的行爲(附註顏色變化,使圖像顯示出來)。

using internal button

該代碼,這仍然是相當簡單:這裏

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    UIButton *innerButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 22, 22)]; 
    [innerButton setImage:[UIImage imageNamed:@"share"] forState:UIControlStateNormal]; 
    [innerButton addTarget:self action:@selector(shareTap:) forControlEvents:UIControlEventTouchUpInside]; 

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:innerButton];; 
} 

- (void)shareTap:(UIButton *)button { 
    self.popover = [[UIPopoverController alloc] initWithContentViewController:[[UIViewController alloc] init]]; 

// CGRect bottomCenter = CGRectMake(button.frame.size.width/2, button.frame.size.height, 1, 1); 
    CGRect bottomCenter = CGRectMake(2, button.frame.size.height, 1, 1); 

    [self.popover presentPopoverFromRect:bottomCenter inView:button permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; 
} 

注意,而不是使用實際的中心,我已經使用了任意值,2。如果我用1或0,彈出窗口變爲左對齊。大於1的任何東西再次對齊。

left-aligned

我搜索了一下週圍尋找一個類似的問題,但我似乎無法找到同樣的問題的人。任何圍繞什麼原因或如何避免它的想法將不勝感激。我唯一能夠猜到的是,由於它靠近邊緣,蘋果會做一些定位巫術來迫使它成爲他們想要的地方。問題是右上角的按鈕看起來像是一個非常標準的下拉位置。

編輯:我已經證實,在本地郵件應用程序中,長按「新郵件」圖標也會發生同樣的行爲。

編輯2:我能夠向Apple確認這是一個問題。在其中一個更新的版本中(我記不清哪一個是我認爲的9箇中的一個),他們這樣做是爲了您可以手動設置它。我相信默認行爲仍然是錯誤的(我還沒有嘗試過這一段時間),但是如果你這麼傾向,你可以使用CGRect偏移方法使它正常工作。

+0

嘗試此 的UIBarButtonItem *按鈕= [[ALLOC的UIBarButtonItem] initWithBarButtonSystemItem:UIBarButtonSystemItemAction目標:自動作:@selector(輕觸分享:)]; – Nishant

+1

你能解釋一下嗎?使用系統項目本身並不能修復按鈕的位置,在我的編輯中我提到了默認的應用程序也展示了這個問題(郵件),這大概是使用系統圖標。 – shortstuffsushi

回答

-2

試試這個自定義的Popover控制器 - WYPopoverController(https://github.com/nicolaschengdev/WYPopoverController)來解決問題。

+2

我不是在尋找一個替代庫,只是試圖瞭解本地控制器的行爲。事實上,WY控制器的第一個屏幕截圖也是偏離中心的:(儘管如此,儘管如此。 – shortstuffsushi

0

以下是一種方法:使用帶有自定義視圖的UIBarButtonItem而不是使用UIBarButtonSystemItem。只需將UIButton拖入UINavigationBar即可獲得UIBarButtonItem,其中嵌入UIButton,該值顯示爲UIBarButtonItem的customView。

@IBAction func didTapActionButton(_ sender: Any) { 
    if let vc = self.storyboard?.instantiateViewController(withIdentifier: "myPopover") { 
     vc.modalPresentationStyle = .popover 
     guard let innerView = actionButton.customView else { 
      // Unexpected missing custom view 
      return 
     } 

     vc.popoverPresentationController?.sourceView = navigationController?.navigationBar 
     vc.popoverPresentationController?.sourceRect = innerView.frame 
     self.present(vc, animated: true, completion: nil) 
    } 
} 
+0

我想你可能會注意到這是iOS 9後的固定版本。我在我的帖子開頭提到,即使是UIButton沒有工作,但後來(在編輯中)蘋果更新它,以便*可以*修復使用UIButton的定位。 – shortstuffsushi

+0

我有你最初在iOS 10項目中描述的彈出箭頭偏移問題,這是對我來說 - 我想你說的是,這種方法不適用於存在錯誤的iOS 9,但我沒有嘗試這種方式 – stevex

0

您必須指定彈出窗口需要顯示的欄按鈕的框架。

以下代碼將UIAlertController顯示爲條形按鈕的彈出式窗口。

@IBOutlet weak var playerRightBarButton: UIBarButtonItem! 

    extension UIBarButtonItem { 
     var frame: CGRect? { 
     guard let view = self.value(forKey: "view") as? UIView else { 
      return nil 
     } 
     return view.frame 
    } 
    } 

    let alert = UIAlertController(title: "", message: "Sample PopOver", 
    preferredStyle: .actionSheet) 
    if alert.responds(to: #selector(getter: popoverPresentationController)) { 
      alert.popoverPresentationController?.sourceView = self.view 
      alert.popoverPresentationController?.barButtonItem = playerRightBarButton 
      alert.popoverPresentationController?.permittedArrowDirections = .up 
      if let frame = playerRightBarButton.frame { 
       alert.popoverPresentationController?.sourceRect = frame 
      } 
     } 
     self.present(alert, animated: true, completion: nil) 
+0

我並不完全確定,但我不認爲這與我的問題有關,這是如何解決箭頭位置的問題的?你指的是什麼「框架」設置?你是否在談論在UIBarButtonItem類中添加該擴展方法? – shortstuffsushi

+0

擴展爲您提供了barButton的框架。我們設置 彈出窗口需要呈現的框架,因此它本身就是中心。我已經提供了一個alertController的例子,在iPad中顯示爲popOver。 – Swathi