ユーザーがテーブルビューのすべてのテキストフィールド間を矢印ボタンでナビゲートできるようにするいくつかの矢印キーを備えたキーボードを作成しました。(セルあたり 2 つ)
セルが無効になる状況がいくつかあるため、それらをスキップする再帰呼び出しがあります。すなわち。ユーザーが右矢印を押したときに textField が無効になっている場合は、右矢印を再帰的に呼び出してスキップします。
また、自分で行う必要があるスクロールをアニメーション化します。ただし、最近、ユーザーが新しい textField に移動し、スクロール アニメーションが終了した後に firstResponder を設定しようとすると、EXEC_BAD_ACCESS が発生する問題が発生しました。
最初のセルから 2 回下に移動すると、この問題を再現できます。これがコードです。表示できる限り最善の順序で、多くの編集が行われています(他の3つの矢印ボタンのすべてのコードと同様に、呼び出された行のみが表示されます)
//receive the arrow button pressed first
_arrowButton = arrowButton;
@try
{
switch (_arrowButton.tag)
{
case NumericKeyboardViewDownArrow:
destinationIndexPath = [NSIndexPath indexPathForRow:currentIndexPath.row + 1 inSection:currentIndexPath.section];
newTag = currentTextField.tag;
break;
default:
break;
}
// check bounds of the intended index path and return if out of bounds
if ((destinationIndexPath.row == -1) || (destinationIndexPath.row >= [_tableView numberOfRowsInSection:[destinationIndexPath section]])) {
destinationIndexPath = currentIndexPath;
return;
}
/*
Animation for scrolling
*/
CGPoint current = [_tableView contentOffset];
// if we must animate up
if (destinationIndexPath.row < currentIndexPath.row)
{
// up code here
}
// if we must animate down
else if (destinationIndexPath.row > currentIndexPath.row)
{
// always scroll animate for down
[_tableView setContentOffset:CGPointMake(0, current.y + _tableView.rowHeight) animated:YES];
}
// if we only move left or right
else
{
// left and right code here
}
//update our current location
currentIndexPath = destinationIndexPath;
@catch (NSException *e)
{
return;
}
その後、アニメーションが完了したアニメーション メソッドで終了した後
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
//after the animation is done, set the responder
nextTextFieldSelection = (UITextField *)[[_tableView cellForRowAtIndexPath:currentIndexPath] viewWithTag:newTag];
NSLog(@"nexttextfield%@",nextTextFieldSelection);
if (nextTextFieldSelection)
{
//CRASH OCCURS HERE [nextTextFieldSelection becomeFirstResponder];
}
[self checkTextFieldIsDisabled];
}
そのメソッドの終わりまでに、新しいテキスト フィールドが表示され、無効になっているかどうかを確認します。このクラッシュを再現すると、移動先の textFields が無効になっていないため、終了するだけです。
新しい becomeFirstResponder を呼び出す前にファーストレスポンダーを辞任しようとしましたが、効果がないようです。適切な場所で辞任していなかった可能性があります。メモリの問題はどこにあるのでしょうか?
ありがとう