おひとり

できる限りひとりで楽しむための情報やプログラミング情報など。

【Swift 5】ピンチでTableViewのCellの高さを動的に変更する

Googleカレンダーの1日の予定のような、ピンチでTableViewCellの高さを動的に変更する方法を紹介します。

f:id:hitoridehitode:20190617214943g:plain

ピンチでTableViewのCellの高さを動的に変更する

storyboardでUIを作成する。

TableViewを配置

この際、Spacing to nearest neighborを全て0に設定して画面いっぱいに広げておきます。(結果を分かりやすくするためです。)

f:id:hitoridehitode:20190617215351j:plain

TableViewCellを配置

先ほど設定したTableViewにTableViewCellを配置しておきます。
ここでは何か文字が入っていた方が分かりやすいため、Styleをbasicに設定しています。
identifierの設定も忘れずにしておきましょう。ここではTableViewCellとつけて置きました。

Pinch Gesture Recognizerを配置

最後に、Pinch Gesture Recognizerを配置します。 以上で、UIの作成は完了です。

f:id:hitoridehitode:20190617215244j:plain

アシスタントエディタでUIとソースコードをリンク

アシスタントエディタを開き、以下それぞれ行います。

  • TableViewの@IBOutletを作成
  • Pinch Gesture RecognizerのUIPinchGestureRecognizerの@IBActionを作成

ここでは、TableViewはtableViewとして、UIPinchGestureRecognizerはdidPinch()としてそれぞれ作成しました。

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func didPinch(_ sender: UIPinchGestureRecognizer) {
    }
    
}

ViewControllerのコーディング

import UIKit

class ViewController: UIViewController {
    var pinchScale: CGFloat?
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
    }

    @IBAction func didPinch(_ sender: UIPinchGestureRecognizer) {
        // ピンチスケールを取得
        pinchScale = sender.scale
        
        // TableViewを再描画させる
        tableView.reloadData()
    }
    
}

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        // ピンチスケールにしたがってCellの高さを調整
        let defaultCellHeight = CGFloat(50)
        guard let scale = pinchScale else {
            return defaultCellHeight
        }
        return defaultCellHeight * scale
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 50
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath)
    }
    
    
}

didPinch()によりピンチのスケールを取得します。
このスケールを利用し、tableView()のcellForRowAtの関数にてCellの高さを動的に計算しています。
こうすることで、ピンチに応じて動的にCellの高さを変更することができます。

※シミュレーターでピンチを再現するには、Optionキーを押下しながらシミュレーターの画面をドラッグします。

サンプルアプリ

サンプルのアプリはGithubで公開しています。

github.com

f:id:hitoridehitode:20190616162725j:plain