2014-06-30 7 views
17

Ich habe in einem Projekt festgestellt, dass die Positionierung eines Popover über einem rechten Balkenknopf aus irgendeinem Grund nach rechts verschoben zu sein scheint. Ich habe versucht, stattdessen eine UIButton für die benutzerdefinierte Ansicht verwenden, dann präsentiert das Popover von dieser Schaltfläche, aber Popover scheint die ShowFromRect zu ignorieren, wenn ich es tatsächlich mit dem "zentrierten" Wert bereitstellen.UIPopover presentFromBarButton off center

Off-center popover

Der Code dahinter ist ganz einfach:

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

Nun, wenn ich mit dem internen Taste umschalten, wie erwähnt, sehe ich ein ähnliches Verhalten (Anmerkung Farbwechsel so zeigt Bild nach oben).

using internal button

Der Code dafür ist immer noch recht einfach:

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

Hinweis hier, dass stattdessen das eigentliche Zentrum der Verwendung habe ich den beliebigen Wert verwendet, 2. Wenn ich 1 verwenden oder 0, wird das Popover linksbündig. Alles Größer als Eins ist wieder richtig ausgerichtet.

left-aligned

ich um ein wenig nach einer ähnlichen Frage suchen, aber ich kann nicht scheinen, jemanden mit dem gleichen Problem zu finden. Irgendeine Idee um, was verursacht, oder wie man es vermeidet, würde sehr geschätzt werden. Das Einzige, was ich erraten habe, ist, dass Apple aufgrund seiner Nähe zum Rand etwas Voodoo positioniert, um es dahin zu zwingen, wo sie es haben wollen. Das Problem ist, dass die Schaltfläche oben rechts wie eine normale Drop-Down-Position aussieht.

Bearbeiten: Ich habe das gleiche Verhalten bei einem langen Druck auf das Symbol "Neue Nachricht" in der nativen Mail App bestätigt.

Edit 2: Ich konnte mit Apple bestätigen, dass dies ein Problem ist. In einer der neueren Versionen (ich kann mich nicht erinnern, welche, eine der 9 ich denke), sie haben es so gemacht, dass Sie dies manuell einstellen können. Das Standardverhalten ist immer noch falsch, glaube ich (ich habe das eine Weile nicht versucht), aber Sie können die CGRect-Offset-Methode verwenden, damit es richtig funktioniert, sollten Sie so geneigt sein.

+0

Versuchen Sie, diese UIBarButtonItem Taste * = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAction Ziel: Selbst Aktion: @selector (shareTap :)]; – Nishant

+1

Könnten Sie vielleicht ein bisschen mehr erklären?Durch die Verwendung eines Systemelements wird die Platzierung der Schaltfläche nicht automatisch behoben. In meiner Bearbeitung habe ich erwähnt, dass die Standard-Apps auch das Problem (Mail) aufweisen, bei dem vermutlich System-Icons verwendet werden. – shortstuffsushi

Antwort

-2

Versuchen Sie diesen benutzerdefinierten Popover-Controller - WYPopoverController (https://github.com/nicolaschengdev/WYPopoverController), um das Problem zu beheben.

+2

Ich suche keine Ersatzbibliothek für Popovers, sondern versuche nur das Verhalten eines nativen Controllers zu verstehen. Und in der Tat, der allererste Screenshot des WY-Controllers ist auch aus der Mitte :(Danke trotzdem. – shortstuffsushi

0

Hier ist ein Weg, dies zu tun: Verwenden Sie statt UIBarButtonSystemItem eine UIBarButtonItem mit einer benutzerdefinierten Ansicht. Ziehen Sie einfach eine UIButton in die UINavigationBar, um eine UIBarButtonItem mit einer eingebetteten UIButton zu erhalten, die als UIBarButtonItem 's customView angezeigt wird.

+0

Ich denke, Sie könnten feststellen, dass dies nach iOS 9 behoben ist. Ich erwähnte am Anfang meiner Post, dass sogar ein UIButton nicht funktioniert, aber später (in einer Bearbeitung), dass Apple es aktualisiert, so dass Sie * die Positionierung mit einem UIButton fixieren konnten. \ r \ n – shortstuffsushi

+0

Ich hatte das Popover-Pfeil-Offset-Problem, das Sie ursprünglich in einem Projekt auf iOS 10 beschrieben, und das war Die Lösung für mich - Ich denke, was du sagst ist, dass diese Methode nicht auf iOS 9 funktionieren würde, wo der Fehler vorhanden war. Ich habe das nicht versucht. – stevex

0

Sie müssen den Rahmen des Balkenschaltfläche angeben, aus dem der Pop-Over dargestellt werden soll.

Der folgende Code präsentiert eine UIAlertController als ein Popover von einem Bar-Button.

@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

Ich bin mir nicht ganz sicher, aber ich denke nicht Das hängt mit meiner Frage zusammen: Wie geht das mit der Pfeilplatzierung um? Mit welchem ​​"Rahmen" beziehe ich mich auf Einstellungen? Sprechen Sie darüber, diese Erweiterungsmethode für die UIBarButtonItem-Klasse hinzuzufügen? – shortstuffsushi

+0

Die Erweiterung gibt Ihnen den Rahmen des BarButtons legen wir fest Den Rahmen, aus dem der Popover präsentiert werden soll, zentriert er sich entsprechend. Ich habe ein Beispiel für einen alarmController vorgestellt, der sich als popOver im iPad präsentiert. – Swathi