UIActionSheetキャンセルボタンの奇妙な動作


116

アクションシートを開くUIBarButtonItemを使用して、ユーザーに何をするかを選択できるようにしています。「キャンセル」ボタンをクリックしない限り、すべてが期待どおりに機能します。ボタンのターゲットが本来あるべき場所から上に移動したように見えます。「キャンセル」と「OK」ボタンの真ん中のどこかをクリックすることによってのみそれをアクティブにすることができます。

私は他のアプリケーションでアクションシートを試してみましたが、それらは問題なく動作するため、私の親指ではありません。アクションシートがUIViewControllerで開いています

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

5
無関係なメモとして、Apple UIレビューセッション中にWWDCで、アクションシートの赤いボタンは「破壊的な」アクション(つまり「削除」)を意図していると言われました。
ラミン

ええ、私は最近ヒューマンインターフェイスガイドラインを読んで、それを見ました。赤から灰色に変更しました。
ネヴァンキング

回答:


190

現在のビューコントローラーのビューをアクションシートに渡す代わりに、のshowFromTabBar:メソッドを使用しUIActionSheetます。

正しい方法
これにより、正しいタップ可能な領域が得られます。

[actionSheet showFromTabBar:self.tabBarController.tabBar];

間違った方法
これにより、タップ可能な領域が間違った場所に配置されます(タブバーまたはツールバーを使用している場合)。

[actionSheet showInView:self.view];

ツールバーを使用している場合は、showFromToolbar:代わりにメソッドを使用してください。ツールバーへの参照が必要です。おそらくivar

[actionSheet showFromToolbar:self.myToolbar];

私の古い答えも動作しますが、ハックです:

可能な答えを見つけました:

01-Dec-2008 10:22 PM Tom Saxton:私はこのバグをもう少し見ました、そしてそれはタブバーの問題のようです。

UITabViewControllerの子であるビューコントローラーからUIActionSheetの[シートshowInView:self.view]を呼び出すと、キャンセルボタンのヒットテストは、タブバーのビューの上にあるUIActionSheetのその部分で失敗します。

代わりにUITabBarControllerのビューを渡すと、UIActionSheetは期待どおりに動作します。

注:iPhone OS 2.1以前では、UIActionSheetは子ビューを渡すときにタブバーの上部から表示されていましたが、2.2ではタブバーの下部から表示されるため、タブビューを覆っています。

http://openradar.appspot.com/6410780

編集:ビューをタブバーのビューに変更すると、正しく機能します

[sheet showInView:self.parentViewController.tabBarController.view];

動作するため、これに賛成しました。なぜこれが他の答えよりも優れているのですか?
ベントフォード2009

1
なぜparentViewControllerなのですか?ビューがnavigationviewにある場合でも、tabBarControllerは正しい場所を指す必要があります。いずれの場合も、parentViewControllerがなくても機能します。
Nathan

11
別の答えは潜在的に良いようです。[actionSheet showInView:[self.view window]]を探します。より単純で一般的なようです。
ケビン

この回答を投稿していただき、ありがとうございます。
fulvio 2010年

1
アプリにタブバーはありませんが、まだそのような問題があります。「[serf.view window]」で解決しました。とにかくタブバーの問題ではありません。
マイクケスキノフ

37

私はここでうまくいく答えを見つけました。

使用:[filterActionSheet showInView:[self.view window]];

タブバーにアクセスするためにいくつかの方法を試しましたが、このアプリが設定されているため、複雑に見えます...


パーフェクト!ありがとう。これは私にとって正しい解決策です。ここにあるような他のTabBar ではなく、ツールバーを持つUITableViewControllerでこの問題が発生していたからです。
ウィリアムデニス

これは私にとってうまくいきました!これが間違いなく最も簡単な方法です。
cgossain

2
それは別の問題を引き起こします。デバイスが横向きの場合、ActionSheetは縦向きで表示されます(他のすべてのコンテンツと同様)。
マイク・ケスキノフ

22

代わりに:

[sheet showFromTabBar:theTabBar];

1
これをからに修正しshowInTabBar:ましたshowFromTabBar:。また、画面の下部にある画面の家具に応じて、「showFromToolbar:」メソッドがあることに注意してください。これは、受け入れられた答えよりも良い答えだと思います。
スティーブンダーリントン

ステファン、なぜこれがshowInView:theTabBarを指定するよりも優れているとお考えですか?カップリングの観点から、後でtabBarがドロップされた場合、たとえばツールバーに置き換えられた場合、showInViewがおそらくより理想的だと思います。特定のサブビューコントローラーは、実際に知ったり気にしたりする必要はないはずだと思います。
Billy Grey、

タブバーが後でドロップされた場合は、そのコード行を編集する必要があります(おそらく、TabBarが渡されたビューへの不適切な名前の参照でない限り)。したがって、このメソッドがshowInView:theTabBarよりもどのように結合されているかはわかりません。私はshowFromTabBar:も使用しています。カバーの下で何が起こっているのかはわかりませんが、showFromTabBar:は、タブバービューを備えたshowFromView:よりも将来のOSリリースで機能しなくなると思います。
Christopher Pickslay 2010年

10

これが修正です。これを試してください:

[actionsheet showInView:[UIApplication sharedApplication].keyWindow];

5

3つの答えの組み合わせがこれを処理する正しい方法だと思います。

    [actionSheet showFromTabBar:self.tabBarController.tabBar];

つまり、showFromTabBarを使用します(それが存在する理由です)。Nathanが指摘したように、parentViewControllerは必要ありません(実際には、self.parentViewController.tabBarController.tabBarはnilを返します。


もちろん、nilを返します。これは、親のビューコントローラー(UITabBarViewController)が別のUITabBarControllerにネストされていないため、そのtabBarController-propertyがnilであるためです。
Dominik Seibold

1

参考までに-UIDocumentInteractionControllerのアクションシートでタブバーを踏んで同じ問題がありました。以下を使用して修正しました。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.