UIActionSheet Abbrechen Schaltfläche seltsames Verhalten

116

Ich habe ein UIBarButtonItem, das ein Aktionsblatt öffnet, um Benutzern Auswahlmöglichkeiten zu bieten. Alles funktioniert wie erwartet, es sei denn, ich versuche auf die Schaltfläche "Abbrechen" zu klicken. Das Ziel der Schaltfläche scheint sich von der Stelle nach oben bewegt zu haben, an der es sein sollte. Ich kann es nur aktivieren, indem ich irgendwo in der Mitte der Schaltflächen "Abbrechen" und "OK" klicke.

Ich habe Aktionsblätter in anderen Anwendungen ausprobiert und sie funktionieren einwandfrei, es ist also nicht nur mein großer Daumen. Das Aktionsblatt wird in einem UIViewController geöffnet

- (void)showOpenOptions
{
    UIActionSheet *sheet = [[UIActionSheet alloc] 
    initWithTitle:NSLocalizedString(@"Open link in external application?", @"Open in external application")
    delegate:self
    cancelButtonTitle:NSLocalizedString(@"Cancel", @"Cancel")
    destructiveButtonTitle:NSLocalizedString(@"Open Link", @"Open Link")
    otherButtonTitles:nil];

    [sheet showInView:self.view];
    [sheet release];
}
Nevan König
quelle
5
In einem anderen Zusammenhang wurde mir auf der WWDC während einer Apple UI-Überprüfungssitzung mitgeteilt, dass der rote Knopf auf den Aktionsblättern wirklich für "destruktive" Aktionen (dh "Löschen") gedacht ist.
Ramin
Ja, ich habe kürzlich die Richtlinien für Benutzeroberflächen gelesen und das gesehen. Änderte es von rot nach grau.
Nevan King

Antworten:

190

Verwenden Sie die showFromTabBar:Methode von, anstatt die Ansicht des aktuellen Ansichtscontrollers an das Aktionsblatt zu übergeben UIActionSheet.

Der richtige Weg
Dies ergibt den richtigen tippbaren Bereich:

[actionSheet showFromTabBar:self.tabBarController.tabBar];

Der falsche Weg
Dadurch wird der tippbare Bereich an der falschen Stelle platziert (wenn Sie eine Registerkarten- oder Symbolleiste verwenden):

[actionSheet showInView:self.view];

Wenn Sie eine Symbolleiste verwenden , verwenden Sie showFromToolbar:stattdessen die Methode. Sie benötigen einen Verweis auf die Symbolleiste, höchstwahrscheinlich einen Ivar

[actionSheet showFromToolbar:self.myToolbar];

Meine alte Antwort funktioniert auch, ist aber hacky:

Habe gerade eine mögliche Antwort gefunden:

01.12.2008 22:22 Tom Saxton: Ich habe mir diesen Fehler noch einmal angesehen und es scheint ein Problem mit der Registerkartenleiste zu sein.

Wenn Sie UIActionSheets [sheet showInView: self.view] von einem Ansichtscontroller aus aufrufen, der einem UITabViewController untergeordnet ist, schlägt der Treffer-Test auf der Schaltfläche Abbrechen in dem Teil des UIActionSheets fehl, der über der Ansicht der Registerkartenleiste liegt.

Wenn Sie stattdessen die Ansicht des UITabBarControllers übergeben, verhält sich das UIActionSheet wie erwartet.

HINWEIS: In iPhone OS 2.1 und früheren Versionen wurde das UIActionSheet beim Übergeben der untergeordneten Ansicht oben in der Registerkartenleiste angezeigt. In 2.2 wird es jedoch unten in der Registerkartenleiste angezeigt und deckt somit die Registerkartenansicht ab.

http://openradar.appspot.com/6410780

Bearbeiten: Es funktioniert korrekt, wenn ich die Ansicht in die Ansicht der Registerkartenleiste ändere

[sheet showInView:self.parentViewController.tabBarController.view];
Nevan König
quelle
Upvoted dies, weil es funktioniert. Warum ist das besser als die anderen Antworten?
Bentford
1
Warum der parentViewController? Auch wenn sich die Ansicht in einer Navigationsansicht befindet, sollte tabBarController immer noch auf die richtige Stelle zeigen. Funktioniert bei mir auf jeden Fall ohne den parentViewController.
Nathan
11
Eine andere Antwort scheint möglicherweise besser zu sein. Suchen Sie nach [actionSheet showInView: [self.view window]]. Scheint direkter und allgemeiner.
Kevin
Vielen Dank für die Veröffentlichung dieser Antwort.
Fulvio
1
Ich habe keine Registerkartenleiste in meiner App, habe aber immer noch ein solches Problem. Ich habe es mit '[serf.view window]' gelöst. Es ist sowieso kein Problem mit der Registerkartenleiste.
Mike Keskinov
37

