私のView Controllerには、UITextViewがあります。このテキストビューには文字列が入力されます。文字列は短くても長くてもかまいません。文字列の長さに応じて、textviewの高さを調整する必要があります。ストーリーボードと自動レイアウトを使用しています。
テキストビューの高さにいくつか問題があります。
場合によっては、高さがテキストに完全に調整されます。時々、いいえ、最初の行でテキストがトリミングされます。以下では、textviewは黄色です。青はスクロールビュー内のコンテナビューです。紫は写真を撮る場所です。
テキストは私のコアデータベースからのもので、文字列属性です。画面1と2の間で変更されるのは文字列だけです。
コンソールで文字列を印刷すると、正しいテキストが表示されます。
my amazing new title
Another funny title for demo
私のテキストビューの制約:
2つの異なるディスプレイがある理由がわかりません。
編集
私はviewDidLoadで@Nateのアドバイスを試しました、私は追加しました:
myTextViewTitle.text="my amazing new title"
myTextViewTitle.setContentHuggingPriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
myTextViewTitle.setContentCompressionResistancePriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
myTextViewTitle.setTranslatesAutoresizingMaskIntoConstraints(false)
let views = ["new_view": myTextViewTitle]
var constrs = NSLayoutConstraint.constraintsWithVisualFormat("|-8-[new_view]-8-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
self.view.addConstraints(constrs)
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[new_view]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
self.myTextViewTitle.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[new_view(220@300)]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
結果がありません。インターフェイスビルダーのテキストビューに追加された高さ制約の有無にかかわらず...
編集2
除外パスを使用するには、戻るボタンがあるため、UIlabelではなくUITextViewが必要です。
let exclusionPathBack:UIBezierPath = UIBezierPath(rect: CGRect(x:backButton.bounds.Origin.x, y:backButton.bounds.Origin.y, width:backButton.bounds.width+10, height:backButton.bounds.height))
myTextViewTitle.textContainer.exclusionPaths=[exclusionPathBack]
私は解決策を見つけました。
UITextViewの高さに注目し、アスペクト比に関する記事を読みました。試してみたかったのですが、うまくいきました!
そのため、ストーリーボードで、textviewのアスペクト比を追加し、[ビルド時に削除]オプションをオンにしました。
ViewDidLayoutSubviews()で、私は書いた:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let contentSize = self.myTextViewTitle.sizeThatFits(self.myTextViewTitle.bounds.size)
var frame = self.myTextViewTitle.frame
frame.size.height = contentSize.height
self.myTextViewTitle.frame = frame
aspectRatioTextViewConstraint = NSLayoutConstraint(item: self.myTextViewTitle, attribute: .Height, relatedBy: .Equal, toItem: self.myTextViewTitle, attribute: .Width, multiplier: myTextViewTitle.bounds.height/myTextViewTitle.bounds.width, constant: 1)
self.myTextViewTitle.addConstraint(aspectRatioTextViewConstraint!)
}
完璧に機能します。
まず、UITextViewのスクロール可能を無効にします。 2つのオプション:
UITextViewを作成し、IBOutlet(TextView)に接続します。デフォルトの高さのUITextView高さ制約を追加し、IBOutlet(TextViewHeightConstraint)に接続します。 UITextViewのテキストを非同期に設定する場合、UITextViewの高さを計算し、UITextViewの高さの制約を設定する必要があります。サンプルコード:
CGSize sizeThatFitsTextView = [TextView sizeThatFits:CGSizeMake(TextView.frame.size.width, MAXFLOAT)];
TextViewHeightConstraint.constant = sizeThatFitsTextView.height;
In Swift 3.0、tvHeightConstraintは対象のTextViewの高さの制約です(複数のtextviewを使用する場合、関数入力に追加します):
func textViewDidChange(textView: UITextView) {
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
if size.height != tvHeightConstraint.constant && size.height > textView.frame.size.height{
tvHeightConstraint.constant = size.height
textView.setContentOffset(CGPoint.zero, animated: false)
}
}
@cmiおよび@Pablo RuanへのH/T
In Swift 2.3:
func textViewDidChange(textView: UITextView) {
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.max))
if size.height != TXV_Height.constant && size.height > textView.frame.size.height{
TXV_Height.constant = size.height
textView.setContentOffset(CGPointZero, animated: false)
}
}
私はあなたのコードを適合させ、レイアウトサブビューとtextViewDidChangeの両方に使用しました。トラブルシューティングを1時間行った後、私の1日をありがとうございました...
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textViewDidChange(self.recordingTitleTV)
}
func textViewDidChange(_ textView: UITextView) {
let contentSize = textView.sizeThatFits(textView.bounds.size)
var frame = textView.frame
frame.size.height = contentSize.height
textView.frame = frame
let aspectRatioTextViewConstraint = NSLayoutConstraint(item: textView, attribute: .height, relatedBy: .equal, toItem: textView, attribute: .width, multiplier: textView.bounds.height/textView.bounds.width, constant: 1)
textView.addConstraint(aspectRatioTextViewConstraint)
}
非常に類似した問題に対する私の簡単な解決策:
テキストフィールドまたはビューを使用する代わりに、行数を0に設定したラベルを使用しました。次に、この例では幅を制約するラベルのコンテナーにリーディングエッジとトレーリングエッジをクリップしました。制約の定数は0です。問題は、行数を0に設定して、内容に応じてラベルを拡大または縮小できるようにすることです。テキストが切り取られることはなく、ラベルの高さは、幅(私の場合はコンテナーの幅)に対して構成したさまざまなサイズクラスのすべてについて、その内容を超えることはありません。 IOS 8.0以降(さまざまなサイズクラスに合わせてラベル幅のすべてのラベルの[優先幅]属性の横にある[明示的]がオフになっていることも確認してください)].
戻るボタンの画像とテキストのUILabelを用意し、自動レイアウトを使用して配置しませんか?そして、おそらく黄色の背景の3番目のビュー。