Adjusting UILabels size (i.e., width and height) inside a UITableViewCell Class? - swift

I created a custom UITableViewCell Class as illustrated below, whereby i defined the items I would like to be displayed inside my custom cell (specifically UILabel items):
import UIKit
import ChameleonFramework
class IsectionsCustomTableViewCell: UITableViewCell {
let sectionDesignationLabelTopPadding: CGFloat = 10
let sectionDesignationLabelLeftPadding: CGFloat = 10
let sectionDesignationLabelRightPadding: CGFloat = 10
let depthOfSectionLabelTopPadding: CGFloat = 0
let depthOfSectionLabelLeftPadding: CGFloat = 10
let depthOfSectionLabelRightPadding: CGFloat = 10
let webThicknessLabelTopPadding: CGFloat = 10
let webThicknessLabelLeftPadding: CGFloat = 10
let webThicknessLabelRightPadding: CGFloat = 10
var sectionDesignationLabel: UILabel = {
let label = UILabel()
label.backgroundColor = UIColor.yellow
label.textAlignment = .left
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor(hexString: "#F27E63")
return label
}()
var depthOfSectionLabel: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
label.backgroundColor = UIColor.blue
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor(hexString: "#F27E63")
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(sectionDesignationLabel)
addSubview(depthOfSectionLabel)
applyAppropriateSizeAndConstraintsForCellItems()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func applyAppropriateSizeAndConstraintsForCellItems() {
sectionDesignationLabel.frame.size.width = 200
NSLayoutConstraint.activate([
sectionDesignationLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: sectionDesignationLabelLeftPadding),
sectionDesignationLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -1*sectionDesignationLabelRightPadding),
sectionDesignationLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: sectionDesignationLabelTopPadding),
depthOfSectionLabel.topAnchor.constraint(equalTo: sectionDesignationLabel.bottomAnchor, constant: depthOfSectionLabelTopPadding),
depthOfSectionLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: depthOfSectionLabelLeftPadding),
depthOfSectionLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -1 * (((self.frame.size.width)/2) + depthOfSectionLabelRightPadding)),
])
}
}
As it can be seen from the declaration of depthOfSectionLabel, whereby I stated the width and height of its frame. However, these values are not reflected when my table gets displayed (please refer to attached image). The width is displayed much more greater than the 50 I specified for this specific label?
My question is how can I adjust the widths of the various labels to be displayed inside my tableView custom Cell?

Related

CollectionView Cell Changing Size when screen reloads