Ich habe hier eine Antwort gefunden , die funktioniert.

mit : [filterActionSheet showInView:[self.view window]];

Ich habe ein paar Möglichkeiten ausprobiert, um zu meiner Registerkartenleiste zu gelangen, und die Art und Weise, wie diese App eingerichtet ist, scheint kompliziert zu sein ...

driveguy
quelle
PERFEKT! Vielen Dank. Dies ist die richtige Lösung für mich, da ich dieses Problem mit einem UITableViewController hatte, dessen Symbolleiste keine TabBar wie andere hier hatte.
William Denniss
gute Sachen, das hat bei mir funktioniert! Dies ist definitiv der einfachste Weg, dies zu tun!
cgossain
2
Es verursacht ein anderes Problem. ActionSheet wird im Hochformat angezeigt, wenn sich das Gerät im Querformat befindet (sowie alle anderen Inhalte).
Mike Keskinov
22

Verwenden Sie stattdessen:

[sheet showFromTabBar:theTabBar];
Corey Floyd
quelle
1
Ich habe das von showInTabBar:bis korrigiert showFromTabBar:. Beachten Sie auch, dass es eine 'showFromToolbar:' - Methode gibt, je nachdem, welche Bildschirmmöbel Sie am unteren Bildschirmrand haben. Ich denke, dies ist eine bessere Antwort als die akzeptierte Antwort.
Stephen Darlington
Stephen, neugierig, warum Sie denken, dass dies besser ist, als showInView: theTabBar anzugeben? Aus Sicht der Kopplung würde ich denken, dass showInView wahrscheinlich idealer wäre, falls die TabBar später gelöscht und beispielsweise durch eine Symbolleiste ersetzt wird. Der jeweilige Sub-View-Controller sollte es eigentlich nicht wissen oder sich darum kümmern müssen, würde ich denken.
Billy Gray
Wenn die Registerkartenleiste später gelöscht wird, müssen Sie diese Codezeile unabhängig davon bearbeiten (es sei denn, die TabBar ist möglicherweise ein schlecht benannter Verweis auf eine übergebene Ansicht). Ich sehe also nicht, wie diese Methode besser gekoppelt ist als showInView: theTabBar. Ich benutze showFromTabBar: auch, da es mir sicherer erscheint. Ich weiß nicht, was unter der Decke vor sich geht, aber ich stelle mir vor, dass showFromTabBar: in zukünftigen Betriebssystemversionen weniger wahrscheinlich kaputt geht als showFromView: mit einer Registerkartenansicht.
Christopher Pickslay
10

Hier ist das Update. Versuchen Sie Folgendes:

[actionsheet showInView:[UIApplication sharedApplication].keyWindow];
Viggnesh
quelle
5

Ich denke, eine Kombination aus drei der Antworten ist der richtige Weg, um damit umzugehen:

    [actionSheet showFromTabBar:self.tabBarController.tabBar];

Verwenden Sie also showFromTabBar (deshalb gibt es ihn), und Sie benötigen den parentViewController nicht, wie Nathan betont hat (tatsächlich gibt self.parentViewController.tabBarController.tabBar für mich null zurück.

RawMean
quelle
Natürlich gibt es nil zurück, da der übergeordnete Ansichtscontroller (der UITabBarViewController) nicht in einen anderen UITabBarController verschachtelt ist, sodass seine tabBarController-Eigenschaft nil ist.
Dominik Seibold
1

Zu Ihrer Information - hatte das gleiche Problem mit dem Aktionsblatt von UIDocumentInteractionController, das auf die Registerkartenleiste trat. Zum Beheben wurde Folgendes verwendet.

UIViewController *parentView = [[self parentViewController] parentViewController];
[docController presentOptionsMenuFromRect: rect inView: parentView.view animated:YES];
Mickey
quelle
-2

Schreiben Sie einfachen Code

 actionSheet.actionSheetStyle = UIActionSheetStyleDefault;

das funktioniert gut

Jayesh Kavathiya
quelle