2009-05-12 8 views
6

ユーザが入力したテキストを大きなマルチラインUITextViewに移動する必要がありますが、小さい(しかしまだ複数行の)UITextView *にしてください。ユーザーが小さなビューで表示するよりも多くのテキストを入力した場合、すべての(切り捨てられた)テキストが表示されるようにテキストを切り捨てたいと思います。 (大きいUITextViewも小さなものもスクロールしないでください)UITextViewに合うようにフォントを指定した文字列

これを行う最も良い方法は何ですか?

私は文字ずつ文字列を短くし、ループを使用し、この短い文字列が必要となる高さを見つけるためにNSStringsizeWithFont: constrainedToSize: lineBreakMode:を使用して、高さに対して、私は私の小さなに利用できる持っていることを比較することができますUITextView、文字列が収まるとループが終了しますが、遅くて扱いにくいようです。より良い方法が必要です。

UITextViewのdisplayTextメンバーを画面に表示するときにその宛先を切り捨てるように指示したいのですが、その方法を見つけることができませんでした。

*この詳細コンテキストを、私は以下の作ったコメントから:

を私は風景のアプリを持っています。私は、ユーザーが選択した写真に応じてビューのレイアウトを変更します。風景写真の場合、キャプションは小さく、写真の一番下に1行だけ表示されます。彼女がポートレートの写真を選んだ場合、写真の横にあるキャプションには十分なスペースがあるので、キャプションが大きくなります。

ユーザーが写真の向きを縦長から横長に変更した場合、テキストを切り捨てて、それを編集して意味をなさないようにします。私はちょうどそれをザップすることができますが、私は彼女のタイピングを最小限に抑えるためにそれを保存することを好むでしょう。

答えて

3

これを正しく行うために、以下の再帰メソッドとパブリックAPIを書きました。醜いファッジファクターは、this questionの件名です。

#define kFudgeFactor 15.0 
#define kMaxFieldHeight 9999.0 

// recursive method called by the main API 
-(NSString*) sizeStringToFit:(NSString*)aString min:(int)aMin max:(int)aMax 
{ 
if ((aMax-aMin) <= 1) 
    { 
    NSString* subString = [aString substringToIndex:aMin]; 
    return subString; 
    } 

int mean = (aMin + aMax)/2; 
NSString* subString = [aString substringToIndex:mean]; 

CGSize tallerSize = CGSizeMake(self.frame.size.width-kFudgeFactor,kMaxFieldHeight); 
CGSize stringSize = [subString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap]; 

if (stringSize.height <= self.frame.size.height) 
    return [self sizeStringToFit:aString min:mean max:aMax]; // too small 
else  
     return [self sizeStringToFit:aString min:aMin max:mean];// too big 
} 

-(NSString*)sizeStringToFit:(NSString*)aString 
{ 

CGSize tallerSize = CGSizeMake(self.frame.size.width-kFudgeFactor,kMaxFieldHeight); 
CGSize stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap]; 

// if it fits, just return 
if (stringSize.height < self.frame.size.height) 
    return aString; 

// too big - call the recursive method to size it  
NSString* smallerString = [self sizeStringToFit:aString min:0 max:[aString length]]; 
return smallerString; 
} 
+0

このコードは素晴らしいですが、ありがたいですが、私はそれが失敗する2つの状況を発見しました:1)文字列にスペースがたくさんある場合2)行の "<" if(stringSize.height SpaceDog

1

小さなUITextViewの代わりにUILabelを使用できるかどうかやや異なるアプローチをとることをお勧めします。

UILabelsは、numberOfLinesプロパティを使用してUITextViewのように複数行に設定できます。

UILabelsにはlineBreakModeプロパティもあります。このプロパティのデフォルト値は、探している切り捨て効果とまったく同じだと思います。ユーザーがUITextViewの編集を終了

+1

私はUILabelsを編集できるとは思いませんか?ユーザーが両方のフィールドにテキストを入力できるようにします。 (とりあえず一度切り捨てれば、おそらくテキストは意味をなさないでしょう) –

+0

あなたは正しいですUILabelsは編集できません。私はあなたが今私を困らせたと思う。 一般的に、私はあなたのより小さいUITextViewを編集するときにユーザーエクスペリエンスがどんなものかと思います。ユーザーはすべてのテキストを編集できますか、または切り捨てられていない部分だけを編集できますか?ユーザーがすべてのテキストを編集できる場合、編集セッションが終了したときに切り捨てられると、編集内容が反映されたことをユーザーはどのように伝えることができますか? これらの理由から、私は小規模なビューをテキストの読み取り専用の要約として保つことを検討するかもしれません。 –

+0

もう少し情報が必要です。私はランドスケープアプリを持っています。何が起こるかは、ユーザーが選択した写真に応じてビューのレイアウトを変更することです。風景写真の場合、キャプションは小さく、写真の一番下に1行だけ表示されます。彼らが肖像写真を選んだ場合、写真の横にあるキャプションには十分なスペースがあるので、キャプションは大きくなります。 ユーザーが写真の向きを縦長から横長に変更した場合、テキストを切り捨てて、変更することができます。 –

1

私はジョナサンがUILabelについての何かに上だったと思う...だから

は、テキストの文字列を取得し、UILabelにそれを渡します。 UITextViewのアルファ値を0に変更したり、スーパービューから削除したりします。可能であれば、改ざんされていないフルテキストをivarに保存してください。

UILabelは「編集可能」ではありませんが、UILabel(またはそのスーパービュー)でタッチを検出できます。 UILabelのタッチを検出すると、非表示のUITextViewを復元し、保存した文字列を復元するだけです。

SDKは時には痛みですが、ほとんどの場合常に戦いに勝ちます。多くの場合、UIKitの規約に合わせてデザインを調整する方が良い

2

これは実際の修正ではありませんが、計算の出発点となります。

NSStringのsizeWithFont: constrainedToSize: lineBreakMode:を使用すると、テキストの縦の高さが得られます。フォントの先頭の高さでそれを分割すると、文字列全体の行数が取得されます。その数で[NSString count]を除算すると、1行あたりの文字数に近似できます。これは、文字列が均質であると仮定し、誰かが「MMMMMMMMM ...」のように「iiiiiiiiiii ...」と入力すると不正確になります。

また、関連するフォントのleadingの高さあなたのバウンディングボックスに収まる行数を取得します。

行あたりの文字数を掛けると行数によって、あなたに合うテキストを見つけるための出発点を与える。

あなたがすることで、この図では、エラーのマージンを計算することができそれらの「iiiiii ...」と「MMMMMM ...」の文字列について同じ計算を行います。

+0

これは良いアプローチであり、上記の方法を使用して文字列の長さにバイナリチョップを行うことです。私はまだ良い方法があることを望んでいるが、私は今そこにない気分を得る。 –

+0

解決策はCourierです。固定幅フォント、数式なし... –

+0

@Tristan、ラップ時に空白を無視する場合のみ。しかし、より簡単な問題になります。 –