UITableViewCell textLabel not covering the full width of the cell - swift

I tried all the popular suggestions like:
tableView.cellLayoutMarginsFollowReadableWidth = false
tableView.contentInset = .zero
tableView.separatorInset = .zero
but still im getting some spacing between the textlabel and the parent cell like below:
Cell creation code is shown below:
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = eligibleArray[indexPath.row]
cell.layoutMargins = .zero
cell.separatorInset = .zero
cell.textLabel?.textColor = .secondaryLabel
cell.textLabel?.backgroundColor = .systemOrange
cell.textLabel?.numberOfLines = 0
cell.backgroundColor = .systemPink
Please help with suggestions

This is the max that you can do with default textLabel cell:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
if (cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins))) {
cell.preservesSuperviewLayoutMargins = false
}
if (cell.responds(to: #selector(setter: UIView.layoutMargins))) {
cell.layoutMargins = UIEdgeInsets.zero
}
if tableView.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
tableView.separatorInset = .zero
}
}
and this is the result
otherwise you can create a custom cell to have total control:
class YourController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(YourCell.self, forCellReuseIdentifier: "cellId")
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
tableView.topAnchor.constraint(equalTo: view.topAnchor).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
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! YourCell
cell.myLabel.text = "System will compute elegibility based on the current LTV of the loanscheme selected"
cell.myLabel.numberOfLines = 0
cell.myLabel.backgroundColor = .orange
cell.backgroundColor = .systemPink
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
your cell:
class YourCell: UITableViewCell {
let myLabel: UILabel = {
let l = UILabel()
l.backgroundColor = .orange
l.textColor = .black
l.numberOfLines = 0
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(myLabel)
myLabel.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
myLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
myLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
myLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
and this is the result

Related

Getting id by clicking on tableView

By clicking on the red area I get a comment id. But I also want to get the id if I click on the blue button. How can I do that?
Right now I use this to detect a tap on a row. But tapping on button should run some other code.
extension FirstTabSecondViewComment: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
FirstTabSecondViewComment.subComment = table[indexPath.row].commentId ?? ""
print(FirstTabSecondViewComment.subComment)
self.performSegue(withIdentifier: "CommentDetail", sender: Any?.self)
}
}
After you have register your custom cell declare it in cellForRowAt and add target in button cell:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! MyCell // your custom cell
// add target in buoon cell
cell.YourButtonCell.addTarget(self, action: #selector(submit(_:)), for: .touchUpInside)
return cell
}
after that add submit func:
#objc fileprivate func submit(_ sender: UIButton) {
var superview = sender.superview
while let view = superview, !(view is UITableViewCell) {
superview = view.superview
}
guard let cell = superview as? UITableViewCell else {
print("button is not contained in a table view cell")
return
}
guard let indexPath = tableView.indexPath(for: cell) else {
print("failed to get index path for cell containing button")
return
}
// We've got the index path for the cell that contains the button, now do something with it.
print("button is in index \(indexPath.row)")
}
This is a full code example, copy and paste in a new project and run:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.register(MyCell.self, forCellReuseIdentifier: cellId)
}
#objc fileprivate func submit(_ sender: UIButton) {
var superview = sender.superview
while let view = superview, !(view is UITableViewCell) {
superview = view.superview
}
guard let cell = superview as? UITableViewCell else {
print("button is not contained in a table view cell")
return
}
guard let indexPath = tableView.indexPath(for: cell) else {
print("failed to get index path for cell containing button")
return
}
// We've got the index path for the cell that contains the button, now do something with it.
print("button is in index \(indexPath.row)")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyCell
// add target in buoon cell
cell.cancelButton.addTarget(self, action: #selector(submit(_:)), for: .touchUpInside)
return cell
}
}
class MyCell: UITableViewCell {
let cancelButton: UIButton = {
let b = UIButton(type: .system)
b.backgroundColor = .white
b.setTitle("get Index", for: .normal)
b.layer.cornerRadius = 10
b.clipsToBounds = true
b.titleLabel?.font = .systemFont(ofSize: 16, weight: .semibold)
b.tintColor = .black
b.translatesAutoresizingMaskIntoConstraints = false
return b
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .darkGray
contentView.addSubview(cancelButton)
cancelButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
cancelButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
cancelButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
cancelButton.widthAnchor.constraint(equalToConstant: 300).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

Add button to uitableview cell programmatically

I just want my code to produce a button in every table view cell that has text. When the button is press just have it say hi. Each cell should have a button in it. I want this to be done all and code and do not use the storyboard at all. The class should remain a uiview controller and not be changed.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private let myArray: NSArray = ["First","Second","Third"]
var myTableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
myTableView.dataSource = self
myTableView.delegate = self
self.view.addSubview(myTableView)
myTableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
myTableView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.90),
myTableView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1),
myTableView.topAnchor.constraint(equalTo: view.topAnchor),
myTableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
])
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Num: \(indexPath.row)")
print("Value: \(myArray[indexPath.row])")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
cell.textLabel!.text = "\(myArray[indexPath.row])"
return cell
}
}
Create a subclass of UITableViewcell -
class MyCell: UITableViewCell {
var buttonTapCallback: () -> () = { }
let button: UIButton = {
let btn = UIButton()
btn.setTitle("Button", for: .normal)
btn.backgroundColor = .systemPink
btn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
return btn
}()
let label: UILabel = {
let lbl = UILabel()
lbl.font = UIFont.systemFont(ofSize: 16)
lbl.textColor = .systemPink
return lbl
}()
#objc func didTapButton() {
buttonTapCallback()
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
//Add button
contentView.addSubview(button)
button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
//Set constraints as per your requirements
button.translatesAutoresizingMaskIntoConstraints = false
button.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
button.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
button.widthAnchor.constraint(equalToConstant: 100).isActive = true
button.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
//Add label
contentView.addSubview(label)
//Set constraints as per your requirements
label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: button.trailingAnchor, constant: 20).isActive = true
label.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Now in your view controller register this cell -
myTableView.register(MyCell.self, forCellReuseIdentifier: "MyCell")
Now load this cell using cellForRowAt method -
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
cell.label.text = ""
cell.buttonTapCallback = {
cell.label.text = "Hi"
}
return cell
}
You could add a UIButton to UITableViewCell by just adding it in the cellForRow method, like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
let button = UIButton()
button.setTitle("\(myArray[indexPath.row])", for: .normal)
button.center = cell.center
cell.addSubview(button)
return cell
}
Although the above method works, it is not recommended. You should probably create a custom class for UITableViewCell and use it as your cell, like this:
class MyCustomCell: UITableViewCell {
let button = UIButton()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(button)
// do layout setup here
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Usage:
override func viewDidLoad() {
super.viewDidLoad()
myTableView.register(MyCustomCell.self, forCellReuseIdentifier: "MyCell")
//...
}
//...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCustomCell
cell.button.setTitle("\(myArray[indexPath.row])", for: .normal)
return cell
}

