ちょうど同じ問題を遭遇し、ちょっとデバッグすることに決めました。基本的には、さまざまなフォント(帽子の高さ、ポイントサイズ、好みの高さ、利用可能な高さ、テキストが移動した距離)の値をプロットし、パターンに気づいただけです。
それは2つの完全に異なる方法でレンダリングされるので、テキストが上に移動した理由:非編集バージョンは(あなたも、フックをオーバーライドすることができます)-drawRect:
を使用してレンダリングされ、編集バージョンは、いわゆるUIFieldEditor
によってレンダリングされます。これは、あなたが網膜デバイスにいるかどうかにかかわらず、テキストの高さがceil
に現れ、後でそれを中心にします。しかし、Retinaデバイスでは、ピクセルに合わせるには常にceil(scalar * scale)/scale
にする必要があります。したがって、iOSは必要以上のテキストの高さを想定しています。面白いことに、静的テキストとUIFieldEditor
のレンダリングが異なります。
この問題を解決するには、サブタイプUITextField
をオーバーライドし、-editingRectForBounds:
を上書きします。ここでは、非編集矩形( 'テキスト矩形')を取って、Appleが事前に実行するシフトを考慮する必要があります。
- (CGRect)editingRectForBounds:(CGRect)bounds
{
if (UIDevice.currentDevice.systemVersion.integerValue != 8) return [self textRectForBounds:bounds];
CGFloat const scale = UIScreen.mainScreen.scale;
CGFloat const preferred = self.attributedText.size.height;
CGFloat const delta = ceil(preferred) - preferred;
CGFloat const adjustment = floor(delta * scale)/scale;
CGRect const textRect = [self textRectForBounds:bounds];
CGRect const editingRect = CGRectOffset(textRect, 0.0, adjustment);
return editingRect;
}
編集:私はちょうど8.0などの古いOSのバージョン、上のコードをテストしました。 iOS 7.xでは、すべてが問題なく表示されますが、iOS 8.0にはすでにバグが含まれています。私たちは未来を予測することはできないので、今はiOS 8.xの修正だけを含めるようにしています。AppleがiOS 9自体で問題を修正したらうれしいことです。
別の編集:このコードは、テキスト編集はその静的なカウンターパートと同じ位置に表示されます。それらを個別に制御したい場合(-textRectForBounds:
と-editingRectForBounds:
の両方を提供しているのでAppleが理にかなっていると思う)、[self textRectForBounds:bounds]
を[super editingRectForBounds:bounds]
に置き換えることができます。スウィズルを使用してカテゴリにこの修正プログラムを実装する場合は、確かにsuper
バージョンを使用する必要があります。
私はこの問題に直面していることを覚えています。フォントの縦の位置に関連するフォントの特定のプロパティは、一部の状況では無視され、他のプロパティでは無視されます。この場合、編集中には異なる動作をしますが、そうではありません。当時、私は素早いハックとして、編集開始時にUITextField 1または2ピクセルの位置を変更し、編集終了時に戻すようにしました。 – manecosta
このアプローチの問題点は、UITextFieldに境界線や背景を使用することができないことです。つまり、使用していると思われるネイティブの丸い境界線を全体的に再配置していることが明らかになります。 – manecosta
この男は同じ問題に直面していて、私が当時と同じ結論に達しました。 http://stackoverflow.com/questions/9674566/text-in-uitextfield-moves-up-after-editing-center-while-editing – manecosta