18865


まず、アプリの起動時に First View を表示し、First View の viewDidLoad 関数で Touch ID
の認証を行う記述をしました。

[![StoryBoard](https://i.stack.imgur.com/Q5Pj7.png)](https://i.stack.imgur.com/Q5Pj7.png)

[code]

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let context = LAContext()
        var error :NSError?
        let localizedReason = "Touch ID で保護"
    
        if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error){
    
            //Tocuh ID に対応
            context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: localizedReason, reply: {
                success, error in
    
                if success {
    
                    let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    
                    let next:UIViewController = storyboard.instantiateViewControllerWithIdentifier("Home")
                        as UIViewController
    
                    next.modalTransitionStyle = UIModalTransitionStyle.FlipHorizontal
    
                    self.presentViewController(next, animated: true, completion: nil)
    
                } else {
                    switch error!.code {
                    case LAError.AuthenticationFailed.rawValue:
                        NSLog("認証失敗")
                    case LAError.UserCancel.rawValue:
                        NSLog("キャンセル")
                    case LAError.UserFallback.rawValue:
                        NSLog("パスコードを入力を選択")
                    case LAError.PasscodeNotSet.rawValue:
                        NSLog("パスコードが設定されていない")
                    case LAError.SystemCancel.rawValue:
                        NSLog("システムによってキャンセルされた")
                    default:
                        NSLog("不明なエラー")
                        return
                    }
                }
            })
    
        } else {
            //Tocuh ID に非対応
            NSLog("Touch IDに対応してない")
        }
    
    }
    
[/code]

Touch ID での認証に成功した後、Modal の FlipHorizontal で画面遷移を行いたいのですが、  
スクリーンショットのようになってしまい、TabBarItem の icon が表示されません。

[![画像の説明をここに入力](https://i.stack.imgur.com/AgHSg.png)](https://i.stack.imgur.com/AgHSg.png)

一度、その TabBarItem をタップするか、しばらく時間が経つ(その時間は起動するたびにまちまち)と表示されるようになりますが、  
通常の画面遷移の時のように一発で表示されるようにしたいです。

遷移先は Main.Storyboard にある UITabBarController、Storyboard ID は "Home" です。

どのようにすればよいか、ご教授願います。

なお、Apple Swift version 2.1 (swiftlang-700.1.101.6 clang-700.1.76) を使用しています。


CC BY-SA 3.0
2015-11-15T08:39:25.310
18843
2015-11-16T02:17:39.433
2015-11-15T15:46:35.413
10947
10947
question
ios swift xcode
Touch ID での認証後、Modal で UITabBarController に画面遷移を行う方法


症状の再現を確認しました。ボタンのアクションメソッドで、`TabBar
Controller`に遷移するときは問題ないのに、クロージャ内で遷移すると、（未表示の）タブのアイコンが、欠けますね。  
はっきりした理由はわかりませんが、私は、クロージャ内で`UITabBarController`を生成し、遷移することに原因があると仮定し、それに沿って、プログラムを修正したところ、アイコンが欠けなくなりました。

[code]

    import UIKit
    
    class ViewController: UIViewController {
        // インスタンス変数として、TabBar Controllerを宣言
        var theTabBarController: UITabBarController!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            theTabBarController = storyboard.instantiateViewControllerWithIdentifier("Home")
                            as! UITabBarController
            theTabBarController.modalTransitionStyle = UIModalTransitionStyle.FlipHorizontal
            // この時点でTabBarControllerインスタンスはできあがっている。
    
            let context = LAContext()
            var error :NSError?
            let localizedReason = "Touch ID で保護"
    
            if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error){
    
                //Tocuh ID に対応
                context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: localizedReason, reply: {
                    success, error in
    
                    if success {
                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
                            // 認証成功したら、モーダル表示。
                            self.presentViewController(self.theTabBarController, animated: true, completion: nil)
                        })
                    } else {
                        switch error!.code {
                        case LAError.AuthenticationFailed.rawValue:
                            print("認証失敗") // NSLogじゃなく、print()を使おう。
                        case LAError.UserCancel.rawValue:
                            print("キャンセル")
                        case LAError.UserFallback.rawValue:
                            print("パスコードを入力を選択")
                        case LAError.PasscodeNotSet.rawValue:
                            print("パスコードが設定されていない")
                        case LAError.SystemCancel.rawValue:
                            print("システムによってキャンセルされた")
                        default:
                            print("不明なエラー")
                            return
                        }
                    }
                })
    
            } else {
                //Tocuh ID に非対応
                print("Touch IDに対応してない。エラーコード：\(error!.code)") // どうせならエラーコードも出力しておく。
            }
    
        }
    }
    
[/code]

いいたいことは、`TabBar Controller`をクロージャの外で生成するということです。

関係ないところで、気になった点に修正を加えていますので、余裕ができたときにご覧ください。


CC BY-SA 3.0
2015-11-16T01:41:46.667
18865
2015-11-16T02:17:39.433
2015-11-16T02:17:39.433
5519
7362
18843
answer