How to add multiple items to a UITableViewCell?

Can anyone help me get the email field to display in the tableView cell? The amount field is showing up, but I can't get the email to show along with it.
struct Posts {
var amount:String
var email:String
}
class PaymentRequestVC: UIViewController, UITableViewDelegate {
let tableView = UITableView()
var posts = [Posts]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.tableView.dataSource = self
self.tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell2")
tableView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 900)
setupViews()
setupTableView()
loadPosts()
self.tableView.reloadData()
}
func loadPosts() {
let dbUsers = Firestore.firestore().collection("Payouts")
dbUsers.addSnapshotListener { (querySnapshot, error) in
if let error = error {
print("\(error.localizedDescription)")
} else {
for document in (querySnapshot?.documents)! {
if let Amount = document.data()["amount"] as? String {
let Email = document.data()["email"] as? String
print(Amount)
var post = Posts(amount: "", email: "")
post.amount = Amount
post.email = Email ?? ""
self.posts.append(post)
}
}
self.tableView.reloadData()
print(self.posts)
}
}
}
private func setupViews() {
let stackView: UIStackView = {
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.spacing = 28
sv.axis = .vertical
sv.distribution = .fill
sv.alignment = .fill
return sv
}()
view.addSubview(stackView)
view.addSubview(tableView)
}
func setupTableView() {
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: self.view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor)
])
}
}
extension PaymentRequestVC: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath)
let post = posts[indexPath.row]
cell2.detailTextLabel?.text = post.email
cell2.detailTextLabel?.textColor = UIColor.black
return cell2
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
}
Swift 5
You need to init the cell with UITableViewCell.CellStyle.subtitle for the detailTextLabel attribute to work.
In your extension, change the cell init:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.text = post.email
cell.detailTextLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell2")
let post = posts[indexPath.row]
cell2.detailTextLabel?.text = post.email
cell2.detailTextLabel?.textColor = UIColor.black
return cell2
}
Note that if you want the amount and the mail to both show up, using else will only display either the amount or the email, like in the code below
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell2")
let post = posts[indexPath.row]
cell2.detailTextLabel?.text = post.email
cell2.detailTextLabel?.textColor = UIColor.black
return cell2
}
So a better approach would be to return both, and else display nothing
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.text = post.email
cell.detailTextLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell2")
//Empty cell returned if the condition above is not fulfilled
return cell2
}
Hope this helps.
I think your logic in cellForRowAt is incorrect.
You have an array of Posts. And you want to display amount and email in the same cell right? One label being the title and the other being the detailed text.
Both labels are in the same UITableViewCell, so you only need to set it up once per post.
In addition, if indexPath.row is greater than the post count, then posts[indexPath.row] would actually crash your code. So that else statement should actually just log an error or simply do nothing.
Try something like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
cell.textLabel?.detailTextLabel?.text = post.email
cell.textLabel?.detailTextLabel?.textColor = UIColor.black
return cell
} else {
// No cells
}
}

