質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.49%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

0回答

190閲覧

SwiftでUITableViewCell内のUIViewをトグルさせる(高さを変更する)処理を実装したい

oajfodjooaidjoa

総合スコア6

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

1クリップ

投稿2018/05/04 10:54

前提・実現したいこと

現在SwiftでSNSの投稿一覧の画面を実装しています。UITableViewCell内にあるUIViewの高さを動的に変更してトグルのような動きを制約のコンフリクトなしに実装したいです。

発生している問題・エラーメッセージ

過去に1度実装しています。表示は問題ないのですが、その時はトグルを広げる時に制約のコンフリクトが起きてしまい、エラーメッセージが表示されてしまいました。
イメージ説明

自分で実装した時の処理の流れ

  1. トグルを開く時は広げたいUIViewの中にUILabelを繰り返しaddSubviewしていく

UILabelの高さは複数行のコメントに対応するため高さが可変。高さに関する制約はなく、top,trailing、leading、bottomのAnchorConstirantの値をコードから設定。最後のUILabelのbottomの制約はトグル対象のUIViewのbottomとの距離を設定しています。
2. トグルを閉じる時はトグル対象のUIViewのsubviewを再帰的にremoveFromSuperview()して結果的に高さが0になるようにしています。
コンフリクトするのは、トグルを開閉する時だけでなくトグルを開いた状態で上にスクロールする時も制約にコンフリクトが生じます。コンフリクトの内容は縦方向の制約のコンフリクトです。

