割と有名な話かもしれませんが iOS 7とiOS 8以降とでUIActionSheetの挙動が違っていたためハマりました。
Xcode 7.3.1ではすでにiOS 7はサポートされておらず、手元にiOS 7デバイスがなかったのでハマったとも言えます。挙動が掴めずに最終的にiOS 7デバイスを手配することとなってしまいました。
問題の発生した状況はいたって単純で、0〜3の数字をアクションシートを表示させてユーザーに選択させるというシチュエーションでした。すでにUIActionSheetはiOS 8.3でdeprecated扱いになっていますが、互換性維持のためかiOS 9.3.2時点でも普通に動いていました。
let actionSheet = UIActionSheet(title: "タイトル", delegate: self, cancelButtonTitle: "キャンセル", destructiveButtonTitle: nil) actionSheet.addButtonWithTitle("0") actionSheet.addButtonWithTitle("1") actionSheet.addButtonWithTitle("2") actionSheet.addButtonWithTitle("3") actionSheet.showFromTabBar(tabbar)
ユーザーによって数字が選択されるとactionSheet(:clickedButtonAtIndex:)
が呼ばれ、選択されたボタンのインデックスがcancelButtonIndex
と異なっていればhogeAction
を実行するというものです。
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) { if buttonIndex != actionSheet.cancelButtonIndex { hogeAction(buttonIndex) } }
問題としては、iOS 7.1.2デバイスで「0」を選択するとhogeAction
が実行できませんでした。iOS 8.4、iOS 9.3.2ではhogeAction
は実行されていました。
ドキュメントではcancelButtonIndexについて以下のように書かれていました。
Button indices start at 0. The default value of this property is normally -1, which indicates that no cancel button has been set. However, a cancel button may be created and set automatically by the initWithTitle:delegate:cancelButtonTitle:destructiveButtonTitle:otherButtonTitles: method. If you use that method to create a cancel button, you should not change the value of this property.
「通常は-1
が割り当てられるけど、コンストラクタでキャンセルボタンを指定していると自動で割り当てられる」と書かれています*1。iOS 7の時はcancelButtonIndexは0
が初期値になっているのかもしれないので明示的にcancelButtonIndexの値を指定することにしました。
解決編
UIActionSheetのコンストラクタでcancelButtonTitle
の「キャンセル」を指定せずに、cancelButtonIndex
を明示的に指定することで意図した挙動をおこなうようにしました。
let actionSheet = UIActionSheet(title: "タイトル", delegate: self, cancelButtonTitle: nil, destructiveButtonTitle: nil) actionSheet.addButtonWithTitle("0") actionSheet.addButtonWithTitle("1") actionSheet.addButtonWithTitle("2") actionSheet.addButtonWithTitle("3") actionSheet.cancelButtonIndex = actionSheet.addButtonWithTitle("キャンセル") actionSheet.showFromTabBar(tabbar)
これでiOS 7とiOS 8以降でもきちんと動いてくれましたが、開発環境やCocoaPodsの関係でiOS 7のサポートが切れると嬉しいなと考えています。
*1:読み間違えてたら教えて欲しい!