2014-06-30 23 views
17

Bir projede, sağdaki bir bar düğmesi üzerindeki bir popover'ın konumlandırmasının bir nedenden dolayı sağda olduğu anlaşılıyor. Özel görünüm için bir UIButton kullanarak denedim, daha sonra bu düğmeden popover'ı sunmayı denedim, ancak aslında 'ortalanmış' değerle sağladığımda pop-up showFromRect'i göz ardı ediyor gibi görünüyor.UIPopover presentFromBarButton merkezi

Off-center popover

Bunun arkasındaki kod oldukça basittir: Ben de belirtildiği gibi, iç düğmesini kullanarak geçerseniz,

- (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]; 
} 

Şimdi, benzer bir davranışla (not renk değişimi böylece görüntü gösterir).

using internal button

bu kodu hala oldukça basittir: Ben 1 kullanırsanız

- (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]; 
} 

burada Not yerine gerçek merkezini kullanarak, ben keyfi değerini, 2. kullandım veya 0, popover sola hizalanmış olur. Birden fazla olan herhangi bir şey tekrar hizalanmış.

left-aligned

Ben benzer bir soruya arayan biraz etrafına aradım ama aynı sorunla kimseyi bulmak için görünmüyor olabilir. Bunun neden olduğu ya da bundan nasıl kaçınılacağı ile ilgili herhangi bir fikir büyük ölçüde takdir edilecektir. Tahmin edemediğim tek şey, kenara yakınlığı nedeniyle Apple'ın istediği yerde zorlamak için bazı konumlandırma vudularını yapmasıdır. Sorun, sağ üst köşedeki düğmenin oldukça standart bir açılır menü gibi görünmesidir.

Düzenleme: Bu davranışın, yerel Posta uygulamasında "Yeni İleti" simgesine uzun basışla gerçekleştiğini doğruladım.

Düzenleme 2: Apple ile bunun bir sorun olduğunu onayladım. Daha yeni versiyonlardan birinde (hangisini hatırlıyorum, 9'lardan birini düşünüyorum), bunu manuel olarak ayarlayabilmeniz için yaptılar. Varsayılan davranış hala yanlıştır (bunu bir süredir denemedim), ancak doğru bir şekilde çalışabilmeniz için CGRect ofset yöntemini kullanabilirsiniz, bu nedenle eğimli olmalısınız.

+0

bu UIBarButtonItem * düğmesine deneyin = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAction hedef: self eylemi: @selector (ShareTap :)]; – Nishant

+1

Belki biraz daha açıklayabilir misiniz?Bir sistem öğesinin kullanılması, düğme yerleşimini kendi başına düzeltmez ve düzenlememde varsayılan uygulamaların, muhtemelen sistem simgelerini kullanan sorunu da (Mail) gösterdiğinden bahsetmiştim. – shortstuffsushi

cevap

-2

Sorunu düzeltmek için bu özel Popover Denetleyicisi - WYPopoverController (https://github.com/nicolaschengdev/WYPopoverController) 'u deneyin.

+2

Pop'lular için bir yedek kütüphane aramıyorum, sadece yerel bir denetleyicinin davranışını anlamaya çalışıyorum. Ve aslında, WY denetleyicisinin ilk ekran görüntüsü de merkez dışıdır :(Yine de teşekkürler. – shortstuffsushi

0

Bunu yapmanın bir yolu: UIBarButtonSystemItem kullanmak yerine, özel bir görünümle UIBarButtonItem kullanın. Sadece UIButton'u UIBarButtonItem'a UIBarButtonItem'a sahip olmak için UIButton'a sürükleyin ve UIBarButtonItem'un özel Görünümü olarak görünen gömülü bir UIButton ile.

@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

Bu durumun, iOS 9'un düzeltilmiş bir ileti olduğunu fark edebilirsiniz. Yazımın başlangıcında bir UIButton bile belirttim işe yaramadı, ancak daha sonra (bir düzenleme) Apple'ın güncellediğinden, bir UIButton kullanarak konumlandırmayı * düzeltebilirsiniz. – shortstuffsushi

+0

Orijinal olarak iOS 10'daki bir projede anlattığınız bir ok offset sorunu yaşadım ve bu Benim için düzeltme - Sanırım, bu yöntemin, hatanın mevcut olduğu iOS 9'da işe yaramayacağını tahmin ediyorum. Bunu denemedim. – stevex

0

Sen ihtiyaçları üzerinde pop sunulmak üzere hangi bar düğmesinin çerçevesini belirtmelisiniz.

Aşağıdaki kod, bir bar düğmesinden pop-up olarak bir UIAlertController sunar.

@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

Tamamen emin değilim, ama sanmıyorum Bu benim sorduğum soru ile ilgili: Ok yerleşimini nasıl ele alıyorsunuz? Hangi "çerçeve" ayarına atıfta bulunuyorsunuz? UIBarButtonItem sınıfında bu uzantı yöntemini ekleme hakkında mı konuşuyorsunuz? – shortstuffsushi

+0

Uzantı size barButton'un çerçevesini verir. ayarladık Popover'in sunulması gereken çerçeve, kendisini buna göre merkezler. IPad'de popOver olarak sunulan bir alertController örneği verdim. – Swathi