最新のiOS 8.3リリースでは、アプリの動作がおかしくなっています。
テキストフィールドの編集が終了したら、ユーザーはUIAlertView
を表示する閉じるボタンをクリックできます。ユーザーがalertviewでdiscardをクリックすると、alertviewと現在のビューが閉じられます。しかし、どういうわけか、ビューが消えた後にキーボードが表示され、ユーザーにとって非常に迷惑です。
デバッグ後、ビューを閉じる前にユーザーがアクセスした最後のテキストフィールドにキーボードが表示されているようです。多くの場所で現在のビューのendEditing
にさまざまな方法を試しました(UIAlertView
のボタンをクリックした後、UIAlertView
を表示する前に、別のUI要素にフォーカスを設定しました。ビューの)。問題は解決しませんでした。
しかし、この特定の問題については、それが一般的な問題なのか、修正が必要なものなのかわかりません。 iOS 8.3より前のすべては完全に機能します。
UIAlertView
はiOS 8で廃止されることを理解しています。UIAlertController
への移行を開始します。しかし、回避策があれば、ぜひ聞いてみてください。
コードスニペットを次に示します。
- (IBAction)closeTapped:(UIButton *)sender
{
// try to resign first responder
// [self.tfName resignFirstResponder];
// [self.tfPosition resignFirstResponder];
[self.view endEditing:YES];
if(self.orderDetails.isOpen && self.orderItemChanged)
{
UIAlertView* saveAlert = [[UIAlertView alloc] initWithTitle:@"Unsaved Changes"
message:@"Your changes have not been saved. Discard changes?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Save", @"Discard", nil];
[saveAlert show];
}
else
{
[self close];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch(buttonIndex)
{
case 1: // Save
{
[self save];
break;
}
case 2: // Discard
{
[self close];
break;
}
}
}
- (void)close
{
[self.delegate dismissEditOrderItemVC];
}
展開ターゲットがiOS 8以降の場合、UIAlertController
を試してください。
UIAlertView
の簡単な修正:テキストフィールドまたはテキストビューが最初のレスポンダーを辞任したときにアラートビューを表示する呼び出しを遅らせます。
[self performSelector:@selector(showAlertView) withObject:nil afterDelay:0.6];
誰かがこれに苦労しているなら、これが役立つことを願っています:
if (NSClassFromString(@"UIAlertController")) {
UIAlertController* alert = ...
}
else {
UIAlertView* alert = ...
}
iOS 8.3のアラートを変更する必要があります
最初にこれをあなたの見解に入れてください
#define IS_IOS8 [[UIDevice currentDevice].systemVersion floatValue] >= 8.0
それから
if (IS_IOS8) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Unsaved Changes" message:@"Your changes have not been saved. Discard changes?" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *saveAction = [UIAlertAction
actionWithTitle:@"Save"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
[self save];
}];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
[alertVC dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction *discardAction = [UIAlertAction
actionWithTitle:@"Discard"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
[alertVC dismissViewControllerAnimated:YES completion:nil];
}];
[alertVC addAction:saveAction];
[alertVC addAction:cancelAction];
[alertVC addAction:discardAction];
[self.view.window.rootViewController presentViewController:alertVC animated:YES completion:nil];
同じ問題で私を助けてくれるので、これはあなたを助けます。上記のコードはiOS 7と8の両方と互換性があります
私も、UIAlertControllerを閉じた後にキーボードが(最後に使用したtextViewにカーソルを置いて)ポップアップしました。これは非常に簡単な修正です。
UIAlertControllerを作成して表示する直前に、
[_activeTextView resignFirstResponder]を使用します。キーボードが再表示されます。 [self.view endEditing:YES]を使用します。キーボードは再表示されません。
これがあなたのお役に立てば幸いです。
テキストフィールドが最初のレスポンダーである場合、アラートが消えるとキーボードが自動的にポップアップします。最初のレスポンダーが適切に解雇されることを確認します:
[textField resignFirstResponder]
要確認:テーブルまたはスクロールビューでは、レスポンダーを適切に閉じるためにフィールドが画面上に表示されている必要がある場合があります。
アクティブな最初のレスポンダーがいない場合、アラートが消えてもキーボードは表示されません。
この質問の特定のケースでは、デリゲートメソッドを設定して「完了」ボタンをリッスンし、デリゲートコールバックで最初のレスポンダーを辞任することをお勧めします。
または、編集を開始するときに、現在アクティブなテキストフィールドへの参照を保存し、「clickedButtonAtIndex」メソッドでアクティブなテキストフィールドがまだアクティブである場合、それを辞任することができます。
以下のコードを使用してみてください。 iOS 8以前のバージョンでは正常に動作します
if (IS_OS_8_OR_LATER) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
TextFieldキーボードとalertViewsの奇妙な振る舞いにも気づきました... disableKeyboardというboolを作成し、次のように使用するかもしれません。
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (disableKeyBoard) {
disableKeyboard = NO;
return NO;
} else {
return YES;
}
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
disableKeyboard = YES;
}
これは単なる回避策であり、コアの問題に対処するものではありません。このメソッドを機能させるには、ヘッダーにalertViewおよびtextFieldデリゲートメソッドを設定する必要があります。