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

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

ただいまの
回答率

90.76%

  • Swift

    6728questions

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

  • Xcode

    3865questions

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

  • iOS

    3813questions

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

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

受付中

回答 0

投稿

  • 評価
  • クリップ 1
  • VIEW 112

 前提・実現したいこと

現在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 )>

 該当のソースコード

// コメントの件数分addSubviewしていくメソッド
    func toggleOpenWithoutUpdate(toggleView: ToggleButtonView, constraint: NSLayoutConstraint, indexPathPointRow: Int) {
        constraint.isActive = false
        let array_count = apiTransferObject.postAllCommentArray[indexPathPointRow].count - 1
        var nextStandardBottomAnchor = NSLayoutYAxisAnchor()
        for count in 0...array_count {
            if count == 0 {
                let label = UILabel()
                label.numberOfLines = 0
                label.lineBreakMode = NSLineBreakMode.byCharWrapping
                label.translatesAutoresizingMaskIntoConstraints = false
                addedViewDictionary[indexPathPointRow]?.addSubview(label)
                label.topAnchor.constraint(equalTo: (toggleView.toggleButton.bottomAnchor), constant: 10.0).isActive = true
                label.leadingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.leadingAnchor)!, constant: 10.0).isActive = true
                label.trailingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.trailingAnchor)!, constant: -22.0).isActive = true
                nextStandardBottomAnchor = label.bottomAnchor
                continue
            } else if count == array_count {
                let label = UILabel()
                label.numberOfLines = 0
                label.lineBreakMode = NSLineBreakMode.byCharWrapping
                label.translatesAutoresizingMaskIntoConstraints = false
                addedViewDictionary[indexPathPointRow]?.addSubview(label)
                label.topAnchor.constraint(equalTo: (nextStandardBottomAnchor), constant: 10.0).isActive = true
                label.leadingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.leadingAnchor)!, constant: 10.0).isActive = true
                label.trailingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.trailingAnchor)!, constant: -22.0).isActive = true
                label.bottomAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.bottomAnchor)!, constant: 0).isActive = true
                return
            }
            let label = UILabel()
            label.numberOfLines = 0
            label.lineBreakMode = NSLineBreakMode.byCharWrapping
            label.translatesAutoresizingMaskIntoConstraints = false
            addedViewDictionary[indexPathPointRow]?.addSubview(label)
            label.topAnchor.constraint(equalTo: (nextStandardBottomAnchor), constant: 10.0).isActive = true
            label.leadingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.leadingAnchor)!, constant: 10.0).isActive = true
            label.trailingAnchor.constraint(equalTo: (addedViewDictionary[indexPathPointRow]?.trailingAnchor)!, constant: -22.0).isActive = true
            nextStandardBottomAnchor = label.bottomAnchor
        }
    }

// トグルを開閉するメソッド
func toggleOpen(toggleView: ToggleButtonView, constraint: NSLayoutConstraint, indexPathPointRow: Int) {
        tableView.beginUpdates()
        self.apiTransferObject.toggleBoolArray[indexPathPointRow] = !self.apiTransferObject.toggleBoolArray[indexPathPointRow]
        toggleOpenWithoutUpdate(toggleView: toggleView, constraint: constraint, indexPathPointRow: indexPathPointRow)
        tableView.endUpdates()
    }

    func toggleClose(toggleView: ToggleButtonView, constraint: NSLayoutConstraint, indexPathPointRow: Int) {
        tableView.beginUpdates()
        for subview in (addedViewDictionary[indexPathPointRow]?.subviews)! {
            if subview.restorationIdentifier == "toggle" {

                continue
            }
            subview.removeFromSuperview()
        }
        constraint.isActive = true
        tableView.endUpdates()
    }

 試したこと

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • kakajika

    2018/05/11 11:16

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

    キャンセル

  • oajfodjooaidjoa

    2018/05/13 17:52

    実装してみます!

    キャンセル

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

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Swift

    6728questions

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

  • Xcode

    3865questions

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

  • iOS

    3813questions

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