[iOS] UITableViewのCellをコードでカスタマイズする

iOSのアプリを開発する場合、UIを作成するのにXibを使ってグラフィカルにUIを組んでいく場合と、ソースコードで全て記述するパターンと2種類の方法があります。 (SwiftUIを使わないパターンを想定しています。) Xibを使うとグラフィカルにできる一方、Xibファイルが競合する恐れがあります。 ソースコードで全てやる場合は、競合の恐れは少なくなりますが、グラフィカルにできなくなります。 ソースコードでCellをカスタムする場合のポイントをまとめてみます。 ## Cellのカスタム方法 UITableViewCellのサブクラスを作成して、ベースとなるクラスにします。 (今後AutoLayoutでCellを組んだり、XibでCellを組む際のベースクラスにする) サブクラスで作成したViewを自分のcontentViewに使いするメソッドを用意しておきます。 ```objc `gutter:true; // ベースとなるCell /// Common TableViewCell class AppTableViewCell: UITableViewCell { var onSelect: (() -> Void) = { } var isEnabled: Bool = true override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) } required init?(coder: NSCoder) { super.init(coder: coder) //fatalError("init(coder:) has not been implemented") } /// contentViewにViewを追加して、サイズをAutoLayoytでcontentViewのサイズに合わせます。 func addToContentView(_ v: UIView) { self.contentView.addSubview(v) v.setupFitConstraint(to: self.contentView) } override func awakeFromNib() { super.awakeFromNib() } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) } } /// Cellをコードでカスタムする際に実装するプロトコル protocol ICustomCell { /// Cellの高さを返します var cellHeight: CGFloat { get } } ``` あまり意味がありませんが、LabelのみのCellを作成してみます。 ポイントはCellのViewをUIViewで定義してカスタムしているところと、Cellの縦のサイズを指定しています。 ```objc `gutter:true; /// Labelのみのセル class SimpleSelectCell: AppTableViewCell, ICustomCell { var cellHeight: CGFloat = 44.0 let mainView = SimpleSelectCellView() init(title: String, onSelect: @escaping (() -> Void)) { super.init(style: .default, reuseIdentifier: nil) self.addToContentView(mainView) self.onSelect = onSelect self.title = title } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } var title: String { get { mainView.titleLabel.text ?? "" } set { mainView.titleLabel.text = newValue } } } extension SimpleSelectCell { class SimpleSelectCellView: UIView { let titleLabel = UILabel() init() { super.init(frame: CGRect()) setupSubviews() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setupSubviews() { self.addSubview(titleLabel) titleLabel.translatesAutoresizingMaskIntoConstraints = false titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: common.cellmargin).isActive = true titleLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -(common.cellmargin)).isActive = true titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true titleLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true } } } ``` このCellを使うTableViewではCellの高さを指定してあげる必要があります。 StackViewを使ったり、Xibで作成したCellの場合は高さを自動で判定できるので、UITableView.automaticDimensionが使えます。 ```objc `gutter:true; func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let cell = self.tableView(self, cellForRowAt: indexPath) if let cell = cell as? ICustomCell { return cell.cellHeight } return UITableView.automaticDimension } ``` ## 参考URL - [今回のコードはここ](https://github.com/k28/ios-customui-sample)

0 件のコメント :

コメントを投稿