I am creating a screen where the user can search for films and the results load in a collection View, everything loads perfectly but in the simulator when I clicked "command, shift, A" to change to light mode to make sure the colours would adapt correctly the Cells randomly changed size to full screen instead of what I have set.
This also happens when I leave the application for the home page and then click back into the app. I am creating everything programmatically so would need answer this way please.
Below is the code from my custom cell:
import UIKit
class FavouritesCell: UICollectionViewCell {
static let identifier = "FavouritesCell"
let movieTitle: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.lineBreakMode = .byWordWrapping
label.textColor = .secondaryLabel
//label.text = "Title"
label.adjustsFontSizeToFitWidth = true
label.textAlignment = .center
label.font = label.font.withSize(12)
label.minimumScaleFactor = 0.75
return label
}()
let image : UIImageView = {
let image = UIImageView()
image.clipsToBounds = true
image.translatesAutoresizingMaskIntoConstraints = false
//image.backgroundColor = .yellow
image.layer.cornerRadius = 10.0
return image
}()
let cancelItem : UILabel = {
let label = UILabel()
label.layer.borderWidth = 2.0
label.layer.borderColor = UIColor.systemGray.cgColor
label.text = "X"
label.textAlignment = .center
label.layer.cornerRadius = 15
//label.isHidden = true
return label
}()
override init(frame: CGRect) {
super.init(frame: .zero)
contentView.addSubview(image)
contentView.addSubview(movieTitle)
contentView.addSubview(cancelItem)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
image.frame = CGRect(x: 0, y: 25, width: contentView.width, height: contentView.height - 30 )
movieTitle.frame = CGRect(x: 0, y: 0, width: contentView.width, height: 25)
cancelItem.frame = CGRect(x: image.right - 25, y: image.top , width: 25, height: 25)
}
}
Here is the code from the view controller in relation to the collectionView:
private let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = 2
layout.minimumInteritemSpacing = 2
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(FavouritesCell.self, forCellWithReuseIdentifier: FavouritesCell.identifier)
collectionView.clipsToBounds = true
collectionView.backgroundColor = UIColor.systemBackground
return collectionView
}()
NSLayoutConstraint.activate([
searchText.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
searchText.heightAnchor.constraint(equalToConstant: 50),
searchText.leadingAnchor.constraint(equalTo: view.leadingAnchor),
searchText.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.topAnchor.constraint(equalTo: searchText.bottomAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (view.width / 3) - 4, height: (view.width / 2) - 2 )
}
image of CollectionView working normally
After the screen has been reloaded
Try to give your imageView a fixed height and fixed width and try it again, It will work

Cell not displaying elements when being reused on a stack that adds a LinkPresentation view

I had this custom view who worked like a charm before i introduce a LinkView for a Metadata
After i introduce a LinkView, since it was inside a stackView i had to remove linkView from superview when preparing for reusable (not sure why tried to redraw layout, but seems this not work with LinkView) the problems shows up when scrolling down elements, seems the data get lost at certain point, curious thing is that it only happens with the reusable element that contains the linkView item, is there any reason for this ? How can i fix it ?
Here is the code i use for the cell
final class TimeLineTableViewCell: UITableViewCell {
var cornerRadius: CGFloat = 6
var shadowOffsetWidth = 0
var shadowOffsetHeight = 3
var shadowColor: UIColor = .gray
var shadowOpacity: Float = 0.3
lazy var containerView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .white
view.addSubview(stackViewContainer)
let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius)
view.layer.cornerRadius = cornerRadius
view.clipsToBounds = true
view.layer.masksToBounds = false
view.layer.shadowColor = shadowColor.cgColor
view.layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight);
view.layer.shadowOpacity = shadowOpacity
view.layer.shadowPath = shadowPath.cgPath
return view
}()
lazy var stackViewContainer: UIStackView = {
let stack = UIStackView()
stack.axis = .horizontal
stack.alignment = .center
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fill
stack.spacing = 10.0
stack.addArrangedSubview(profileImage)
stack.addArrangedSubview(stackViewDataHolder)
return stack
}()
lazy var profileImage: UIImageView = {
let image = UIImage()
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
return imageView
}()
lazy var userName: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
}()
lazy var tweetInfo: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
}()
lazy var tweetText: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
}()
lazy var linkView: LPLinkView = {
let viewer = LPLinkView(frame: CGRect(origin: .zero, size: .init(width: 200, height: 20)))
viewer.translatesAutoresizingMaskIntoConstraints = false
return viewer
}()
lazy var stackViewDataHolder: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fillProportionally
stack.addArrangedSubview(userName)
stack.addArrangedSubview(tweetInfo)
stack.addArrangedSubview(tweetText)
return stack
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func prepareForReuse() {
linkView.removeFromSuperview()
}
func configure(viewModel: ProfileTweetViewModel) {
tweetInfo.configure(model: viewModel.tweetInfo)
userName.configure(model: viewModel.name)
tweetText.configure(model: viewModel.tweet)
if let metadata = viewModel.linkData {
linkView = LPLinkView(metadata: metadata)
stackViewDataHolder.addArrangedSubview(linkView)
//Tried almost all layoyt options but seems a previous view can't be updated since frame is wrong
}
if let url = viewModel.profilePic {
profileImage.downloadImage(from: url)
}
}
}
private extension TimeLineTableViewCell {
struct Metrics {
static let lateralPadding: CGFloat = 8
}
func constraints() {
NSLayoutConstraint.activate([
stackViewContainer.topAnchor.constraint(equalTo: containerView.topAnchor, constant: Metrics.lateralPadding),
stackViewContainer.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -Metrics.lateralPadding),
stackViewContainer.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: Metrics.lateralPadding),
stackViewContainer.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -Metrics.lateralPadding),
profileImage.heightAnchor.constraint(equalTo: profileImage.widthAnchor, multiplier: 1.0),
profileImage.widthAnchor.constraint(equalToConstant: 50.0),
])
}
func commonInit() {
addSubview(containerView)
backgroundColor = .clear
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: topAnchor),
containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 4),
containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -4),
containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -4),
])
constraints()
}
}
Thank you for your time.
The issue was related to .fillProportionally in stackView
since the linkView sometimes renders with 0 height, i just had to use .fill property in stackView in order to show it fully