エラーメッセージ ( "<NSAutoresizingMaskLayoutConstraint:0x608000297890 h=-&- v=-&- UIView:0x7f9307caf0e0.midY == Wannago.ToggleButtonView:0x7f9307cae810.midY (active)>", "<NSAutoresizingMaskLayoutConstraint:0x608000297840 h=-&- v=-&- UIView:0x7f9307caf0e0.height == Wannago.ToggleButtonView:0x7f9307cae810.height (active)>", "<NSLayoutConstraint:0x60000028d660 UIView:0x7f9304cd97c0.height == 20 (active)>", "<NSLayoutConstraint:0x600000481d60 UIView:0x7f9304ceafc0.height == 1 (active)>", "<NSLayoutConstraint:0x60000029de20 UIView:0x7f9304cf01d0.height == 1 (active)>", "<NSLayoutConstraint:0x60000029c750 Wannago.PostedUserInfoView:0x7f9304cf03c0.height == 214 (active)>", "<NSLayoutConstraint:0x600000481ea0 Wannago.ReactionToPostView:0x7f9304cf0bb0.height == 46 (active)>", "<NSLayoutConstraint:0x600000482bc0 Wannago.PostedDateView:0x7f9304cf29f0.height == 33 (active)>", "<NSLayoutConstraint:0x60400028f910 V:|-(0)-[UIView:0x7f9304cd97c0] (active, names: '|':UITableViewCellContentView:0x7f9304cd6bb0 )>", "<NSLayoutConstraint:0x604000289e70 V:[UIView:0x7f9304cd97c0]-(0)-[UIView:0x7f9304ceafc0] (active)>", "<NSLayoutConstraint:0x60400028faa0 V:[UIView:0x7f9304ceafc0]-(0)-[Wannago.PostedUserInfoView:0x7f9304cf03c0] (active)>", "<NSLayoutConstraint:0x604000299c80 V:[Wannago.PostedUserInfoView:0x7f9304cf03c0]-(0)-[Wannago.ReactionToPostView:0x7f9304cf0bb0] (active)>", "<NSLayoutConstraint:0x60400028fb90 V:[Wannago.ReactionToPostView:0x7f9304cf0bb0]-(6)-[UILabel:0x7f9304cf0dc0'\U305f\U306a\U3079\U3067\U3059a \U304a\U6c17\U306b\U5165\U308a\U306e\U5199\U771f\U3067\U3059\U3002'] (active)>", "<NSLayoutConstraint:0x60400028f550 V:[UILabel:0x7f9304cf0dc0'\U305f\U306a\U3079\U3067\U3059a \U304a\U6c17\U306b\U5165\U308a\U306e\U5199\U771f\U3067\U3059\U3002']-(0)-[UIView:0x7f9304cf1af0] (active)>", "<NSLayoutConstraint:0x60400028e8d0 V:[UIView:0x7f9304cf1af0]-(0)-[Wannago.PostedDateView:0x7f9304cf29f0] (active)>", "<NSLayoutConstraint:0x60400028d930 V:[Wannago.PostedDateView:0x7f9304cf29f0]-(0)-[UIView:0x7f9304cf01d0] (active)>", "<NSLayoutConstraint:0x604000290cc0 V:[UIView:0x7f9304cf01d0]-(0)-| (active, names: '|':UITableViewCellContentView:0x7f9304cd6bb0 )>", "<NSLayoutConstraint:0x608000290270 V:|-(0)-[UIButton:0x7f9307caedc0'23\U4ef6\U306e\U30b3\U30e1\U30f3\U30c8\U3092\U898b\U308b'] (active, names: '|':UIView:0x7f9307caf0e0 )>", "<NSLayoutConstraint:0x608000297610 V:|-(10)-[Wannago.ToggleButtonView:0x7f9307cae810] (active, names: '|':UIView:0x7f9304cf1af0 )>", "<NSLayoutConstraint:0x6080002984c0 V:[UIButton:0x7f9307caedc0'23\U4ef6\U306e\U30b3\U30e1\U30f3\U30c8\U3092\U898b\U308b']-(10)-[UILabel:0x7f9307ca1680'\U305f\U306a\U3079 \U3059\U3070\U3089\U3057\U3044\U753b\U50cf\U3067\U3059\U306d\U3042\U304a\U3058\U3087\U3042\U3058\U3087\U3042...'] (active)>", "<NSLayoutConstraint:0x608000297b60 V:[UILabel:0x7f9307ca1680'\U305f\U306a\U3079 \U3059\U3070\U3089\U3057\U3044\U753b\U50cf\U3067\U3059\U306d\U3042\U304a\U3058\U3087\U3042\U3058\U3087\U3042...']-(10)-[UILabel:0x7f9307c51910'\U305f\U306a\U3079\U3060\U3088 \U6771\U5927\U5bfa\U306b\U884c\U3063\U3066\U307f\U305f\U3044\U306a\U3042\U304a\U3058\U3083\U304a...'] (active)>", "<NSLayoutConstraint:0x608000290720 V:[UILabel:0x7f9307c51910'\U305f\U306a\U3079\U3060\U3088 \U6771\U5927\U5bfa\U306b\U884c\U3063\U3066\U307f\U305f\U3044\U306a\U3042\U304a\U3058\U3083\U304a...']-(10)-[UILabel:0x7f9307cafa20'\U306a\U304b\U304c\U308f \U5357\U5927\U9580\U3060\U306d\U3002'] (active)>", "<NSLayoutConstraint:0x608000290cc0 V:[UILabel:0x7f9307cafa20'\U306a\U304b\U304c\U308f \U5357\U5927\U9580\U3060\U306d\U3002']-(10)-[UILabel:0x7f9307caf2d0'\U305f\U306a\U3079 aofjoaijfoajfoajfo...'] (active)>", "<NSLayoutConstraint:0x608000294f00 V:[UILabel:0x7f9307caf2d0'\U305f\U306a\U3079 aofjoaijfoajfoajfo...']-(10)-[UILabel:0x7f9307ca2c90'\U305f\U306a\U3079\U3060\U3088 aofjaoijfoajf'] (active)>", "<NSLayoutConstraint:0x6080002976b0 UILabel:0x7f9307ca2c90'\U305f\U306a\U3079\U3060\U3088 aofjaoijfoajf'.bottom == UIView:0x7f9304cf1af0.bottom (active)>", "<NSLayoutConstraint:0x60400028d9d0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f9304cd6bb0.height == 367 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x608000290270 V:|-(0)-[UIButton:0x7f9307caedc0'23件のコメントを見る'] (active, names: '|':UIView:0x7f9307caf0e0 )>

該当のソースコード

swift

1// コメントの件数分addSubviewしていくメソッド 2 func toggleOpenWithoutUpdate(toggleView: ToggleButtonView, constraint: NSLayoutConstraint, indexPathPointRow: Int) { 3 constraint.isActive = false 4 let array_count = apiTransferObject.postAllCommentArray[indexPathPointRow].count - 1 5 var nextStandardBottomAnchor = NSLayoutYAxisAnchor() 6 for count in 0...array_count { 7 if count == 0 { 8 let label = UILabel() 9 label.numberOfLines = 0 10 label.lineBreakMode = NSLineBreakMode.byCharWrapping 11 label.translatesAutoresizingMaskIntoConstraints = false 12 addedViewDictionary[indexPathPointRow]?.addSubview(label) 13 label.topAnchor.constraint(equalTo: (toggleView.toggleButton.bottomAnchor), constant: 10.0).isActive = true 14 label.leadingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.leadingAnchor)!, constant: 10.0).isActive = true 15 label.trailingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.trailingAnchor)!, constant: -22.0).isActive = true 16 nextStandardBottomAnchor = label.bottomAnchor 17 continue 18 } else if count == array_count { 19 let label = UILabel() 20 label.numberOfLines = 0 21 label.lineBreakMode = NSLineBreakMode.byCharWrapping 22 label.translatesAutoresizingMaskIntoConstraints = false 23 addedViewDictionary[indexPathPointRow]?.addSubview(label) 24 label.topAnchor.constraint(equalTo: (nextStandardBottomAnchor), constant: 10.0).isActive = true 25 label.leadingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.leadingAnchor)!, constant: 10.0).isActive = true 26 label.trailingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.trailingAnchor)!, constant: -22.0).isActive = true 27 label.bottomAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.bottomAnchor)!, constant: 0).isActive = true 28 return 29 } 30 let label = UILabel() 31 label.numberOfLines = 0 32 label.lineBreakMode = NSLineBreakMode.byCharWrapping 33 label.translatesAutoresizingMaskIntoConstraints = false 34 addedViewDictionary[indexPathPointRow]?.addSubview(label) 35 label.topAnchor.constraint(equalTo: (nextStandardBottomAnchor), constant: 10.0).isActive = true 36 label.leadingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.leadingAnchor)!, constant: 10.0).isActive = true 37 label.trailingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.trailingAnchor)!, constant: -22.0).isActive = true 38 nextStandardBottomAnchor = label.bottomAnchor 39 } 40 } 41 42// トグルを開閉するメソッド 43func toggleOpen(toggleView: ToggleButtonView, constraint: NSLayoutConstraint, indexPathPointRow: Int) { 44 tableView.beginUpdates() 45 self.apiTransferObject.toggleBoolArray[indexPathPointRow] = !self.apiTransferObject.toggleBoolArray[indexPathPointRow] 46 toggleOpenWithoutUpdate(toggleView: toggleView, constraint: constraint, indexPathPointRow: indexPathPointRow) 47 tableView.endUpdates() 48 } 49 50 func toggleClose(toggleView: ToggleButtonView, constraint: NSLayoutConstraint, indexPathPointRow: Int) { 51 tableView.beginUpdates() 52 for subview in (addedViewDictionary[indexPathPointRow]?.subviews)! { 53 if subview.restorationIdentifier == "toggle" { 54 55 continue 56 } 57 subview.removeFromSuperview() 58 } 59 constraint.isActive = true 60 tableView.endUpdates() 61 } 62

試したこと

layoutIfneeded()のタイミングの見直し
コンフリクトしている制約のpriorityの変更
高さの制約をEqualにしていたのをGreater than or Equalに変更
などを行いました。

補足情報(FW/ツールのバージョンなど)

Swiftのバージョンは4でXcodeのバージョンはVersion 9.3です。

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

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

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

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

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

kakajika

2018/05/11 02:16

UIStackViewを使ってみてはいかがでしょう?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問