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

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

ただいまの
回答率

90.53%

  • Swift

    8540questions

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

  • Swift 2

    1337questions

    Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

UITableViewCellの大きさをタップ時に広げたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,765

Y_M

score 245

前提・実現したいこと

掲題の通りタップ時に適当な大きさに拡縮したいのですが、思い通りの大きさにはなってくれません。

現在数値で「100」を指定しているため、高さ100のセルになっていますが、
・「名無しさん」「★★★★★」「ここにコメント〜美味しかったです」までの高さをタップする前の高さ
・線を跨ぎ、「ご来店ありが〜お待ちしております」までの高さをタップ後の高さ
として実装したいと思っています。

スクショスクショ2

該当のソースコード

class ViewController: UIViewController, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    var toggle = true
    var toggleArray = [true, false, true]
    var rowHeight: CGFloat = 44.0

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        if let cell = tableView.dequeueReusableCellWithIdentifier("Cell") {
            rowHeight = CGRectGetHeight(cell.frame)
            print("rowHeight=", rowHeight)
        }
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
        cell.setText()
        return cell
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if toggleArray[indexPath.row] == true {
            if toggle {
                return rowHeight
            } else {
                return UITableViewAutomaticDimension
            }
        } else {
            return rowHeight
        }
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if toggleArray[indexPath.row] == true {
            toggle = !toggle
            tableView.reloadRowsAtIndexPaths(tableView.indexPathsForVisibleRows!, withRowAnimation: UITableViewRowAnimation.Fade)
        }
    }

    func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return self.tableView(tableView, heightForRowAtIndexPath: indexPath)
    }

}

試したこと

tableView.rowHeight = UITableViewAutomaticDimensionで高さを調節しているのなら
調整後のtableView.rowHeightから線より下のUIの高さを引けばよいのではないかと考えましたが。
そもそもtableView.rowHeightの認識が間違っていたため実装を断念しました。

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

Swift2.2
Xcode7.3.1
こちらのサイトを参考にしています。

追記

スクショスクショ

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • Y_M

    2016/10/26 16:28

    そうです。1番上のセルをタップすると1番上のセルのみ「拡大/縮小」する感じです。

    キャンセル

  • fuzzball

    2016/10/26 16:35

    拡大した状態は、右側の画像のようになれば正解なんでしょうか?それとも、現状が右側の画像で、これではダメということなのでしょうか?

    キャンセル

  • Y_M

    2016/10/26 16:39

    右側の画像は正解になります。畳んだときの大きさが現在だと100固定になっているものを、キレイにしたいということです。わかりにくくて申し訳ないです。

    キャンセル

回答 1

checkベストアンサー

+1

Storyboard上のセルを作るときにテキストを一行だけにすれば、その時の高さがtableView.rowHeightに入りますので、閉じているときにその高さを設定してやればいいと思います。

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if indexPath.row == 0 {
        if toggle {
            return tableView.rowHeight //※デフォルトサイズを返す
        } else {
            //tableView.estimatedRowHeight = 100 //※とりあえずコメント
            //tableView.rowHeight = UITableViewAutomaticDimension //※これはいらない
            return UITableViewAutomaticDimension //※いい感じのサイズを返す
        }
    } else {
        return tableView.rowHeight //※デフォルトサイズを返す
    }
}

 セルの高さ

tableView.rowHeightを使うのではなく、下のようにしてセルの高さを保存しておいてもいいかと思います。

var rowHeight: CGFloat = 44.0

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if let cell = tableView.dequeueReusableCellWithIdentifier("Cell") {
        rowHeight = CGRectGetHeight(cell.frame)
        print("rowHeight=", rowHeight)
    }
}

 estimatedHeightForRowAtIndexPath

同じ値にしたいのでheightForRowAtIndexPathを呼び出しています。

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
    return self.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

 色々と試した挙句

これがシンプルで良いという結論に。高さはあくまでおまかせで中身を変更します。
今のままだと下のマージンが広くなってしまいますが、気になるようならマージンの制約値を変えてやればいいと思います。(たぶん)

