UITableViewCell height with dynamic subview swift - ios

I have a UITableView that UITableViewCell has a dynamic UILabel which will be added based on data i get from the database.
I'm using something like
let testing = ["A", "B", "C", "D"] // This array is dynamic data
self.dictionaryTableView.estimatedRowHeight = 44
self.dictionaryTableView.rowHeight = UITableViewAutomaticDimension
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath)
var y = 0
for var i in 0..<self.testing.count {
let lbl = UILabel(frame: CGRect(x: 0, y: y, width: 50, height: 25))
lbl.text = self.testing[i]
lbl.numberOfLines = 0
cell.addSubview(lbl)
y += 20
}
return cell
}
But UITableViewCell height does not stretch automatically to display all content cell. Please help
Here is the result
EDIT I added constraint for the uilabel in UITableView cellForRowAtIndexPath, the constraints are working (I knew it when I expend the cell height), but cell height not automaticly strech out
var bottomAnchor: NSLayoutYAxisAnchor = NSLayoutYAxisAnchor()
for var i in 0..<self.testing.count {
let lbl = UILabel()
lbl.text = self.testing[i]
lbl.numberOfLines = 0
lbl.translatesAutoresizingMaskIntoConstraints = false
cell.addSubview(lbl)
lbl.leftAnchor.constraint(equalTo: cell.leftAnchor, constant: 16).isActive = true
lbl.widthAnchor.constraint(equalTo: cell.widthAnchor).isActive = true
lbl.heightAnchor.constraint(equalToConstant: 25).isActive = true
if i == 0 {
lbl.topAnchor.constraint(equalTo: cell.topAnchor).isActive = true
} else {
lbl.topAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
bottomAnchor = lbl.bottomAnchor
}
return cell
Many thanks

There are two things that you need to fix in your implementation:
Create the layout of your cell before dequeueing it in tableView(_:, cellForRowAt:).
For efficiency reasons, table views reuse the same cells over and over again when the user scrolls. That's why you use this weird "dequeuing" function rather than simply instantiating a new cell.
let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath)
will always try to return a used cell that just scrolled out of the view. Only if there are no recycled cells available (for example when dequeueing the first couple of cells) the table view will create new instances of a cell.
The recycling of cells is the very reason why you should never create your cell's layout inside tableView(_:, cellForRowAt:), for example by adding a label. When the cell is being reused, another label will be added on top of the label that you added before and when it's being reused a second time, you'll end up with three overlapping labels etc.
The same applies to constraints. When you add constraints to a cell in tableView(_:, cellForRowAt:) without removing existing ones, more and more constraints will be added while the user is scrolling, most likely resulting in serious constraint conflicts.
Instead, setup your cell's layout before dequeueing it. There are several ways to achieve this:
If you use a UITableViewController inside a storyboard, you can create dynamic prototypes and lay out the cells directly in the storyboard. You could, for example, drag a label to a prototype cell there and create an outlet for it in a custom UITableViewCell subclass.
You can create a XIB file for your cell, open it in Interface Builder and create your layout there. Again, you need to create a UITableViewCell subclass with the appropriate outlets and associate it with your XIB file.
You can create a UITableViewCell subclass and set up your layout purely in code, for example inside the cell's initializer.
You need to use Auto Layout.
If you create your layout in Interface Builder, you just need to add the necessary constraints and you're good to go. If you create your layout in code, you need to set the translatesAutoresizingMaskIntoConstraints property to false for all views that you wish to constrain, for example:
lbl.translatesAutoresizingMaskIntoConstraints = false
In your particular layout, you need to constrain the label at the left, right, top and bottom with the corresponding edges of your cell's contentView.
If you don't know how to do that, please read Apple's Auto Layout Guide. (It's usually a better idea to do this in Interface Builder rather than in code.)
A very detailed description of how to use "Auto Layout in UITableView for dynamic cell layouts & variable row heights" can be found here.

used this code.
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}

You can use UITableView section to render the data instead of adding the view programmatically. Here's the example:
class ViewController: UITableViewController {
private var dataSectionOne = ["Data 1", "Data 2"]
// This can be your dynamic data.
// Once the data changed, called tableView.reloadData() to update the view.
private var dataSectionTwo = ["A", "B", "C"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return dataSectionOne.count
} else if section == 1 {
return dataSectionTwo.count
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if indexPath.section == 0 {
cell.textLabel?.text = dataSectionOne[indexPath.row]
} else if indexPath.section == 1 {
cell.textLabel?.text = dataSectionTwo[indexPath.row]
}
return cell
}
}
The results:

