2015-01-05 17 views
9

iOS 8.1.XのUITextFieldは、Helvetica Neue Light 17:iOS 8.1のUITextFieldは、一部のフォントを使用しているときに、編集モードと非編集モードの垂直方向の配置が異なる

UITextField bug example

私は、サンプルプロジェクトhereを持っています。

カスタムテキストフィールドを作成する必要がない回避策はありますか? 主な問題は、ダイナミックタイプを使用すると、フォントが実行時に変更される可能性があることです。

とにかく私はレーダーrdar://19374610を開いた。

+0

私はこの問題に直面していることを覚えています。フォントの縦の位置に関連するフォントの特定のプロパティは、一部の状況では無視され、他のプロパティでは無視されます。この場合、編集中には異なる動作をしますが、そうではありません。当時、私は素早いハックとして、編集開始時にUITextField 1または2ピクセルの位置を変更し、編集終了時に戻すようにしました。 – manecosta

+0

このアプローチの問題点は、UITextFieldに境界線や背景を使用することができないことです。つまり、使用していると思われるネイティブの丸い境界線を全体的に再配置していることが明らかになります。 – manecosta

+0

この男は同じ問題に直面していて、私が当時と同じ結論に達しました。 http://stackoverflow.com/questions/9674566/text-in-uitextfield-moves-up-after-editing-center-while-editing – manecosta

答えて

-1

このバグはフォントに依存しているので、これを補正するために属性付き文字列のスタイルを設定する解決策を説明します。

ヘルベチカノイエ光とサイズ17との最初のTextFieldにこの問題を解決するための例:

は、ビューコントローラを仮定は、あなたが設定したときに重要な部分があるfirstTextField

- (void)viewDidLoad { 
[super viewDidLoad]; 
// Do any additional setup after loading the view, typically from a nib. 
NSDictionary *style = @{ 
     NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Light" 
               size:17], 
     NSParagraphStyleAttributeName : [NSParagraphStyle defaultParagraphStyle], 
     NSBaselineOffsetAttributeName: @(0.4) 
}; 
_firstTextField.attributedText = [[NSAttributedString alloc] initWithString:_firstTextField.text 
                   attributes:style]; 

} 
-(void)textFieldDidBeginEditing:(UITextField *)textField { 
NSDictionary *style = @{ 
     NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Light" 
               size:17], 
     NSParagraphStyleAttributeName : [NSParagraphStyle defaultParagraphStyle], 
     NSBaselineOffsetAttributeName: @(0.0) 

}; 
[_firstTextField setTypingAttributes: style]; 
} 

の代理人でありますtextFieldを表示してから編集するまでのNSBaselineAlignmentまた、フォントがダブルサイズ(textFieldが十分に大きい)で、ジャンプ効果を避けるためにNSBaselineOffsetが同じであるときに何が起きたかを確認しました。

+0

このバグはフォントに依存することがわかりました。ここで問題となるのは、Dynamic Typeを使用しているため、フォントが実行時に変更される可能性があることです。したがって、このソリューションは、特定のケースでの作業にもかかわらず、その質問に答えることはできません。これをもっと明確にするために質問を書き直します。 –

3

ちょうど同じ問題を遭遇し、ちょっとデバッグすることに決めました。基本的には、さまざまなフォント(帽子の高さ、ポイントサイズ、好みの高さ、利用可能な高さ、テキストが移動した距離)の値をプロットし、パターンに気づいただけです。

それは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バージョンを使用する必要があります。

+0

**編集:**ボーダーテキストフィールドとIBによって作成されたテキストフィールドの修正が追加されました。 –

+0

私はそれがios 8.xの問題であることを確認できます。 iOS 9.0.2では発生しません。 –

+1

@Otávioそれは確かです。したがって、if(UIDevice.currentDevice.systemVersion.integerValue!= 8)チェック。 –

関連する問題