🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

4216閲覧

可変するUITextviewの高さに応じて背景のUIViewの高さを変化させたい

maplemee

総合スコア16

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2019/10/01 11:47

編集2019/10/03 07:40

わからないこと
ピンク色のUIViewの中に配置した水色のUITextviewを文字量に応じて高さが伸びるように設定したのですが、
一番高い時にtextviewがUIViewからはみ出してしまいます。
イメージ説明
イメージ説明

やりたいこと
可変するUITextviewの高さに応じて背景のUIViewの高さを変化させたいのですが、どのような方法がありますでしょうか?

コード

Swift

1import UIKit 2 3class ViewController: UIViewController,UITextViewDelegate { 4 5 let MIN_HEIGHT_MSG: CGFloat = 40 6 let MAX_HEIGHT_MSG: CGFloat = 100 7 8 @IBOutlet weak var msg: UITextView! 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 // Do any additional setup after loading the view. 13 msg.delegate = self 14 } 15 16 func textViewDidChange(_ textView: UITextView) { 17 drawBox() 18 } 19 20 // メッセージBOXの設定 21 func drawBox() { 22 var height = msg.sizeThatFits(CGSize(width: msg.frame.size.width, height: CGFloat.greatestFiniteMagnitude)).height 23 24 if height < MIN_HEIGHT_MSG { 25 height = MIN_HEIGHT_MSG 26 } else if MAX_HEIGHT_MSG < height { 27 height = MAX_HEIGHT_MSG 28 } 29 30 // textviewの位置調整 31 msg.frame = CGRect(x: msg.frame.origin.x, y: msg.frame.origin.y, width: msg.frame.width, height: height) 32 } 33 34} 35

追記
UIViewを以下のようにCGRectで指定したところ高さは可変するようになったのですが今度はtextviewの高さが不変になりました。

// textviewの位置調整 msg.frame = CGRect(x: msg.frame.origin.x, y: msg.frame.origin.y, width: msg.frame.width, height: height)   // 新たに背景のUIViewの高さも動くように設定 backui.frame = CGRect(x: backui.frame.origin.x, y: backui.frame.origin.y , width: backui.frame.width, height: height + backui.frame.height)

5行ほどUITextViewにて改行を行った時のUIView
イメージ説明

追記2
AutoLayout Storyboard
イメージ説明
イメージ説明

追記3
StoryBoard
イメージ説明

コード

/// キーボードが表示時に画面をずらす。 @objc func keyboardWillShow(_ notification: Notification?) { let keyboardFrame = (notification?.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue let duration = notification?.userInfo?[UIKeyboardAnimationDurationUserInfoKey] UIView.animate(withDuration: duration as! TimeInterval, animations: { let transform = CGAffineTransform(translationX: 0, y: -(keyboardFrame?.size.height)!) self.view.transform = transform },completion:nil) topview.isHidden = false subwriteviewconstraint.constant = 71 }

無事動きましたm(_ _)m
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayabusabusash

2019/10/02 01:36

AutoLayoutの制約は設定していたりしますか? また、Storyboard等でレイアウトを組んでいたらスクショを貼ることは可能ですか?
maplemee

2019/10/02 14:08

ありがとうございます。 StoryboardにてAutoLayoutを設定しています。 スクショを追記に載せました。
guest

回答1

0

ベストアンサー

追記ありがとうございます。確認しました。

今回の要件なら特別コードを書かなくても、Auto Layoutのみで解決することができます。
まず背景のViewの上にTextViewをのせる形でレイアウトを作成します。

Storyboard01

次に背景のViewに対してAuto Layoutの制約を付けていきます。
とりあえず**Y座標は画面の真ん中、幅は画面両端から24px(※)**の制約を追加します。
この状態では背景のViewの高さを決定する制約がないためエラーが出ます。

Storyboard02

次にTextViewに対して制約を追加していきます。
まずTextViewのScrolling Enabledをオフにします。
こうすることでTextViewの高さ(intrinsicContentSize)は中のテキストに応じて変化するようになります。

この状態で背景のViewに対して縦横に8pxの余白を設けるように制約を追加します。

Storyboard03

これで実行すれば中のテキストに応じて背景のViewも伸びるようになるはずです。

Result

※ 幅に対する制約がない場合はTextViewが横に伸びてしまうため必須です。

追記(2019/10/03)

入力Viewの上と下に隣り合ってTextViewが入ったViewが挟まったレイアウトで同じようにtextviewの高さだけ伸縮させたい

ということなので、
こういう時にはUIStackViewを使うといいと思います。(参考)

先ほどと同じように背景のViewとTextViewのセットを用意します。
ただし、背景のViewに対して幅やY座標の制約は付けないでください。TextViewの上下左右の余白のみ設定した状態にしてください。

この背景とTextViewのセットと上下のUIViewを選択した状態で、
Embed InからStackViewを選択します。

Storyboard04

これで3つのViewがStackViewに包まれている状態になります。
次にStackViewの設定を変更します。

  • Axis: Vertical
  • Alignment: Fill
  • Distribution: Equal Spacing
  • Spacing: 0

Storyboard05

あとはこのStackViewに対して制約を追加します。
見たところ画面のしたに配置しているので、左右と下の余白を0になるような制約を追加しました。

Storyboard06

以上でやりたいことはできるんじゃないかなと思います。

投稿2019/10/03 00:47

編集2019/10/03 04:23
hayabusabusash

総合スコア767

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maplemee

2019/10/03 03:41 編集

丁寧にありがとうございました。無事解決しました。 追加質問にご回答いただければ幸いなのですが、最終的に作りたい画面では(追記3に載せました) 入力Viewの上と下に隣り合ってTextViewが入ったViewが挟まったレイアウトで同じようにtextviewの高さだけ伸縮させたいのですが、このような場合はどうAutoLayoutを設定すればよいでしょうかm(_ _)m
hayabusabusash

2019/10/03 03:53

ついでなので回答します。 次回以降は違う質問として新しくたてた方がいいと思います????‍♂️ この上下のViewもTextViewですか?
maplemee

2019/10/03 04:00

ごめんなさいm(_ _)m 以後気をつけます。 上下はUIViewになっています。
hayabusabusash

2019/10/03 04:03

わかりました。 ちょっと追記しますので、少々お待ちください????‍♂️
maplemee

2019/10/03 07:55 編集

一度入門書でStackViewという物が書かれていたのですが(そこでは軽く紹介だけ)、 まさかこのような形で応用させることが出来るとはほとんどその知識を今までスルーしていましたm(_ _)m 書物やネットで調べてはいるのですがお恥ずかしながらここが1番の疑問が解決出来ると思い、 勝手ながらですが追加質問をしていました。とても助かりました! この度は本当にありがとうございました。
hayabusabusash

2019/10/03 07:54

実現できたようでよかったです???? StackViewは非常に応用が効くものなのでぜひ色々試してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問