I found the answers here
I added a constraint to my UITableViewCell bottom with the following code and it's working, but I don't know what exactly this line doing (I don't know the parameters too)
Could anyone help me explain this code
let bottomSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: lbl, attribute: NSLayoutAttribute.bottomMargin, relatedBy: NSLayoutRelation.equal, toItem: cell.contentView, attribute: NSLayoutAttribute.bottomMargin, multiplier: 1, constant: -8)
cell.contentView.addConstraint(bottomSpaceConstraint)

Related

tableView does not appear when centered into its parent view

I have a viewController with the following (static) tableView:
class viewController: UIViewController, UITableViewDelegate {
private let tableView: UITableView = {
let tv = UITableView()
tv.separatorStyle = .singleLine
tv.allowsSelection = true
tv.isScrollEnabled = false
return tv
}()
private let tableData = ["row1", "row2", "row3", "row4"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.delegate = self
tableView.tableFooterView = UIView()
view.addSubview(tableView)
NSLayoutConstraints.activate([
tableView.centerXAnchor.constraints(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
tableView.centerYAnchor.constraints(equalTo: view.safeAreaLayoutGuide.centerYAnchor)
)]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel!.text = tableData[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
}
When I run the app, this viewController shows a blank screen. I know that the way I am setting up the tableview's constraints is the problem because when I set up the tableView using topAnchor, bottomAnchor, leftAnchor, and rightAnchor (and with some other tweaking) the tableview appears. Any idea why the app is behaving this way?
Your table view is probably there, and centered, but you didn't define a size, so it's probably being set to zero width and height, that's why you don't see it.
You can fix this by setting a constraint on it's width and height, either to a constant or related to it's superview, depending on what you want.
The problem is this is NOT a static table view. If it were, you would not have implemented cellForRowAt. It is a normal table view and it needs a data source and delegate. Plus it needs a height and a width.

spacing between UITableViewCells swift3

I am creating a IOS app in swift and want to add spacing between cells like this
I would like to give space of each table view cell same like my attach image.
How I can do that? and Right now all cells are coming without any space.
swift3
you can try this in your class of tableView cell:
class cell: UITableViewCell{
override var frame: CGRect {
get {
return super.frame
}
set (newFrame) {
var frame = newFrame
frame.origin.y += 4
frame.size.height -= 2 * 5
super.frame = frame
}
}
}
From Storyboard, your view hierarchy should be like this. View CellContent (as highlighted) will contain all the components.
Give margin to View CellContent of 10px from top, bottom, leading & trailing from its superview.
Now, select the tblCell and change the background color.
Now run your project, make sure delegate and datasource are properly binded.
OUTPUT
NOTE: I just added 1 UILabel in View CellContent for dummy purpose.
Update: UIEdgeInsetsInsetRect method is replaced now you can do it like this
contentView.frame = contentView.frame.inset(by: margins)
Swift 4 answer:
in your custom cell class add this function
override func layoutSubviews() {
super.layoutSubviews()
//set the values for top,left,bottom,right margins
let margins = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
contentView.frame = UIEdgeInsetsInsetRect(contentView.frame, margins)
}
You can change values as per your need
***** Note *****
calling super function
super.layoutSubviews()
is very important otherwise you will get into strange issues
If you are using UITableViewCell to achieve this kind of layout, there is no provision to provide spacing between UITableViewCells.
Here are the options you can choose:
Create a custom UIView within UITableViewCell with clear background, so that it appears like the spacing between cells.
You need to set the background as clear of: cell, content view.
You can use UICollectionView instead of UITableView. It is much more flexible and you can design it the way you want.
Let me know if you want any more details regarding this.
One simple way is collection view instead of table view and give cell spacing to collection view and use
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
let widthSize = collectionView.frame.size.width / 1
return CGSize(width: widthSize-2, height: widthSize+20)
}
And if you want tableview only then add background view as container view and set background color white and cell background color clear color set backround view of cell leading, trilling, bottom to 10
backgroundView.layer.cornerRadius = 2.0
backgroundView.layer.masksToBounds = false
backgroundView.layer.shadowColor = UIColor.black.withAlphaComponent(0.2).cgColor
Please try it. It is working fine for me.
You can use section instead of row.
You return array count in numberOfSectionsInTableView method and set 1 in numberOfRowsInSection delegate method
Use [array objectAtIndex:indexPath.section] in cellForRowAtIndexPath method.
Set the heightForHeaderInSection as 40 or according to your requirement.
Thanks,Hope it will helps to you
- Statically Set UITableViewCell Spacing - Swift 4 - Not Fully Tested.
Set your tableView Row height to whatever value you prefer.
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = <Your preferred cell size>
tableView.rowHeight = UITableViewAutomaticDimension
// make sure to set your TableView delegates
tableView.dataSource = self
tableView.delegate = self
}
extension YourClass : UITexFieldDelegate, UITextFieldDataSource {
//Now set your cells.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! UITableViewCell
//to help see the spacing.
cell.backgroundColor = .red
cell.textLabel?.text = "Cell"
return cell
}
//display 3 cells
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
//now lets insert a headerView to create the spacing we want. (This will also work for viewForHeaderInSection)
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//you can create your own custom view here
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: tableView.frame.width, height: 44) //size of a standard tableViewCell
//this will hide the headerView and match the tableView's background color.
view.backgroundColor = UIColor.clear
return view
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
}

