1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UITableViewをUIScrollView + UIStackViewに置き換える

Last updated at Posted at 2019-10-21

UITableViewにCustomCellゴテゴテで実装された画面を、UIScrollViewに置き換える機会がありましたので共有します。
主にUIStackViewへの追加で制約が入らなくてつまりました。

※UITableViewCellをそのまま使う前提で書いてます。
普通にViewを置く場合はもっと簡単にできると思います。

前説

まずUITableViewCellってコードから生成できるの…?

というところから始まりました。
途中、
制約全然効いてくれない!!
セルの高さが全部同じになっちゃう!!
横幅がおかしくなる!!!

とか色々やりながら、結果生まれたのが以下のコードです。

その結果生まれたのが以下のコードです。

コードとストーリーボードの例

ViewController.swift
import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var stack: UIStackView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let row = 20
        for i in 0...row {
            let cell = Cell.init(style: .default, reuseIdentifier: "Cell", widht: self.stack.frame.width)
            cell.heightAnchor.constraint(equalToConstant: cell.frame.height).isActive = true
            cell.hogeLabel.text = "\(i)"
            print("add to stack:\(cell)")
            self.stack.addArrangedSubview(cell)
        }
    }
}
Cell.swift
import UIKit

class Cell:UITableViewCell {
    // セルにはラベル1つだけおいてある
    @IBOutlet weak var hogeLabel: UILabel!
    
    // ストーリーボードで配置した時の初期化処理※ストーリーボードからの初期化は想定してません
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.nibInit(width: 0.0)
    }
    
    // 横幅を受け取って初期化する(制約がうまく効かなかったので)
    init(style: UITableViewCell.CellStyle, reuseIdentifier: String?, widht:CGFloat) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.nibInit(width: widht)
    }
    
    // viewの初期化
    fileprivate func nibInit(width: CGFloat) {
        guard let view = UINib(nibName: "Cell", bundle: nil)
            .instantiate(withOwner: self, options: nil)
            .first as? UIView else { return }
        
        //セルの高さはセル側でランダムに決める※使うときはちゃんとConstとか作って高さ設定してね
        let height = Bool.random() ? 50:100
        
        view.frame = CGRect(x: 0, y: 0, width: width, height: CGFloat(height))
        self.frame = CGRect(x: 0, y: 0, width: width, height: CGFloat(height))
        self.addSubview(view)
    }
}

ストーリーボードは特に特別な設定はしておりません。
普通にScrollViewをおいて中にStackViewを配置するだけです。
スクリーンショット 2019-10-21 21.24.23.png

スクロールビューについては(多分)いちばんシンプルなUIScrollViewの実装を見てみてください。


**もっとこんな方法あるよ!!**や、
**ここちょっとやばいよ!!**などございましたらお教えいただけますと幸いです。

ありがとうございました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?