Chris
Chris

Reputation: 2314

Swift - custom UITableViewCell programmatically

I am having troubles customizing my cells inside my UITableView. I would like to have a UIButton on the left but somehow the UIButton only appears inside the first cell:

enter image description here

This is how I create the UIButton inside my UITableViewCell:

class WhishCell: UITableViewCell {

let checkButton: UIButton =  {
    let v = UIButton()
    v.backgroundColor = .red
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()



public static let reuseID = "WhishCell"

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

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    self.addSubview(checkButton)
    self.backgroundColor = .clear

}
}

My TableView:

class WhishlistTableViewController: UITableViewController {

public var wishList = [Wish]()


override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.allowsSelection = false
    self.tableView.register(WhishCell.self, forCellReuseIdentifier: WhishCell.reuseID)
    self.wishList.append(Wish(withWishName: "Test"))

}

// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return wishList.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: WhishCell.reuseID, for: indexPath)
    let currentWish = self.wishList[indexPath.row]
    cell.textLabel?.text = currentWish.wishName
    cell.backgroundColor = .clear

    return cell
}

Does anyone know why it only appears only on the first cell?? Kind of new to TableViews so I'm happy with every help :)

Upvotes: 0

Views: 2356

Answers (3)

gvizeu
gvizeu

Reputation: 59

You should add constrains to the UIButton because the parent view needs to know where the button must be. Also if the view has other components inside, you have to declare that instead.

In conclusion, you have to tell to the component that you want to add witch components have around.

Try with this

self.addConstraint(NSLayoutConstraint(item: checkButton, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1, constant: 10))
self.addConstraint(NSLayoutConstraint(item: checkButton, attribute: .trailing, relatedBy: .equal, toItem: textLabel, attribute: .trailing, multiplier: 1, constant: 10))
self.addConstraint(NSLayoutConstraint(item: checkButton, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 10))
self.addConstraint(NSLayoutConstraint(item: checkButton, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 10))

Upvotes: 0

creeperspeak
creeperspeak

Reputation: 5521

As others are suggesting the reason for this is that you are never defining layout constraints for your button. Here is a sample update to your init to include the layout, though there are many ways you could do this.

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
  super.init(style: style, reuseIdentifier: reuseIdentifier)
  self.addSubview(checkButton)
  self.checkButton.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20).isActive = true
  self.checkButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
  self.checkButton.widthAnchor.constraint(equalToConstant: 40).isActive = true
  self.checkButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
  self.backgroundColor = .clear
}

Of course I'm just making up constraints here, but this would achieve what you are looking for.

Upvotes: 1

Gaurav Parvadiya
Gaurav Parvadiya

Reputation: 149

UIButton is subclass of UIView so initialization of UIbutton requires frame or constraints to specify it's position. Try applying constraints to checkButton will solve your issue.

Upvotes: 1

Related Questions