Multiple UITableViewCell problem in displaying

I'm new in autolayout programmatically, and I have a problem with displaying 2 different cells in UITableView as below:
The first cell I want to show profiles picture and the username, then the menu options. But as screenshot the second section menu option is displaying behind the first section (user profile picture and username).
How to solve this problem?
UserTableViewCell:
class UserTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
layoutUI()
backgroundColor = .CustomGreen()
selectionStyle = .none
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var containerView: UIView = {
let containerView = UIView()
containerView.backgroundColor = .clear
containerView.translatesAutoresizingMaskIntoConstraints = false
return containerView
}()
lazy var userPhoto: UIImageView = {
let userPhoto = UIImageView()
userPhoto.translatesAutoresizingMaskIntoConstraints = false
userPhoto.layer.cornerRadius = userPhoto.frame.size.width / 2
userPhoto.clipsToBounds = true
return userPhoto
}()
lazy var username: UILabel = {
let username = UILabel()
username.textColor = .white
username.text = "Ahmed Abd Elaziz"
username.translatesAutoresizingMaskIntoConstraints = false
return username
}()
func setupContainerViewConstraints() {
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: topAnchor),
containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: trailingAnchor)
])
}
func setupUserPhotoConstraints() {
NSLayoutConstraint.activate([
userPhoto.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
userPhoto.widthAnchor.constraint(equalToConstant: frame.width / 3),
userPhoto.heightAnchor.constraint(equalToConstant: frame.width / 3)
])
}
func setupUsernameConstraints() {
NSLayoutConstraint.activate([
username.topAnchor.constraint(lessThanOrEqualTo: userPhoto.bottomAnchor, constant: 16),
username.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
])
}
func addSubviews() {
addSubview(containerView)
containerView.addSubview(userPhoto)
containerView.addSubview(username)
}
func layoutUI() {
addSubviews()
setupContainerViewConstraints()
setupUserPhotoConstraints()
setupUsernameConstraints()
}
}
SideMenuOptionTableViewCell:
class SideMenuOptionTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
layoutUI()
backgroundColor = .CustomGreen()
selectionStyle = .none
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var containerView: UIView = {
let containerView = UIView()
containerView.backgroundColor = .clear
containerView.translatesAutoresizingMaskIntoConstraints = false
return containerView
}()
lazy var viewTitle: UILabel = {
let viewTitle = UILabel()
viewTitle.font = UIFont(name: "AvenirNext-Regular", size: 20)
viewTitle.textColor = .white
viewTitle.numberOfLines = 0
viewTitle.translatesAutoresizingMaskIntoConstraints = false
return viewTitle
}()
func setupContainerViewConstraints() {
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: topAnchor),
containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: trailingAnchor)
])
}
func setupFoodTitle() {
NSLayoutConstraint.activate([
viewTitle.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
viewTitle.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16)
])
}
func addSubview() {
addSubview(containerView)
containerView.addSubview(viewTitle)
}
func layoutUI() {
addSubview()
setupContainerViewConstraints()
setupFoodTitle()
}
}
SideMenuTableViewController:
class SideMenuTableViewController: UITableViewController {
let viewControllers = ["Controller One", "Logout"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UserTableViewCell.self, forCellReuseIdentifier: "UserTableViewCell")
tableView.register(SideMenuOptionTableViewCell.self, forCellReuseIdentifier: "SideMenuOptionTableViewCell")
tableView.reloadData()
tableView.backgroundColor = .CustomGreen()
tableView.separatorStyle = .none
tableView.rowHeight = UITableView.automaticDimension
// tableView.estimatedRowHeight = 100
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return section == 0 ? 1 : viewControllers.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "UserTableViewCell", for: indexPath) as! UserTableViewCell
cell.userPhoto.image = UIImage(named: "ahmed")
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuOptionTableViewCell", for: indexPath) as! SideMenuOptionTableViewCell
cell.viewTitle.text = viewControllers[indexPath.row]
return cell
}
}
}
The problem here is you are adding constraints according to the cells height and all the views are being adjusted in the cell. As the space for the views is too small they are overlapping the views of the next cell. You can fix this problem by increasing the size of the content view of the cell.
Add this line in init of your UserTableViewCell
let minHeight = 70
let minHeightConstraint = contentView.heightAnchor.constraint(greaterThanOrEqualToConstant: minHeight)
minHeightConstraint.priority = UILayoutPriority(rawValue: 999)
minHeightConstraint.isActive = true

Programmatically perform segue to new View Controller from UIbutton within a cell? (without storyboard)

I would like to perform a segue to a new VC by clicking on a UIButton that is found with in a cell (a Users Cell)
class TableViewController: UITableViewController {
var userScreenVC: usersScreenVC?
var HomePageVc: HomePageVC?
var signInVC: SignInVC?
var ref = FIRDatabase.database().reference()
let cellId = "cellId"
var users = [User]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UserCellLargePicture.self, forCellReuseIdentifier: cellId)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCellLargePicture
cell.selectionStyle = .none
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
let user = users[indexPath.row]
cell.ProfileButton.setImage(#imageLiteral(resourceName: "Grape"), for: .normal)
return cell
}//func tableview cellForRowAt
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 234
}
class UserCellLargePicture: UITableViewCell {
var ProfileButton: UIButton = {
let button = UIButton()
//label.text = "TEST TEST TEST"
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
addSubview(ProfileButton)
ProfileButton.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -58).isActive = true
ProfileButton.widthAnchor.constraint(equalToConstant: 54).isActive = true
ProfileButton.heightAnchor.constraint(equalToConstant: 54).isActive = true
ProfileButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant:0).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}