KAinone
@KAinone

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

コードのみでCustomCellに追加したUIButtonが押下できない

解決したいこと

CustomCell に設置した UIButton を押下して画面遷移させたいです。

詳細は、WelcomeViewCell に SignInButton と SignUpButton を設置し、2つのボタンには WelcomeViewCell の追加先である WelcomeViewController に委任した WelcomeViewDelegate のメソッドを addTarget で追加し機能するようにしました。

しかし、実際シミュレーターで確認してみると、レイアウトは出来ているのに、どちらのボタンも全く動かず画面遷移もしません。UIView の階層の問題で UIButton の上に別の層がある説や、アクションの委任の仕方が間違ってる説を疑いましたが、調べても分かりませんでした。原因と解決方法が分かる方がいらっしゃいましたらお教えください。

該当するソースコード

CustomCell

import UIKit
import SnapKit


protocol WelcomeViewCellDelegate {
    
    func signInButtonDelegate()
    func signUpButtonDelegate()
}


class WelcomeViewCell: UITableViewCell {

    
    var welcomeViewCellDelegate: WelcomeViewCellDelegate? = nil
    
    let logoImageView = UIImageView(image: UIImage(named: "logo"))
    let titleLabel = UILabel()
    let signInButton = UIButton()
    let signUpButton = UIButton()
    
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        setupSubviews()
        
        signInButton.addTarget(self, action: #selector(hundleSignInButton(_:)), for: .touchUpInside)
        signUpButton.addTarget(self, action: #selector(hundleSignUpButton(_:)), for: .touchUpInside)
    }
    
    
    required init?(coder: NSCoder) {
        
        fatalError("init(coder:) has not been implemented")
    }
    
   
    override func layoutSubviews() {
        
        super.layoutSubviews()
        
        self.backgroundColor = .clear
        
        logoImageView.backgroundColor = .clear
        logoImageView.contentMode = .scaleAspectFill
        
        titleLabel.text = "Welcome!"
        titleLabel.font = UIFont(name: "Chalkduster", size: 50)
        titleLabel.adjustsFontSizeToFitWidth = true
        titleLabel.textColor = .cyan
        titleLabel.backgroundColor = .clear
        titleLabel.textAlignment = .center
        titleLabel.numberOfLines = 1
        
        signInButton.setTitle("サインイン", for: .normal)
        signInButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
        signInButton.titleLabel?.adjustsFontSizeToFitWidth = true
        signInButton.backgroundColor = UIColor(hex: "FF77FF")
        signInButton.layer.borderWidth = 2
        signInButton.layer.borderColor = UIColor(hex: "FF77FF").cgColor
        signInButton.layer.cornerRadius = signInButton.frame.height / 2
        signInButton.layer.masksToBounds = true
        
        signUpButton.setTitle("サインアップ", for: .normal)
        signUpButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
        signUpButton.titleLabel?.adjustsFontSizeToFitWidth = true
        signUpButton.setTitleColor(UIColor(hex: "FF77FF"), for: .normal)
        signUpButton.backgroundColor = .clear
        signUpButton.layer.borderWidth = 2
        signUpButton.layer.borderColor = UIColor(hex: "FF77FF").cgColor
        signUpButton.layer.cornerRadius = signUpButton.frame.height / 2
        signUpButton.layer.masksToBounds = true
    }
    
    
    func setupSubviews() {
        
        addSubview(logoImageView)
        addSubview(titleLabel)
        addSubview(signInButton)
        addSubview(signUpButton)
        
        logoImageView.snp.makeConstraints {

            $0.size.equalTo(contentView.snp.width).multipliedBy(0.3)
            $0.centerX.equalToSuperview()
            $0.top.equalToSuperview().offset(contentView.frame.width * 0.35)
        }
        
        titleLabel.snp.makeConstraints {
            
            $0.width.equalToSuperview().multipliedBy(0.8)
            $0.height.equalTo(contentView.snp.width).multipliedBy(0.2)
            $0.centerX.equalToSuperview()
            $0.top.equalTo(logoImageView.snp.bottom).offset(contentView.frame.width * 0.2)
        }
        
        signInButton.snp.makeConstraints {
            
            $0.width.equalToSuperview().multipliedBy(0.7)
            $0.height.equalTo(35)
            $0.centerX.equalToSuperview()
            $0.top.equalTo(titleLabel.snp.bottom).offset(contentView.frame.width * 0.4)
        }
        
        signUpButton.snp.makeConstraints {
            
            $0.width.equalTo(signInButton)
            $0.height.equalTo(signInButton)
            $0.centerX.equalToSuperview()
            $0.top.equalTo(signInButton.snp.bottom).offset(15)
        }
        
    }
    
    
    @objc func hundleSignInButton(_ sender: UIButton) {
        
        welcomeViewCellDelegate?.signInButtonDelegate()
    }
    
    
    @objc func hundleSignUpButton(_ sender: UIButton) {
        
        welcomeViewCellDelegate?.signUpButtonDelegate()
    }
    
    
}

ViewContoroller

import UIKit
import SnapKit


class WelcomeViewController: UITableViewController, WelcomeViewCellDelegate {
    
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
        tableView.delaysContentTouches = false
        
        tableView.delegate = self
        tableView.dataSource = self
        
        tableView.register(WelcomeViewCell.self, forCellReuseIdentifier: "welcomeViewCell")
    }
    
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        
        return 1
    }
    
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return 1
    }
    
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "welcomeViewCell") as! WelcomeViewCell
        
        cell.welcomeViewCellDelegate = self
        
        return cell
    }
    
    
    override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
        
        return false
    }
    
    
    func signInButtonDelegate() {
        
        let signInView = SignInViewController()
        self.present(signInView, animated: true, completion: nil)
    }
    
    
    func signUpButtonDelegate() {
        
        let signUpView = SignUpViewController()
        self.present(signUpView, animated: true, completion: nil)
    }
    

}
0

1Answer

XcodeでView Hierarchyを確認してください。セルの高さが正しくない、各ボタンがcontentViewの下にある、が原因です。


以下、本件とは関係ありませんが

  • デリゲートは弱参照で持ってください。循環参照によるメモリリークの原因になります。
protocol WelcomeViewCellDelegate: AnyObject { ... }

weak var delegate: WelcomeViewCellDelegate?
  • 添付するコードはコピペだけで動くようになっていると回答者に優しいです。

0Like

Comments

  1. @KAinone

    Questioner

    お返事遅くなりすみません。
    View Hierarchy で確認し、cell の高さを固定し、contentView に addSubview することで解決しました。
    添付するコードではご迷惑おかけしました。
    また、本件以外のアドバイス大変助かります。
    ありがとうございました!

Your answer might help someone💌