質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

3回答

2850閲覧

Alamofire内でTabPageViewControllerを呼ぶと、一瞬表示されない

Y_M

総合スコア265

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/08/16 05:12

編集2016/08/16 06:23

###前提・実現したいこと
遷移した段階でTabPageViewControllerを表示させたい。

###発生している問題・エラーメッセージ
Alamofireの処理の中にTabPageViewControllercreate()以降の処理を記述すると
タブをスワイプするなどの動作をしないと設定したタブバーが表示されない。

★通信結果によってはじめに表示されるタブを変更したい。
★受け取ったjson["result"]の結果がnilの場合は0番めのタブを。
★受け取ったjson["result"]の結果がnilの場合は1番めのタブを。

現在の構造は
viewDidLoad
−−check()
−−−tabPageSetting()

###該当のソースコード

import UIKit import Alamofire import SwiftyJSON import TabPageViewController class ViewController: UIViewController { let server: String = "http://sample.jp" let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate override func viewDidLoad() { super.viewDidLoad() self.navigationItem.title = "テスト" self.navigationController!.interactivePopGestureRecognizer!.enabled = false check() } func tabPageSetting(setIndex: Int) { let tabPageViewController = TabPageViewController.create() let vc1 = self.storyboard?.instantiateViewControllerWithIdentifier("Tab1") as! Tab1ViewController let vc2 = self.storyboard?.instantiateViewControllerWithIdentifier("Tab2") as! Tab2ViewController let vc3 = self.storyboard?.instantiateViewControllerWithIdentifier("Tab3") as! Tab3ViewController tabPageViewController.tabItems = [(vc1, "タブ1"), (vc2, "タブ2"), (vc3, "タブ3")] tabPageViewController.displayControllerWithIndex(setIndex, direction: .Forward, animated: false) var option = TabPageOption() option.currentColor = UIColor.redColor() option.tabWidth = view.frame.width / CGFloat(tabPageViewController.tabItems.count) tabPageViewController.option = option tabPageViewController.view.frame.origin.y += (self.tabBarController?.tabBar.frame.height)! tabPageViewController.view.frame.size.height -= (self.tabBarController?.tabBar.frame.height)! self.addChildViewController(tabPageViewController) self.view.addSubview(tabPageViewController.view) tabPageViewController.didMoveToParentViewController(self) } func check() { Alamofire.request(.GET, "\(server)/api/test", headers: appDelegate.customHeader) .responseJSON { response in guard let object = response.result.value else { return } let json = JSON(object) if json["result"].int == nil { self.tabPageSetting(0) } else { self.tabPageSetting(1) } } } }

###試したこと

override func viewDidLoad() { super.viewDidLoad() self.navigationItem.title = "テスト" self.navigationController!.interactivePopGestureRecognizer!.enabled = false tabPageSetting(0) }

Alamofire内で処理をしなければ、普通に表示されます。

###補足情報(言語/FW/ツール等のバージョンなど)
Xcode7.3.1
Swift2
TabPageViewController (0.2.1)

###追記

fuzzballさん

override func viewDidLoad() { super.viewDidLoad() self.navigationItem.title = "テスト" self.navigationController!.interactivePopGestureRecognizer!.enabled = false tabPageSetting(0) check() }

これで再度実行しましたが結果は変わらずでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2016/08/16 06:00

tabPageSetting(0); check() としたらどうなりますか?
Y_M

2016/08/16 06:17 編集

あ、理解しました。少々お待ちください
fuzzball

2016/08/16 06:17

viewDidLoad()の中です。
Y_M

2016/08/16 06:21

試してみましたが、タブは表示されないです。 確認のために書いたコードを質問内容に追記しました。
fuzzball

2016/08/16 06:38 編集

viewDidLoad()の変更はそのままにして、check()の中の self.tabPageSetting(0)と self.tabPageSetting(1)をコメントアウトするとどうなりますか?
Y_M

2016/08/16 06:44

self.tabPageSetting(0)と self.tabPageSetting(1)をコメントアウトすると正常にタブの0番を表示します。(タブもきちんと表示)
fuzzball

2016/08/16 06:46

検証ありがとうございました。上記の修正は元に戻しておいて下さい。
fuzzball

2016/08/16 08:35

「タブバーが表示されない」のタブバーとは、TabPageViewControllerのでしょうか?それともUITabBarControllerのでしょうか?(スワイプと書いているのでTabPageViewControllerのような気がしますが)
Y_M

2016/08/16 08:49

混乱させてしまい申し訳ないです。TabPageViewControllerのタブになります
guest

