公開中のアプリ

[Swift/Xcode]初心者必見!iOSアプリ作成から公開まで徹底解説!#20「カスタムセルをコードだけで実装編」

テーブルビューのセルをカスタマイズするにはUITableViewCellを使います!

今回は、下記画像のようにアイコンとテキストを横並びでセルを作りたいと思います!


動作環境は下記の通りです!
Xcode Version 12.5 Swift version 5.4

まずはアイコン画像の用意

先にアイコン画像を用意しましょう!

今回はフリー素材を使用させていただきました!
同じ画像を使いたい場合は下記からダウンロードして下さいね〜!

アラーム
使い方
シェア
評価
データリセット

ダウンロードしたらレティーナディスプレイ用にサイズを3パターン作ります!
僕の場合ですが、今回ダウンロードしたサイズが256pxなので下記のように3ファイル作ります。

例)アラーム
サイズ:256px ファイル名:menuIcon-1@3x.png
サイズ:170px ファイル名:menuIcon-1@2x.png
サイズ:85px ファイル名:menuIcon-1.png

全てのアイコンで3サイズ作ったらAssets.xcassetsフォルダにドロップ&ドラッグします!

こうする事で、レティーナディスプレイの場合も「menuIcon-1」と言うファイル名で使い分ができるようになります!

実装の流れ

カスタムセルを作ると言ってもピンとこないと思うので簡単に説明したいと思います。

デフォルトのセルを使う場合、下記画像のようにテキストを入れる事しかできません。
右端の > はコードで簡単に付けれます。

このセルを冒頭の画像のようにレイアウトするにはカスタマイズしなければいけません。

実装の流れとしては、カスタマイズセル用のファイルを作成して、そこでアイコンとかテキストを配置してレイアウトしちゃいます。

そのファイルを既に作成済みのテーブルビューと紐付けて、使用すればOKです!

要するに赤枠部分だけ好きにレイアウト実装して、それをテーブルにはめてる感じです!

ではやっていきましょう!

MenuTableViewCell.swiftの作成

まずはカスタムテーブル用に新しいファイルを作成しましょう。

Cocoa Touch ClassでSubclassをUITableViewCellにして
ファイル名をMenuTableViewCell.swiftにして下さい!

わからない場合こちらの記事をご覧下さい〜

カスタムセルの作成

作成したMenuTableViewCell.swiftには下記コードを書きます。

import UIKit

class MenuTableViewCell: UITableViewCell {

//Commonクラスのインスタンス生成
let common = Common()

//左側のアイコン
let menuIcon: UIImageView = {
    let ImageView = UIImageView()
    ImageView.translatesAutoresizingMaskIntoConstraints = false
    return ImageView
}()
//右側のラベル
let itemName: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

//レイアウト
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: .subtitle, reuseIdentifier: reuseIdentifier )
    //アイコンとラベルを表示
    addSubview(itemName)
    addSubview(menuIcon)
    //アイコンの設定
    menuIcon.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20).isActive = true
    menuIcon.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    menuIcon.topAnchor.constraint(equalTo: self.topAnchor, constant: 20).isActive = true
    menuIcon.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.09).isActive = true
    menuIcon.heightAnchor.constraint(equalTo: menuIcon.widthAnchor, multiplier: 1).isActive = true
    //ラベルの設定
    itemName.textColor =  UIColor(hex: self.common.text, alpha: 1)
    itemName.font = UIFont(name: "HiraMaruProN-W4", size: 17)
    itemName.leftAnchor.constraint(equalTo: menuIcon.rightAnchor, constant: 20).isActive = true
    itemName.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
}
    
//セルにテキストと画像の名前を設定
func setCell(item: String, iconName: String) {
    itemName.text = item
    menuIcon.image = UIImage(named: iconName)
}
    
required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
    
override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}
}

コードの説明はコメントに書いてあるので大体わかると思います!

テーブルビューの編集

あとはテーブルビュー側を修正すればカスタムセルが使えるようになります!
MenuViewController.switに下記コードを追加しましょう!

追加する場所がわからない場合は記事の最後にコード全部載せてるので確認して下さい!

まずはアイコンのファイル名を配列に格納します!

let icons = ["menuIcon-1", "menuIcon-2", "menuIcon-3", "menuIcon-4", "menuIcon-5"]

次にテーブルビューの設定の中に下記コードを追加します!

tableView.register(MenuTableViewCell.self, forCellReuseIdentifier: "Cell")

最後にセルの設定を下記コードのように修正します!

//セルの設定
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //カスタムをセルを使えるように設定
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! MenuTableViewCell
    //ラベルのテキストとアイコン画像のファイル名を設定
    cell.setCell(item: self.items[indexPath.row], iconName: icons[indexPath.row])
    //セルの右側に<を付ける
    cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
    //セル選択時に背景色を変更しない
    cell.selectionStyle = UITableViewCell.SelectionStyle.none
    return cell
}

ちなみに6行目のsetCellメソッドはMenuTableViewCell.swiftに書いた、41行目~44行目のメソッドです!

