[解決済み] presentViewController:animated:YES ビューはユーザーが再度タップするまで表示されない。
質問
私は
presentViewController:animated:completion
. 私が作っているものは、基本的に推測ゲームです。
を持っています。
UIViewController
(frequencyViewController) を含む
UITableView
(frequencyTableView)を作成します。ユーザーが正解を含むquestionTableViewの行をタップすると、ビュー(correctViewController)がインスタンス化され、そのビューはモーダルビューとして、画面の下からスライドアップする必要があります。これはユーザーに正しい答えがあることを伝え、次の質問に備えて後ろのfrequencyViewControllerをリセットします。correctViewControllerは、次の質問を表示するためにボタンが押されると解除されます。
これはすべて毎回正しく動作し、correctViewControllerのビューは、以下のように即座に表示されます。
presentViewController:animated:completion
がある限り、正しいビューが即座に表示されます。
animated:NO
.
もし私が
animated:YES
を設定すると、correctViewController が初期化され、その中で
viewDidLoad
. しかし
viewWillAppear
,
viewDidAppear
からの補完ブロック、および
presentViewController:animated:completion
からの完了ブロックは呼び出されません。2回目のタップをするまで、アプリはまだfrequencyViewControllerを表示したままになっています。ここで、viewWillAppear、viewDidAppear、および完了ブロックが呼び出されます。
もう少し調べてみたところ、もう1回タップするだけでは続かないようです。iPhone を傾けたり振ったりすると、viewWillLoad などのトリガーが発生することがあるようです。まるで、他のユーザーからの入力を待っているようです。これは実際の iPhone とシミュレータで発生し、私はシミュレータに振るコマンドを送信することで証明しました。
どうしたらいいのか、本当に困っています...。どなたか助けていただけると本当にありがたいです。
ありがとうございます。
これが私のコードです。かなりシンプルですが...
これはquestionViewControllerのコードで、questionTableViewへのデリゲートとして動作しています。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row != [self.frequencyModel currentFrequencyIndex])
{
// If guess was wrong, then mark the selection as incorrect
NSLog(@"Incorrect Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
UITableViewCell *cell = [self.frequencyTableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor colorWithRed:240/255.0f green:110/255.0f blue:103/255.0f alpha:1.0f]];
}
else
{
// If guess was correct, show correct view
NSLog(@"Correct Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
self.correctViewController = [[HFBCorrectViewController alloc] init];
self.correctViewController.delegate = self;
[self presentViewController:self.correctViewController animated:YES completion:^(void){
NSLog(@"Completed Presenting correctViewController");
[self setUpViewForNextQuestion];
}];
}
}
これがcorrectViewControllerの全体像です。
@implementation HFBCorrectViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
NSLog(@"[HFBCorrectViewController initWithNibName:bundle:]");
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"[HFBCorrectViewController viewDidLoad]");
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"[HFBCorrectViewController viewDidAppear]");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)close:(id)sender
{
NSLog(@"[HFBCorrectViewController close:sender:]");
[self.delegate didDismissCorrectViewController];
}
@end
編集します。
以前、こんな質問を見つけました。 UITableViewとpresentViewControllerは、表示するために2クリックを取る
そして、もし私が
didSelectRow
のコードをこのように変更すると、アニメーションが非常に高速に動作します... しかし、それは厄介で、なぜそれが最初に動作しないかについて意味をなさない。だから、私はそれを答えとしてカウントしません...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row != [self.frequencyModel currentFrequencyIndex])
{
// If guess was wrong, then mark the selection as incorrect
NSLog(@"Incorrect Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
UITableViewCell *cell = [self.frequencyTableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor colorWithRed:240/255.0f green:110/255.0f blue:103/255.0f alpha:1.0f]];
// [cell setAccessoryType:(UITableViewCellAccessoryType)]
}
else
{
// If guess was correct, show correct view
NSLog(@"Correct Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
////////////////////////////
// BELOW HERE ARE THE CHANGES
[self performSelector:@selector(showCorrectViewController:) withObject:nil afterDelay:0];
}
}
-(void)showCorrectViewController:(id)sender
{
self.correctViewController = [[HFBCorrectViewController alloc] init];
self.correctViewController.delegate = self;
self.correctViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:self.correctViewController animated:YES completion:^(void){
NSLog(@"Completed Presenting correctViewController");
[self setUpViewForNextQuestion];
}];
}
どのように解決するのですか?
私も今日、同じ問題に遭遇しました。トピックを掘り下げてみたところ、メインのランループがスリープしていることに関係しているようです。
実際、これは非常に微妙なバグで、コード内にわずかなフィードバックアニメーションやタイマーなどがある場合、ランループはこれらのソースによって生かされているため、この問題は表面化しないのです。私は、この問題を
UITableViewCell
で、その
selectionStyle
に設定されている
UITableViewCellSelectionStyleNone
と設定することで、行選択ハンドラが実行された後、選択アニメーションがランループをトリガーしないようにしました。
これを修正するために (Apple が何かをするまで)、いくつかの手段でメインのランループをトリガーすることができます。
最も負担の少ない解決策は
CFRunLoopWakeUp
:
[self presentViewController:vc animated:YES completion:nil];
CFRunLoopWakeUp(CFRunLoopGetCurrent());
あるいは、メインキューに空のブロックをエンキューすることもできます。
[self presentViewController:vc animated:YES completion:nil];
dispatch_async(dispatch_get_main_queue(), ^{});
面白いことに、デバイスを振るとメインループも起動します(モーションイベントを処理する必要があります)。タップについても同じことが言えますが、これは元の質問に含まれています :) また、システムがステータスバーを更新した場合(例えば、時計の更新、WiFi信号強度の変更など)にも、メインループが起動し、ビューコントローラーが表示されます。
興味のある方のために、私はランループの仮説を検証するために、この問題の最小限のデモ プロジェクトを書きました。 https://github.com/tzahola/present-bug
Apple にもバグを報告しました。
関連
-
[解決済み] このアクションは完了できませんでした。再試行 (-22421)
-
[解決済み] カスタムオブジェクトを含むNSMutableArrayをソートするにはどうすればよいですか?
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] Objective-Cで文字列が空かどうかをテストするにはどうすればよいですか?
-
[解決済み] iOS 8 UITableViewのセパレータインセット0が機能しない件
-
[解決済み] Xcode 6のバグ:Interface Builderファイル内の不明なクラス
-
[解決済み] Objective-CでNSNotificationCenterを通してメッセージを送受信する?
-
[解決済み] Unwind segueは何に使うのか、どう使うのか?
-
[解決済み] UILabelで複数行のテキストを表示する
-
[解決済み] UITextFieldのテキストインセット?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] iOSのステータスバーの文字色を変更する方法
-
[解決済み] 制約条件の変更をアニメーションで表現するには?
-
[解決済み] 文字列の長さを取得する
-
[解決済み] UITableViewの下にある余分なセパレータをなくす
-
[解決済み] UIViewController のビューが表示されているかどうかを確認する方法
-
[解決済み] テキストフィールドを移動する方法(次へボタン/完了ボタン)
-
[解決済み] iOSとWatchKitで画像のtintColorを変更する方法
-
[解決済み] iPadマルチタスクのサポートには、これらの方向が必要です。
-
[解決済み] ファイルはユニバーサル(3スライス)ですが、iOSの静的ライブラリのための(n)ARMv7-sスライスエラーが含まれていない、どうにかして回避するには?
-
[解決済み] Cocoapods警告 - CocoaPodsがプロジェクトの基本構成を設定しなかった理由は、プロジェクトに既にカスタム構成が設定されているためです。