回答3

0

自己解決

###遷移前のViewCOntroller

Swift

1import UIKit 2import Alamofire 3import SwiftyJSON 4import TabPageViewController 5 6class ExampleTableViewController: UIViewController, UITableViewDataSource { 7 8 @IBOutlet weak var tableView: UITableView! 9 10 let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 } 15 16 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 17 return 10 18 } 19 20 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 21 22 let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 23 return cell 24 } 25 26 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 27 //セルを選択した際に呼びだされ、checkを呼び出し結果を`appDelegate`の`tagIndex`に格納する 28 //その後`TabPageViewController`を実装しているViewへ遷移する 29 check { response in 30 self.appDelegate.tagIndex = response 31 let nextVC = self.storyboard?.instantiateViewControllerWithIdentifier("View2") as! ViewController2 32 self.navigationController?.pushViewController(nextVC, animated: true) 33 } 34 } 35 36 func check(apiResponse: (responseData: Int) -> ()) { 37 38 Alamofire.request(.GET, "http://sample.jp/api/test", headers: appDelegate.customHeader) 39 .responseJSON { response in 40 guard let object = response.result.value else { 41 return 42 } 43 var result: Int = 0 44 let json = JSON(object) 45 if json["result"]["member_no"].int == nil { 46 result = 0 47 } else { 48 result = 1 49 } 50 apiResponse(responseData: result) 51 } 52 53 }

###遷移後のView(TabPageViewControllerを実装するView)

Swift

1class ViewController2: UIViewController { 2 3 let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 8 self.navigationItem.title = "Page2" 9 10 let tabPageViewController = TabPageViewController.create() 11 let vc1 = UIViewController() 12 vc1.view.backgroundColor = UIColor.grayColor() 13 let vc2 = self.storyboard?.instantiateViewControllerWithIdentifier("Tab2") as! Tab2ViewController 14 let vc3 = UIViewController() 15 vc3.view.backgroundColor = UIColor.greenColor() 16 tabPageViewController.tabItems = [(vc1, "タブ1"), (vc2, "タブ2"), (vc3, "タブ3")] 17 tabPageViewController.displayControllerWithIndex(appDelegate.tagIndex!, direction: .Forward, animated: false) 18 19 var option = TabPageOption() 20 option.currentColor = UIColor.redColor() 21 option.tabWidth = self.view.frame.width / CGFloat(tabPageViewController.tabItems.count) 22 tabPageViewController.option = option 23 24 tabPageViewController.view.frame.origin.y += (self.tabBarController?.tabBar.frame.height)! 25 tabPageViewController.view.frame.size.height -= (self.tabBarController?.tabBar.frame.height)! 26 27 self.addChildViewController(tabPageViewController) 28 self.view.addSubview(tabPageViewController.view) 29 tabPageViewController.didMoveToParentViewController(self) 30 31 } 32 33}

投稿2016/08/17 05:36

Y_M

総合スコア265

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

同期すればいけそうな気がしたのですが、
カッコイイ同期の方法が見つからなかったです。

swift

1func check() { 2 3 var keepAlive = true //※追加 4 5 Alamofire.request(.GET, "\(server)/api/test", headers: appDelegate.customHeader) 6 .responseJSON { response in 7 guard let object = response.result.value else { 8 return 9 } 10 let json = JSON(object) 11 if json["result"].int == nil { 12 self.tabPageSetting(0) 13 } else { 14 self.tabPageSetting(1) 15 } 16 keepAlive = false //※追加 17 } 18 19 //sync ※追加 20 let runLoop = NSRunLoop.currentRunLoop() 21 while true 22 && keepAlive 23 && runLoop.runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeIntervalSinceNow: 0.1)) 24 {} 25}

同期に関しては下記の記事からパクりました。
Alamofireでデータ受信が終わるまで待機する方法

投稿2016/08/16 07:33

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y_M

2016/08/16 07:52

ご回答ありがとうございます。 回答いただきましたコードを取り入れて実行してみたのですが、 結果は変わらずということになっています。。。
fuzzball

2016/08/16 08:07

むむむ‥同じ環境作って試したいのですが面倒なのでこれにて終了。
Y_M

2016/08/16 08:09

ありがとうございました。
fuzzball

2016/08/16 08:54

と言いつつ、同じような環境を作ってみたのですが症状を再現できず‥。 (Alamofireのリクエスト部分以外は同じソース)
Y_M

2016/08/16 09:11

ここには書いていなかった(忘れていた)条件としては、 ・TabPageViewControllerを使ったページ①に3つタブを用意し、  それぞれにテーブルビューを配置 ・そのテーブルビューのセルの一つを選択した際に  TabPageViewControllerを使ったページ② <--- これが今回のページ  に遷移するという仕組みになっています。
fuzzball

2016/08/16 09:25

さすがにこれ以上は‥。
Y_M

2016/08/16 09:44

あ、やってくださいというわけではないです(汗 ここまでお力添えいただきありがとうございました。
fuzzball

2016/08/16 14:43

風呂に入っていて思い付いた(思い出した)のですがw、check()をviewWillAppearで呼ぶようにするとどうなるでしょうか?まずは非同期のままで、ダメなら同期させてみて下さい。
Y_M

2016/08/17 01:15

viewWillApperで呼んでも結果は変わらずでした。 やり方が間違っているのかもしれませんが同期にすると固まってしまいます。
fuzzball

2016/08/17 02:00

viewDidLoadでは固まらないのにviewWillAppearでは固まるのでしょうか? override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) check() }
Y_M

