8

私が取り組んでいるプロジェクトでは、iOS アプリのあちこちにポップアップを表示する UIAlert ヘルパー モジュールを作成する必要がありました。ポップアップは、コード内の任意の場所で簡単に呼び出すことができるクラス関数として記述されています (クラスは静的であり、すべての関数もそうです)。

アラートを一度閉じてからもう一度開くと、そのアクションが機能しなくなるという非常に奇妙なバグに遭遇しました(アクションハンドラーが呼び出されないなど)。ただし、ポップアップが最初に表示されたときにアクションをクリックすると機能します...

このバグが発生する特定のポップアップのコードは次のとおりです (他のポップアップはまったく影響を受けません)。

static func popSkipWalkthrough() {
    let alert = UIAlertController(title: "Skip", message: "whatever", preferredStyle: .Alert)

    alert.addAction(cancelAction)
    alert.addAction(skipWalkthroughAction)
    appDelegate.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)
}

は次のskipWalkthroughActionように定義されます。

static let skipWalkthroughAction = UIAlertAction(title: "Continue", style: .Default, handler: { (action: UIAlertAction!) -> Void in
    appDelegate.setWindowViewTo("NavCtrl", navigateTo: false)
    CallIn.Settings.didWalkthrough = true
})

は次のcancelActionように定義されます。

static let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)

特にこのポップアップは、ウォークスルーの最後のステップで「スキップ」ボタンを押すたびに表示されます...

この動作の原因についていくつかのリードを試してみましたが、実際には割り当てが解除されていないポップアップと関係があるのではないかと思いますが、現時点ではまったくわかりません...

何か案は ?

4

1 に答える 1

5

この再利用可能な部分のコーディング方法に問題がありますが、この問題は にcopy:メッセージを送信することで解決できますskipWalkthroughAction。単に行う:

static func popSkipWalkthrough() {
    let alert = UIAlertController(title: "Skip", message: "whatever", preferredStyle: .Alert)

    alert.addAction(cancelAction.copy() as! UIAlertAction)
    alert.addAction(skipWalkthroughAction.copy() as! UIAlertAction)
    appDelegate.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)
}

これで解決するはずです。

alertをインスタンス レベルに移動することで、これを解決することもできます。その場合、送信する必要はありませんcopy:

より良いアプローチ

の「本当に」再利用可能なエクスペリエンスが必要な場合は、拡張機能UIAlertControllerを作成することをお勧めします。UIViewController私は自分のプロジェクトの1つにこれを持っています:

extension UIViewController {
    func showAlertControllerWithTitle(title:String?,message:String?,actions:[UIAlertAction],dismissingActionTitle:String?, dismissBlock:(() -> ())?) -> UIAlertController {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        if dismissingActionTitle != nil {
            let okAction = UIAlertAction(title: dismissingActionTitle, style: .Default) { (action) -> Void in
                dismissBlock?()
                alertController.dismissViewControllerAnimated(true, completion:nil)
            }
            alertController.addAction(okAction)
        }
        for action in actions {
            alertController.addAction(action)
        }
        self.presentViewController(alertController, animated: true, completion:nil)
        return alertController
    }
}
于 2016-02-09T12:15:46.410 に答える