4行目でMenuTableViewCellを使えるようにしてるので、このメソッドの中では、MenuTableViewCell.swiftの変数やメソッドを使えるようになります!

ここでもしエラーが出ても一回ビルドしてみて下さい!
たまにあるんですけど、何も変更してないのにビルドしたら解決する場合があります!


あってるはずやのにな〜って永遠ググっても解決しません。
間違ってないですからね(^^;

エラーが出たらググる前に一回ビルドする事をお勧めします!

問題なく表示されましたでしょうか??

まとめ

カスタムセルどうでしたか??
いつもStoryboardで実装してましたがコードでも簡単ですね!

使い回しもしやすいしStoryboardいらんな(^^;

てかもうSwiftUIか〜

明日は大谷さんのホームラン競争!!
多分優勝すると思うけど、何より怪我なく終えて欲しいですね!

編集したファイルのコード全部

MenuViewController.swift

import UIKit

class MenuViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    

//Commonクラスのインスタンス生成
let common = Common()
//Cancelボタン
var cancelBtn: UIBarButtonItem!
//テーブルビューの変数
var tableView: UITableView?
//セル用の配列
let items = ["貯金忘れ防止アラーム", "使い方", "シェア", "評価", "データリセット"]
let icons = ["menuIcon-1", "menuIcon-2", "menuIcon-3", "menuIcon-4", "menuIcon-5"]
    
override func viewDidLoad() {
    super.viewDidLoad()

//ナビゲーションコントローラーまわり
//タイトル
self.title = "メニュー"
//背景色
self.navigationController?.navigationBar.barTintColor = UIColor(hex: self.common.main , alpha: 1)
//セーフエリアとの境目の線を消す
self.navigationController?.navigationBar.shadowImage = UIImage()
//フォントの設定
self.navigationController?.navigationBar.titleTextAttributes
    = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: "HiraMaruProN-W4", size: 20)!]
//Cancelボタンを追加
cancelBtn = UIBarButtonItem(title: "Cancel", style: .done, target: self, action: #selector(self.cancelBtnTapped))
cancelBtn.tintColor = UIColor(hex: self.common.white , alpha: 1)
self.navigationItem.leftBarButtonItem = cancelBtn
    
//テーブルビューの設定
self.tableView = {
    let tableView = UITableView(frame: self.view.bounds, style: .plain)
    tableView.autoresizingMask = [
      .flexibleWidth,
      .flexibleHeight
    ]

    tableView.delegate = self
    tableView.dataSource = self

    self.view.addSubview(tableView)

    tableView.register(MenuTableViewCell.self, forCellReuseIdentifier: "Cell")
    
    return tableView

  }()
}

//Cancelボタンのメソッド
@objc func cancelBtnTapped() {
    //前の画面に戻る
    dismiss(animated: true, completion: nil)
}

    
//テーブルビューまわり
//テーブルビューのセクションの数を設定
func numberOfSections(in tableView: UITableView) -> Int {
  return 1
}
//テーブルビューのセルの数を設定
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  //配列itemsの数になるように設定
  return self.items.count
}

//セルの設定
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //カスタムをセルを使えるように設定
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! MenuTableViewCell
    //ラベルのテキストとアイコン画像のファイル名を設定
    cell.setCell(item: self.items[indexPath.row], iconName: icons[indexPath.row])
    //セルの右側に<を付ける
    cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
    //セル選択時に背景色を変更しない
    cell.selectionStyle = UITableViewCell.SelectionStyle.none
    return cell
}
    
//セルを選択した時の設定
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  print("Selected! \(self.items[indexPath.row])")
}
    
}

MenuTableViewCell.swift

import UIKit

class MenuTableViewCell: UITableViewCell {

//Commonクラスのインスタンス生成
let common = Common()

//左側のアイコン
let menuIcon: UIImageView = {
    let ImageView = UIImageView()
    ImageView.translatesAutoresizingMaskIntoConstraints = false
    return ImageView
}()
//右側のラベル
let itemName: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

//レイアウト
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: .subtitle, reuseIdentifier: reuseIdentifier )
    //アイコンとラベルを表示
    addSubview(itemName)
    addSubview(menuIcon)
    //アイコンの設定
    menuIcon.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20).isActive = true
    menuIcon.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    menuIcon.topAnchor.constraint(equalTo: self.topAnchor, constant: 20).isActive = true
    menuIcon.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.09).isActive = true
    menuIcon.heightAnchor.constraint(equalTo: menuIcon.widthAnchor, multiplier: 1).isActive = true
    //ラベルの設定
    itemName.textColor =  UIColor(hex: self.common.text, alpha: 1)
    itemName.font = UIFont(name: "HiraMaruProN-W4", size: 17)
    itemName.leftAnchor.constraint(equalTo: menuIcon.rightAnchor, constant: 20).isActive = true
    itemName.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
}
    
//セルにテキストと画像の名前を設定
func setCell(item: String, iconName: String) {
    itemName.text = item
    menuIcon.image = UIImage(named: iconName)
}
    
required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
    
override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

アプリ