Swift TableViewCell xib doesn't have constraints

I have two TableViews, when I designed the original I designed it using the prototype cell in the storyboard, to make it reusable I tried to pull it out into a .xib and load that instead. When it is loaded from cellID.xib however it loses all the constraints at runtime, and everything is layered on top of each other.
TableViewController
let cellIdentifier = "cellID"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: cellIdentifier, bundle: nil), forCellReuseIdentifier: cellIdentifier)
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300
}
Prototype cell in Storyboard (Used to work)
Cell when copy pasted to XIB
Constraints
XIB View Hierarchy
The Problem
In your question title, you asked how to solve an issue where "Swift TableViewCell xib doesn't have constraints." Additionally in the bounty, you specify that the answer should be:
An adequate answer showing why constraints are lost when moved to a
xib, when they exist in the xib, and how to address this problem.
From my understanding, your question has two parts:
Issue where a custom TableViewCell xib does not have constraints
Why constraints are lost when copy/pasted from Storyboard prototype to a xib
For issue #1, I used almost all of the same constraints as you had displayed in your screenshot in a custom cell xib and it worked. I will explain in more detail below.
For issue #2, I found that constraints are not lost. You may need to share your project so that others can replicate the issue you are having. I copy/pasted a Storyboard prototype cell with similar constraints over to a xib and I did not have any issues with constraints. So I can confirm that the copy/paste feature does work.
Solution Demo
I created the following demo to test your issue. Refer to the screenshot below. The tableView contains six cells. The 1st and 2nd are the same and have reuse identifier MyCell. The 3rd and 4th are the same and have reuse identifier MyCopyPasteCell. The 5th and 6th are the same and have reuse identifier MyPrototypeCell.
MyCell exists in a xib and uses nearly all the same constraints that you showed in your screenshot. As you can see, there are no constraints issues. MyCopyPasteCell uses similar constraints and was copy/pasted from a Storyboard prototype over to a xib. MyPrototypeCell is the original prototype that was copied. These last four cells look exactly the same even though the prototype was copied over to the xib. The constraints carried over from prototype to xib without an issue.
Constraints
In the code below, I list all the constraints that you showed in your screenshot for your ContentView. (Note that I also implemented the height=20, aspect=1:1, and height=75 constraints, although they are not listed below.) Two constraints are commented out since I did not use them. I also added one more constraint to replace another unused one.
// bottomMargin = Profile Image View.bottom + 188.5
bottomMargin = Profile Image.bottom + 17
Profile Image View.top = Username Label.top
Profile Image View.leading = leadingMargin + 2
Profile Image View.top = topMargin + 20
Username Label.leading = Content Text View.leading
// Username Label.top = topMargin + 20
Username Label.trailing = Content Text View.trailing
Username Label.leading = Profile Image View.trailing + 15
trailingMargin = Username Label.trailing + 10
Content Text View.top = Username Label.bottom + 5
Content Text View.leading = leadingMargin + 92
bottomMargin = Content Text View.bottom + 20
The first commented constraint // bottomMargin = Profile Image View.bottom + 188.5 did not make sense as it would separate the bottom of the image from the bottom of the cell by 188.5. This also did not match your Prototype cell in Storyboard (Used to work) screenshot at all. I replaced it with bottomMargin = Profile Image.bottom + 17, which just replaces the 188.5 with 17.
The second commented constraint // Username Label.top = topMargin + 20 (which separates username and topMargin by 20) can technically work. However, its functionality is redundant to Profile Image.top = topMargin + 20 (which separates Profile Image and topMargin by 20) and Profile Image View.top = Username Label.top (which sets the Profile Image and Username to the same top separation i.e. by 20).
MyTableViewController
The following is my view controller. Basically I create three sections with two cells/rows per section. MyCell and MyCopyPasteTableViewCell are from a xib and are registered in the viewDidLoad(). MyPrototypeCell is from the Storyboard and is not registered in viewDidLoad().
// MyTableViewController.swift
import UIKit
class MyTableViewController: UITableViewController {
let myCell = "MyCell"
let myCopyPasteCell = "MyCopyPasteTableViewCell"
let myPrototypeCell = "MyPrototypeCell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: myCell, bundle: nil), forCellReuseIdentifier: myCell)
tableView.register(UINib(nibName: myCopyPasteCell, bundle: nil), forCellReuseIdentifier: myCopyPasteCell)
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: myCell, for: indexPath)
return cell
} else if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: myCopyPasteCell, for: indexPath)
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: myPrototypeCell, for: indexPath)
return cell
}
}
}
Github link
https://github.com/starkindustries/TableViewCellConstraintsTest
Problem and Solution
You may have disabled the Autolayout for your XIB to turn it ON go to File Inspector from Top Right Menu
You Can Follow the Simple Steps to Create Cell from Xib 😊
1. Create UITableCell with .xib ( ✅ also create Xib file)
2. Give the cell identifier
3. Layout Constraints
🔸 ImageView give contarints from Top , Left and Bottom
height constant and Aspect ratio [i have set Border to show the frame]
🔸 UIlable for the title lable give constraints from three sides
from Top , Left and Right NumberOflines=0 (🚫 Don't give height constant -
⚠️ if gives warning go ahead and update the constraints)
🔸 UIlable for the Descriptions lable give constraints from all four sides also NumberOflines=0
(⚠️ This will give you an error go to suggestion and change the priority of UIlable constraints)
see the screenshot below
changing priority
than again update contraints
4. Code in UIViewController
#IBOutlet var tableView: UITableView!
var cellIdentifier="cell"
var cellXibName = "MyTableCell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: cellXibName, bundle: nil), forCellReuseIdentifier: cellIdentifier)
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 320
}
func numberOfSections(in tableView1: UITableView) -> Int {
return 3
}
func tableView(_ tableView1: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell :MyTableCell = tableView1.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! MyTableCell
return cell
}
And Finally the Output is perfect as you want
OUTPUT
I hope this will work for you...... please let me know if this worked for you or not.
Solution :
I was achive solution to your problem. hope it might be help to you
I use uiview to clips all cell elements.
And Cell Design
Code :
class ViewController: UIViewController {
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 100
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.register(UINib(nibName: "TestCell", bundle: Bundle.main), forCellReuseIdentifier: "TestCell")
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController : UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 1;
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for: indexPath) as! TestCell
cell.selectionStyle = .none
return cell
}
}
Result :
It seems that the cell height is the problem, right? Because of that the constraints can't do their work correctly.
You need this override func when you work with XIB files:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 300
}
However your constraints must be wrong or let us say they are not perfect. I know they are working with the prototype cells in storyboard but that don't make them 100% perfect working right?
Your UIImageView has no height and width. You should try to set that with some constraints. (or you set the width and use the Aspect Ratio constraint)

