起動されるメイン画面(ログイン画面)に3つのテキストフィールドとフィールドの下に「ログイン」ボタンがあるiOSアプリケーションがあります。フィールドとボタンを保持するメイン ビュー内にコンテンツ ビューがあり、垂直方向の中央に配置されます。3 つのフィールドのいずれかが編集を開始すると、ビューが上に移動してそれらが表示されるようになり、ボタンも表示されます。これに関連するコードは次のとおりです。
(void)viewDidLoad {
[super viewDidLoad];
[userName addTarget: self action: @selector(slideFrameUp:) forControlEvents: UIControlEventEditingDidBegin];
[userName addTarget: self action: @selector(slideFrameDown:) forControlEvents: UIControlEventEditingDidEnd];
//.... same thing for 2 other fields
}
-(void) slideFrameUp: (id)sender {
CGFloat slidePoints = 116.0;
[self slideFrame: YES distance: slidePoints];
}
-(void) slideFrameDown: (id)sender {
CGFloat slidePoints = 116.0;
[self slideFrame: NO distance: slidePoints];
}
-(void) slideFrame:(BOOL) up distance: (NSInteger)amount {
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -amount : amount);
[UIView beginAnimations: nil context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
これはうまく機能し、必要なことを行います。1 つの問題は、ユーザーがテキスト フィールドを編集しているときにホーム ボタンを押してアプリを再度開いたときに、アプリが再び開いたときに (アプリがバックグラウンドに移行しただけで強制終了されていない場合)、アプリが正確にどのように配置されるかということです。以前は最初は (1/10 秒程度) だったのですが、キーボードがまだ存在する状態で中央にリセットされるため、本来よりも画面上の位置が低くなり、いくつかのフィールドが非表示になります。ビューの位置がリセットされると、私のコードは実行されません。アプリがバックグラウンドに入ったとき、またはアクティブに戻ったときに、slideFrame はまったく呼び出されません。ビュー関連のメソッド (viewDidLoad/viewDidAppear/viewWillAppear/viewWillDisappear など) は、バックグラウンドまたはアクティブに入ると呼び出されません。私'
私はあまり好きではない解決策を見つけました。私がしたことは、UIApplicationDidEnterBackgroundNotification を観察し、コードを使用してキーボードを閉じることでした。
[self.view endEditing: YES];
アプリが開いたときにユーザーがフィールドに集中していない場合を除いて、これはうまく機能しているようです。ただし、アプリが元の状態に戻った場合は、それを好むでしょう。また、システムがこのように動作する理由と、これを処理するためのよりエレガントな方法があるかどうかにも興味があります。