2016/08/17 02:14

認識が間違っていたかも知れません。 その書き方だと固まらずTabPageのタブも表示されません。
Y_M

2016/08/17 02:27

新しくプロジェクトを作り最低限の機能で再現してみても、 同じ結果になってしまうので、TabPageViewControllerの内部処理が原因なのかもしれないです。
Y_M

2016/08/17 02:40

_Kentarouさんの言うとおり、前のViewで情報を取得した後に 次のビューに値を引き継ぎ初期設定することで無事に意図する動きとなりました。 本番環境に実装してみて問題がなければ再度ソースを解答に記載したいと思います。 同じような環境を作って検証までして頂き、助言いただき本当にありがとうございました。
fuzzball

2016/08/17 02:48

その「最低限」のプロジェクトを丸ごと見せてもらえると検証出来るのですが、もういいですね。
guest

0

Alamofireの戻りでの呼び出しをメインスレッドにしてみるといかがでしょうか?
※そもそも通信しているので、タイミングによってはやはりそのようになるのはしょうがないと思いますが。

swift

1dispatch_async(dispatch_get_main_queue(), { 2 3 let json = JSON(object) 4 if json["result"].int == nil { 5 self.tabPageSetting(0) 6 } else { 7 self.tabPageSetting(1) 8 } 9})

投稿2016/08/16 05:21

編集2016/08/16 05:26
_Kentarou

総合スコア8490

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y_M

2016/08/16 05:26

画面が真っ白で表示されなくなってしまいました。。。
_Kentarou

2016/08/16 05:30 編集

ちょっと間違えていたのでもう一度以下でお願いします。 dispatch_async(dispatch_get_main_queue(), { })
Y_M

2016/08/16 05:35

画面は再度表示されましたが、タブバーの部分は消えたままになっています。 やはりスワイプすると表示されます。
_Kentarou

2016/08/16 05:39

違う原因ですね、確かにその現象には自分も見覚えがあったので、分かるようなら追記します。
Y_M

2016/08/16 05:42

ありがとうございます。 よろしくお願い致します。
_Kentarou

2016/08/16 07:56

自分の考えとしては、本家のサンプルも前画面で設定してから遷移しているのでその使い方が一番無難かと思いました。 気になったのですがサーバーへアクセスして取得するような条件の方です、ABテストの様な設定を変更したいということですか?そうではなくてアプリ内で判断できることであれば通信はしなくてもよいと思いました。
Y_M

2016/08/16 08:04

一つ前の画面にて複数項目の中から一つを選択し、 その選択された項目が個々にIDを持っていて、それをサーバへ投げ その項目に(例えばAというイベント)に参加しているかいないかで ・参加している場合は0番めのタブ ・参加していない場合は1番目のタブ と表示するタブを変えたいのです。 そのためアプリ単体では判断できないと思われます。 タブにこだわっている理由としてはどちらの場合も両方のページが見れるようにするためです。
_Kentarou

2016/08/16 08:23

そうでしたか、それでしたら前の画面でAPIを投げてから遷移しても同じですね。 前画面でしたらAPIの戻りでタブを選択して遷移するのが一連の流れでできるので検討してもよいかと思います。 まぁ、APIの話では無くてライブラリの使い方なので、前画面で生成するのが無難な気がします。
Y_M

2016/08/17 02:39

_Kentarouさんの言うとおり、前のViewで情報を取得した後に 次のビューに値を引き継ぎ初期設定することで無事に意図する動きとなりました。 本番環境に実装してみて問題がなければ再度ソースを解答に記載したいと思います。 長い時間の助言本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問