How to size a UIStackView depending on its content?

I would like to have a similar behavior than the <Table> HTML tag, in the sense where the frame is sized according to its content.
In my very context, I use an UIStackView as the content view of a UITableViewCell. As items in the cell are various information, the resulting height of the cell should be variable.
My strategy is to programmatically build a cell as a UIStackView with a .Vertical axis, as in the code snippet as follows:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let sv = UIStackView(frame: tableview.frame)
sv.axis = .Vertical
cell.addSubview(sv)
for i in information {
let l = UILabel()
l.text = i
sv.addSubViewAndArrange(l)
}
return cell
}
Unfortunately, the cell size does not adjust to the content, and as a result I have to set the cell height myself, as follows:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return cellHeight // a constant
}
How could I fix that?
UIStackView is designed to grow its size according to the content. In order for that to work, you need to set up the constraints between the UIStackView and the UITableViewCell. For example, if UIStackView is first-item and UITableViewCell is it's super-view, then this is how the constraints look like in interface builder:
If you like setting up constraints in code, that should work too.
For example, assuming stackView and cellView are the names, then above constraints' Swift-code would look like:
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.topAnchor.constraint(equalTo: cellView.topAnchor, constant: 0).isActive = true
stackView.bottomAnchor.constraint(equalTo: cellView.bottomAnchor, constant: 0).isActive = true
stackView.leadingAnchor.constraint(equalTo: cellView.leadingAnchor, constant: 0).isActive = true
stackView.trailingAnchor.constraint(equalTo: cellView.trailingAnchor, constant: 0).isActive = true
To demonstrate that this will work, I have this for the cellForRowAt function. Basically, it puts a number of UILabel inside the UIStackView and the label count is depending on the row number.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableviewCell", for: indexPath) as! TableviewCell
for i in 1...indexPath.row + 1 {
let label = UILabel()
label.text = "Row \(indexPath.row), Label \(i)"
cell.stackView.addArrangedSubview(label)
}
return cell
}
Here is the final result:
https://github.com/yzhong52/AutosizeStackview
I built this example I hope it helps, I've created a tableView which use a cell that contains a stackView and the views loaded in the stackView are gotten from a nib file
https://github.com/Joule87/stackView-within-TableViewCell