勝手に色々と追加していますが、

  • labelTop,labelBottomは、それぞれ上ラベル、下ラベル
  • msgTop,msgBottomは、それぞれ上メッセージ、下メッセージ
  • viewBarは下線(区切り線)のUIView
  • toggleは配列にしています

となっています。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    //上は常に全文表示
    cell.labelTop.text = msgTop[indexPath.row]

    //線から下は開いているときだけ
    if toggle[indexPath.row] {
        //close
        cell.labelBottom.text = ""
        cell.viewBar.hidden = true
    } else {
        //open
        cell.labelBottom.text = msgBottom[indexPath.row]
        cell.viewBar.hidden = false
    }

    return cell
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
    return UITableViewAutomaticDimension
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/26 17:09

    この方法で試したところ、「名無しさん」「ここにコメント〜美味しかったです」
    などを含めすべて隠れてしまいました。

    キャンセル

  • 2016/10/26 17:13 編集

    rowHeightが0ということでしょうか?Storyboard上のTableViewのRow Heightが0になってますか?

    キャンセル

  • 2016/10/26 17:15

    スクリーンショットを追記しました。

    キャンセル

  • 2016/10/26 17:16 編集

    AutoLayoutが崩れてしまっているかもしれないです。
    ※閉じたときに崩れてしまっているようです。

    キャンセル

  • 2016/10/26 17:28

    tableView.rowHeightを使わない方法を追記しました。

    キャンセル

  • 2016/10/26 17:33

    ※スクリーンショット追加しました。
    やはりAutoLayoutが崩れているみたいです。
    コメントのLabelの高さを可変にしているのがいけないのでしょうか。
    ひとまず回答ありがとうございました。

    キャンセル

  • 2016/10/26 18:09

    estimatedHeightForRowAtIndexPathを実装するとどうなるでしょうか?(回答に追記しました)

    キャンセル

  • 2016/10/26 18:21

    実装した結果をスクリーンショットとして掲載しました。
    アコーディオンのようになってくれればそれがベストなんですけどね。

    キャンセル

  • 2016/10/26 18:22

    質問内のソースコードも最新のものに書き換えました。

    キャンセル

  • 2016/10/26 19:07

    だいぶ惜しい感じにはなっています。
    あと下の線とラベル(ご来店ありがとう〜)が消えればいい感じにはなりそうです。。。

    キャンセル

  • 2016/10/26 19:12 編集

    あー、ラベルは上下二段になっているんですね。
    ラベルは一つだけだと思っていて、閉じる:一行目だけ表示、開く:全行表示、かと思っていました。

    どちらのラベルも行数は可変なんでしょうか?
    だとすると、真面目に計算するしかないですね。

    キャンセル

  • 2016/10/26 21:34

    ちょっと思い付いただけですが、「下の線」のY座標を高さにすればいいんじゃないでしょうか?

    キャンセル

  • 2016/10/27 10:16 編集

    >fuzzball様
    >どちらのラベルも行数は可変なんでしょうか?
    どちらのラベルも可変になります。

    >「下の線」のY座標を高さにすればいいんじゃないでしょうか?
    "viewDidLayoutSubviews()"の中でタグからUIViewを指定して
    高さを取ろうとしたところ、"signal SIGABRT"になってしまいました。

    →自分の書き方が間違っていました。
    上のUILabelが小さくなり、バーは消えないですね。。

    キャンセル

  • 2016/10/27 10:29

    一晩(夢の中で)考え抜いた結論を回答に追記しました。

    キャンセル

  • 2016/10/27 10:39 編集

    ありがとうございます。
    × よろしければ"msgTop"などの宣言も拝見できないでしょうか。。。

    上記解決しました。

    キャンセル

  • 2016/10/27 10:53

    おぉ。
    思っていた動作になりました。
    長い間解決にご尽力いただき本当に感謝です。

    キャンセル

  • 2016/10/27 11:04

    自動計算(UITableViewAutomaticDimension)を試したのは初めてなので、私も勉強になりました。

    キャンセル

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

  • Swift

    8540questions

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

  • Swift 2

    1337questions

    Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。