How to fix UITableView not displaying in UIStackView

I followed a tutorial to build a weather app programmatically (without a storyboard) that displays the current city and temperature. I am modifying it to display a 5 day forecast instead of just the current temperature by adding a UITableView, but it is not showing up.
Here is my WeatherView code:
class WeatherView: UIView, UITableViewDelegate, UITableViewDataSource {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
setupViews()
setupConstraints()
}
private func setupViews() {
self.addSubview(mainStack)
conditionsImageStack.addArrangedSubview(conditionsImageView)
mainStack.addArrangedSubview(conditionsImageStack)
// forecastTable.register(UITableView.self, forCellReuseIdentifier: "forecast")
forecastTable.register(UITableViewCell.self, forCellReuseIdentifier: "forecast")
forecastTable.delegate = self
forecastTable.dataSource = self
mainStack.addArrangedSubview(centerContentStack)
// centerContentStack.addArrangedSubview(temperatureLabel)
centerContentStack.addArrangedSubview(forecastTable)
centerContentStack.addArrangedSubview(cityAndConditionsStack)
cityAndConditionsStack.addArrangedSubview(cityLabel)
cityAndConditionsStack.addArrangedSubview(conditionsLabel)
mainStack.addArrangedSubview(buttonsStack)
buttonsStack.addArrangedSubview(celsiusButton)
buttonsStack.addArrangedSubview(fahrenheitButton)
buttonsStack.addArrangedSubview(UIView(frame: .zero))
}
private func setupConstraints() {
mainStack.pinEdges(to: self)
}
let mainStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 10
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = UIEdgeInsets(top: 10, left: 30, bottom: 30, right: 30)
return stackView
}()
let conditionsImageStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.alignment = .trailing
stackView.spacing = 10
return stackView
}()
let cityAndConditionsStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .fillProportionally
stackView.spacing = 10
return stackView
}()
let centerContentStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .fillProportionally
stackView.alignment = .center
stackView.spacing = 60
return stackView
}()
// TABLE CODE HERE
var animalArray : [String] = ["elephant", "pig", "goat"]
var forecastTable: UITableView = {
let tableView = UITableView()
let estimatedHeight = tableView.numberOfRows(inSection: 3) //You may need to modify as necessary
// let width = parentView.frame.size.width
let width = estimatedHeight
tableView.frame = CGRect(x: 0, y: 0, width: width, height: estimatedHeight)
return tableView
}()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = forecastTable.dequeueReusableCell(withIdentifier: "forecast")
cell?.textLabel!.text = "Success"
return cell!
}
let temperatureLabel: UILabel = {
let label = UILabel(frame: .zero)
label.font = UIFont.systemFont(ofSize: 144)
label.textColor = .white
label.textAlignment = .center
label.text = "18°"
return label
}()
let cityLabel: UILabel = {
let label = UILabel(frame: .zero)
label.font = UIFont.systemFont(ofSize: 36)
label.textColor = .white
label.textAlignment = .center
label.text = "Atlanta"
return label
}()
let conditionsLabel: UILabel = {
let label = UILabel(frame: .zero)
label.font = UIFont.systemFont(ofSize: 20)
label.textColor = .white
label.textAlignment = .center
label.text = "Sunny"
return label
}()
let conditionsImageView: UIImageView = {
let image = UIImage(named: "sun")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
imageView.widthAnchor.constraint(equalToConstant: image!.size.width).isActive = true
imageView.heightAnchor.constraint(equalToConstant: image!.size.height).isActive = true
return imageView
}()
let celsiusButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("°C", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 73)
button.setTitleColor(.white, for: .normal)
return button
}()
let fahrenheitButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("°F", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 73)
button.setTitleColor(.white, for: .normal)
return button
}()
let buttonsStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .horizontal
stackView.distribution = .equalCentering
stackView.spacing = 10
return stackView
}()
}
Here is my ViewController code:
class WeatherViewController: UIViewController {
var mainView: WeatherView! { return self.view as! WeatherView }
let presenter: WeatherPresenter!
init(with presenter: WeatherPresenter){
self.presenter = presenter
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init coder not implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
updateBackground()
}
func updateBackground() {
self.mainView.updateGradient(presenter.backgroundColor)
}
override func loadView() {
self.view = WeatherView(frame: UIScreen.main.bounds)
}
}
Here is my UIView + Constraints code:
extension UIView {
func pinEdges(to view: UIView){
self.translatesAutoresizingMaskIntoConstraints = false
self.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
self.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
self.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
self.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}
}
I have tried forcing it to display by setting the dimensions with tableView.frame = CGRect(x: 0, y: 0, width: width, height: estimatedHeight) but that did not work.
I am registering the table in the view class instead of of the view controller class, but I am not sure if this is the problem or how to modify it correctly.
You're doing a couple things wrong...
First, in your var forecastTable: UITableView = {...} declaration, you have a line:
let estimatedHeight = tableView.numberOfRows(inSection: 3)
But, at that point, the table view has no dataSource -- even if it did, your dataSource has only section. So the value returned is undefined. If Iprint(esttmatedHeight)I get9223372036854775807. So you are trying to set the frame of your table view to9223372036854775807 x 9223372036854775807`
Next, when you add a table view to a stack view, the stack view will try to arrange it based on the stack view's properties and the table view's intrinsic size. However, the table view has no intrinsic size at that point - you must use auto-layout properties.
So, remove the frame setting for your table view, and after you've added it to the stack view, use:
// I'm guessing you want a height based on number of rows * row height?
// so, something like:
let estimatedHeight = CGFloat(3 * 44)
forecastTable.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
forecastTable.widthAnchor.constraint(equalTo: centerContentStack.widthAnchor),
forecastTable.heightAnchor.constraint(equalToConstant: estimatedHeight),
])
That will make the table view the same width as the centerContentStack that holds it, and give it a height.
At this point, you should see your table.
You are adding mainStack to the superView but not specifying it's dimensions. You need to set constrains to mainStack similar this,
mainStack.translatesAutoresizingMaskIntoConstraints = false
mainStack.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
mainStack.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
mainStack.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
mainStack.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
Above code fills the entire super view with mainStack. You can modify this code according to your requirement.

Dynamically change cell height according to label text

I tried to add Q&A part for my app and that tableview cell have to expand according to text height, cell height have to change with this text. In this point I did some thing to solve problem which are numberOfline = 0 and UITableView.automaticDimension code can't solve my problem. Here my code from project :
Problem is cell height didn't change this code just write label under the questions and for longer answers under the next question. Means cell height didn't change.
let soruLabel: UILabel = {
let sorulabel = UILabel()
sorulabel.textColor = .darkGray
sorulabel.numberOfLines = 0
sorulabel.font = UIFont.boldSystemFont(ofSize: 17)
return sorulabel
}()
let cevapLabel: UILabel = {
let cevaplabel = UILabel()
cevaplabel.textColor = .black
cevaplabel.numberOfLines = 0
cevaplabel.font = UIFont(name: "HelveticaNeue", size: 18)
return cevaplabel
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
}
func set(content: expandingTableCellForsss) {
self.soruLabel.text = content.soru
self.cevapLabel.text = content.expanded ? content.cevap : ""
}
func setup() {
backgroundColor = UIColor.init(red: 245, green: 245, blue: 245, alpha: 1)
addSubview(soruLabel)
addSubview(cevapLabel)
soruLabel.translatesAutoresizingMaskIntoConstraints = false
soruLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
soruLabel.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
soruLabel.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = false
soruLabel.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
cevapLabel.translatesAutoresizingMaskIntoConstraints = false
cevapLabel.topAnchor.constraint(equalTo: soruLabel.bottomAnchor).isActive = true
cevapLabel.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
cevapLabel.bottomAnchor.constraint(equalTo: soruLabel.bottomAnchor).isActive = false
cevapLabel.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The bottom anchor needs to be set:
cevapLabel.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
Please check :
UITableViewCell auto height based on amount of UILabel text ,
Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
To use dynamic cell height:
1) give a minimum row height for cell in viewDidLoad
tableView.estimatedRowHeight = 300
2) set rowHeight property of tableview as automatic in viewDidLoad
tableView.rowHeight = UITableViewAutomaticDimension
3) in storyboard select numberOfLines = 0
4) if you have provided custom height to cell in storyBoard, make sure its equal to estimated row height.

Changing items within custom UITableViewCell Class

I have 2 classes - a UITableViewController and a custom UITableViewCell. I want to change the cell height for my UITableViewController, so I implement the following:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.height*(1/12)
}
and it works! The cell height changes. Now, I go into my custom UITableViewCell class
import UIKit
class TableViewCell: UITableViewCell {
var time:UILabel = UILabel()
var name:UILabel = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) // the common code is executed in this super call
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.frame.width*0.22, height: self.frame.height))
imageView.image = UIImage(named: "Person")
imageView.contentMode = .scaleAspectFit
imageView.isUserInteractionEnabled = true
self.addSubview(imageView)
let tap = UITapGestureRecognizer(target: self, action: #selector(signIn))
imageView.addGestureRecognizer(tap)
name = UILabel(frame: CGRect(x: self.frame.width*0.22, y: 0, width: self.frame.width*0.78, height: self.frame.height*0.7))
name.textColor = UIColor.gray
name.font = UIFont(name: name.font!.fontName, size: 30)
name.adjustsFontSizeToFitWidth = true
self.addSubview(name)
time = UILabel(frame: CGRect(x: self.frame.width*0.22, y: self.frame.height*0.65, width: self.frame.width*0.78, height: self.frame.height*0.3))
time.textColor = UIColor.gray
time.font = UIFont(name: time.font!.fontName, size: 15)
time.adjustsFontSizeToFitWidth = true
self.addSubview(time)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
#objc func signIn(tap: UITapGestureRecognizer) {
let tappedImage = tap.view as! UIImageView
tappedImage.image = UIImage(named: "PersonClocked")
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
So, I now edit the function inside my controller to call the cells.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:TableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
cell.layer.borderColor = UIColor.red.cgColor
cell.layer.borderWidth = 1
cell.name.text = names[indexPath.row]
cell.time.text = times[indexPath.row]
return cell
}
I expect it to all work now! But, it doesn't. For whatever reason, the methods get called in this order...
tableview(cellForRowAt) -> TableViewCell(override init) -> tableView(heightForRowAt)'
So, when I go to run it, it looks something like below. The cell is created with Swift's/Apple's default runtime tableView, then the cell size is changed, but everything inside the cell is still the size of the original default value. I need it to be the size of the cell. Any ideas?
Note - I added a border so you could see the size of the cell compared to the items.
Frame layout can't help in creating dynamic height tables you have to use dynamic tableViewCells and create the cell's contentView with constraints to get the height change with the current content
//
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) // the common code is executed in this super call
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.frame.width*0.22, height: self.frame.height))
imageView.image = UIImage(named: "Person")
imageView.contentMode = .scaleAspectFit
imageView.isUserInteractionEnabled = true
self.addSubview(imageView)
let tap = UITapGestureRecognizer(target: self, action: #selector(signIn))
imageView.addGestureRecognizer(tap)
name = UILabel(frame: CGRect(x: self.frame.width*0.22, y: 0, width: self.frame.width*0.78, height: self.frame.height*0.7))
name.textColor = UIColor.gray
name.font = UIFont(name: name.font!.fontName, size: 30)
name.adjustsFontSizeToFitWidth = true
self.addSubview(name)
time = UILabel(frame: CGRect(x: self.frame.width*0.22, y: self.frame.height*0.65, width: self.frame.width*0.78, height: self.frame.height*0.3))
time.textColor = UIColor.gray
time.font = UIFont(name: time.font!.fontName, size: 15)
time.adjustsFontSizeToFitWidth = true
self.addSubview(time)
imageView.translatesAutoresizingMaskIntoConstraints = false
name.translatesAutoresizingMaskIntoConstraints = false
time.translatesAutoresizingMaskIntoConstraints = false
imageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor,constant: 0).isActive = true
imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor,constant: 20).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 30).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 30).isActive = true
name.topAnchor.constraint(equalTo: contentView.topAnchor,constant: 20).isActive = true
name.leadingAnchor.constraint(equalTo: imageView.leadingAnchor,constant: 20).isActive = true
name.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,constant: -20).isActive = true
time.topAnchor.constraint(equalTo: name.topAnchor,constant: 20).isActive = true
time.leadingAnchor.constraint(equalTo: imageView.leadingAnchor,constant: 20).isActive = true
time.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,constant: -20).isActive = true
time.bottomAnchor.constraint(equalTo: contentView.bottomAnchor,constant: -20).isActive = true
}
//
put this in viewDidLoad
tableview.estimatedRowHeight = 100
tableview.rowHeight = UITableViewAutomaticDimension
and don't implement heightForRowAt method