Self Sizing Cell in Swift, how do I make constraints programmatically?

I'm trying to do a sidebar with self sizing cells in swift. I found this great tutorial : http://www.appcoda.com/self-sizing-cells/
As far as I know you need 3 things to make a self sizing cell:
Define auto layout constraints for your prototype cell
Specify the estimatedRowHeight of your table view
Set the rowHeight of your table view to UITableViewAutomaticDimension
The last two are covered in the tutorial by code, but the first one is explained by the story board, and my problem is how do I implement it by code??
I have this method where I get my custom cell, I think that I have to implement the constraints(in the tutorial you can see what kind of constrains) here but I don't know how, so please could you give me some help?
override func tableView(tableView: (UITableView!), cellForRowAtIndexPath indexPath: (NSIndexPath!)) -> UITableViewCell{
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CellId")
cell!.backgroundColor = UIColor.clearColor()
cell!.textLabel?.textColor = UIColor.darkTextColor()
let selectedView:UIView = UIView(frame:CGRect(x: 0, y: 0, width: cell!.frame.size.width, height: cell!.frame.size.height))
selectedView.backgroundColor = UIColor.orangeColor().colorWithAlphaComponent(0.3)
cell!.selectedBackgroundView = selectedView
//asignar valores a la celda
cell!.textLabel?.text = tableData[indexPath.row]
cell!.textLabel?.numberOfLines = 0
cell!.setTranslatesAutoresizingMaskIntoConstraints(false)
}
return cell!
}
Update 1:
The text goes beyond the 3rd break of line in the 1st and the 3rd row, but here only show me max. of 3 breaklines
Thanks!
Don't add layout constraints in tableView(_:cellForRowAtIndexPath:).
You should not instantiate a table view cell in that method yourself. Instead, you should register one with the UITableView (probably in the viewDidLoad() method of your view controller) (registerClass(_:forCellReuseIdentifier:) or registerNib(_:forCellReuseIdentifier:)).
In tableView(_:cellForRowAtIndexPath:) you use dequeueReusableCellWithIdentifier(_:forIndexPath:) to get an instance of the cell. The table view will reuse cells as you scroll, so that it doesn't have to create new ones all the time. Essentially, let's say you never see more than 15 cells on screen at the same time, then there won't be more than that many instances.
Now, when you register your table view cells (see above) you should probably subclass UITableViewCell and then either set your layout constraints in code (maybe override init(style:reuseIdentifier:)) or you can create a .nib file and use that. Then you can set up the constraints in Xcode through the graphical UI.
Let me know if you have any questions.
I found a good function to make cell dynamic size
func dynamicHeight(text:String, font:UIFont, width:CGFloat) -> CGFloat{
let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.height
}
Call this function in heightForRowAtIndexPath
I hope it works.
Try this:-
First add this two functions in your class
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Second in order to make the UITableViewAutomaticDimension work make sure you have added all the left, right, bottom, and top constraints relative to cell container view.

Resources