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

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

ただいまの
回答率

88.79%

カスタムセルで作成したボタンを押下出来ない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 155

Ka_ya_

score 29

質問失礼します。

コードのみでテーブルビューを作成したいです。

ボタンのあるカスタムセルクラスを使用したいのですが、
下記の様に記載したところ、ボタンを押下しても反応がありません。

これは何が原因なのでしょうか。

どなたかご教授いただけますと嬉しいです。
よろしくお願い致します。

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    //スクリーンサイズ
    var screenSize = CGSize()

    ///背景画像
    let imageView :UIImageView = {

        let image:UIImage = UIImage(named:"noimage")!
        let iv = UIImageView(image:image)
        iv.contentMode = .scaleAspectFill
        iv.frame = UIScreen.main.bounds
        return iv
    }()

    ///テーブルビュー
    let tableView :UITableView = {

        let tv = UITableView()
        tv.backgroundColor = .clear
        tv.separatorStyle = .none
        //カスタムセルを登録する
        tv.register(CustomCell.self, forCellReuseIdentifier: "customCell")
        tv.translatesAutoresizingMaskIntoConstraints = false
        return tv
    }()

    //ヘッダー
    var headerView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        //スクリーンサイズの取得
        screenSize = self.view.frame.size

        //背景画像の設定
        self.view.addSubview(imageView)

        //ヘッダービューを設定
        headerView.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height / 6)
        headerView.backgroundColor = UIColor(red: 88 / 255, green: 0 / 255, blue: 88 / 255, alpha: 1.0)
        view.addSubview(headerView)

        //テーブルビューを設定
        view.addSubview(tableView)

        tableView.topAnchor.constraint(equalTo: headerView.bottomAnchor).isActive = true
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        tableView.delegate = self
        tableView.dataSource = self
    }

    //セルの個数
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }

    //セルの高さ
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return (screenSize.height - headerView.frame.size.height) / 8
    }

    //セルの設定
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        ///カスタムセルを使用する
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomCell

        return cell
    }
}
import UIKit

class CustomCell: UITableViewCell {

    ///セル背景画像
    let bgImageView :UIImageView = {

        let image:UIImage = UIImage(named:"noimage")!
        let iv = UIImageView(image:image)
        iv.backgroundColor = .clear
        iv.translatesAutoresizingMaskIntoConstraints = false
        return iv
    }()

    ///コメントラベル
    let commentLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 18)
        label.textColor = UIColor.black
        label.textAlignment = .center
        label.text = "テスト"
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    ///ボタン・ラベル格納用スタックビュー
    let stackView :UIStackView = {
        let sv: UIStackView = UIStackView()
        sv.distribution = .equalSpacing
        sv.axis = .horizontal
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()

    //ボタン
    var button :UIButton = {
        let btn = UIButton()
        btn.backgroundColor = .red
        btn.translatesAutoresizingMaskIntoConstraints = false
        btn.addTarget(self, action: #selector(CustomCell.tap(_:)), for: .touchUpInside)
        return btn
    }()

    ///ラベル
    let label: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 12)
        label.textColor = UIColor.black
        label.textAlignment = .center
        label.adjustsFontSizeToFitWidth = true
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = "テスト"
        return label
    }()

    //ここにUI部品を追加していく
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        //背景の設定
        addSubview(bgImageView)

        bgImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        bgImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        bgImageView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        bgImageView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true

        //コメントの設定
        addSubview(commentLabel)

        commentLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
        commentLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        commentLabel.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        commentLabel.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.25).isActive = true

        //スタックビュー
        addSubview(stackView)

        stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        stackView.topAnchor.constraint(equalTo: commentLabel.bottomAnchor, constant: 10).isActive = true
        stackView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.6).isActive = true
        stackView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/3).isActive = true

        //ボタンの設定
        stackView.addArrangedSubview(button)

        button.widthAnchor.constraint(equalTo: stackView.heightAnchor).isActive = true
        button.heightAnchor.constraint(equalTo: stackView.heightAnchor).isActive = true

        //ラベルの設定
        stackView.addArrangedSubview(label)

        label.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 0.2).isActive = true
        label.heightAnchor.constraint(equalTo: stackView.heightAnchor).isActive = true
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    //押下時の挙動
    @objc func tap(_ sender: Any) {
//ボタンを押下してもプリントされない
        print("タップ")
    }
}

イメージ説明

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

初期化クロージャ(Initialization closure)の中ではselfは使えません(未定のため)。

なので、

    var button :UIButton = {
        let btn = UIButton()
        btn.backgroundColor = .red
        btn.translatesAutoresizingMaskIntoConstraints = false
//        btn.addTarget(self, action: #selector(CustomCell.tap(_:)), for: .touchUpInside)

        return btn
    }()

という具合にコメントアウトなり削除するなりしたあと、イニシャライザの中で

        button.widthAnchor.constraint(equalTo: stackView.heightAnchor).isActive = true
        button.heightAnchor.constraint(equalTo: stackView.heightAnchor).isActive = true
        button.addTarget(self, action: #selector(CustomCell.tap(_:)), for: .touchUpInside)

という感じでターゲットを追加したら想定通りに動くかと思います。

あるいは、lazy キーワードを使う方法もあるかと思います(遅延評価させる)。

    lazy var button :UIButton = {
        let btn = UIButton()
        btn.backgroundColor = .red
        btn.translatesAutoresizingMaskIntoConstraints = false
        btn.addTarget(self, action: #selector(CustomCell.tap(_:)), for: .touchUpInside)

        return btn
    }()

この場合はイニシャライザで addTargetする必要はありません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/08/01 19:34

    TsukubaDepotさん、いつもご回答ありがとうございます。

    初期化クロージャの中ではselfが使用出来ないのですね…!
    lazyの使用方法も記載いただき、とても勉強になります。
    お陰様で、無事にボタンを押下出来る様になりました^^

    丁寧にご回答いただき、本当にありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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