I have two cells (one dynamic and other static) and I want to set different height for each cell like:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
/*tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath)
tableView.dequeueReusableCell(withIdentifier: "Cell2", for: indexPath)
if cell1 return 100
if cell2 return 20 */
}
It's possible to specific height for each cell not row.
How can I resolve this issue?
For static cell (created either as Xib or in storyboard), you can set the height like this, if you are displaying static cell in first row of your Table View.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 0 {
return 120
}
return UITableViewAutomaticDimension
}
To populate the static cell along with dynamic cell, You should do,
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return datasource.count + 1
}
UITableViewAutomaticDimension
https://www.raywenderlich.com/129059/self-sizing-table-view-cells -
If you set correctly the autolayout for the cell you can use UITableViewAutomaticDimension to have the size without have to specify.
You only need to return a height for each indexPath. There is no need to dequeue a cell here. If you want different prototype cells you will do this in cellForRowAtIndexPath.
You can specify as many sections and rows as you want:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.section {
case 0:
switch indexPath.row {
case 0:
return 100.0
case 1:
return 20.0
// Add rows here if needed
default:
return UITableViewAutomaticDimension
// Add sections here if needed
default:
default:
return UITableViewAutomaticDimension
}
}
*In, Swift 3.0
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0 {
return 100
} else {
return 200
}
}
or you can set Constraint of your Cell proper and then write this code of your ViewDidLoad Method
yourTblView.estimatedRowHeight = 100
yourTblView.rowHeight = UITableViewAutomaticDimension*
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0 {
return 100
} else {
return 20
}
}
Related
I've currently multiple items in tableView cell .I want to increase the height of cell when text condition is matched like if name = "john" then increase the height of cell without disturbing another cell. I want to achieve this screenshot result
My current code is
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == tableOrder {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.tableOrderHeight.constant = self.tableOrder.contentSize.height
//self.tableOrderHeight.constant = (6 * 80)
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath ) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PriceTVCell.self)) as? PriceTVCell else {return UITableViewCell()}
return cell
}
first get the index of the row you want to increase the height and use the delegate function heightForRowAt.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == customRow {
return 100.0;//Choose your custom row height
}
}
I have a UITableViewController with a custom UITableViewCell. Each cell has 2 labels. When the cell is selected it expands to a fixed value, I do it via tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat . I also have set the rowHeight = UITableViewAutomaticDimension , as some cells have to display multiple lines of text.
What I want to achieve is when a cell needs to be expanded I want to add 50 points to its current height. So here's the question, how can I get current height of the cell, when the rowHeight = UITableViewAutomaticDimension is set?
Here's my code for the fixed height for the selected state:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if selectedIndexPath == indexPath {
return selectedHeight
}else{
return tableView.estimatedRowHeight
}
}
EDIT: I also need to change it after that, by adding some variable to it.
Building on HamzaLH's answer you might do something like this...
import UIKit
class TableViewController: UITableViewController {
var selectedRow: Int = 999 {
didSet {
tableView.beginUpdates()
tableView.endUpdates()
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == selectedRow { //assign the selected row when touched
let thisCell = tableView.cellForRow(at: indexPath)
if let thisHeight = thisCell?.bounds.height {
return thisHeight + 50
}
}
return 60 //return a default value in case the cell height is not available
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedRow = indexPath.row
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
cell.detailTextLabel?.text = "test"
return cell
}
}
I'm animating the expansion of the height with a didSet when a the selectedRow is altered.
Also, don't forget you may still need to connect your dataSource and delegate by dragging the outlets in Interface Builder to your View Controller in the storyboard. After that you still need to add this to ViewDidLoad in your ViewController's swift file.
tableView.delegate = self
tableView.dataSource = self
I also have an Outlet declared for the tableView like below, and connected in Interface Builder storyboard.
#IBOutlet weak var tableView: UITableView!
You need to get the cell using cellForRow and then get the height of the cell.
let cell = tableView.cellForRow(at: indexPath)
let height = cell.bounds.height
I have JSON object where one key is interface_id and I want to set Cell height accordingly, When I try to set height 0, after that tableView stuck while scrolling.
public func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat{
if (dataArray[indexPath.row] as AnyObject).value(forKey: "interface_id") as! Int == 1{
return 0
}else{
return UITableViewAutomaticDimension
}
}
Basically, to use self sizing cells, for the UITableView you will set an estimated row height, and also set the rowHeight to a value of UITableViewAutomaticDimension. so changing the Cell height for row your code should be look like that.
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 44.0
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if (dataArray[indexPath.row] as AnyObject).value(forKey: "interface_id") as! Int == 1{
return 0
}else{
return UITableViewAutomaticDimension
}
}
This question already has answers here:
UITableview with more than One Custom Cells with Swift
(7 answers)
Swift: How to set dynamic cell height in TableViewController which contains more than one cell
(2 answers)
Closed 5 years ago.
I have two custom cells, but having trouble setting static heights to both those cells, I need the first cell to have a height of 100, but every other cell to have a height of 40. The below code makes all the cells have a height of a 100 instead of just the first one.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if(indexPath.row == 0) {
return 100.0
}
return 40.0
}
You can put your first cell in a different section.
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
}else {
return yourArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! FirstCustomCell
return cell
}else{
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! SecondCustomCell
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 1 {
return 100
} else{
return 40
}
I would like something like the following:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("NewsCell", forIndexPath: indexPath) as! UITableViewCell
if indexPath == 3{
cell.height = "50dp"
}
return cell
}
what is the alternative or the easiest way to go about this?
EDIT
Is it possible for me to also specify section number: i.e-
if sectionIndex == 5
I suggest use the heightForRowAtIndexPath function. TableView will call this function to determine the row height for a specific indexpath.
Sample code:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.section == SECTION_INDEX {
return 60
} else {
return UITableViewAutomaticDimension
}
}
Swift 4:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == SECTION_INDEX {
return 60
} else {
return UITableViewAutomaticDimension
}
}
A little explain:
indexPath have two properties: section and row. By checking these two properties, you can make your own control flow to determine the height for each cell.
If you return 60, it means you want the cell's height to be 60 points. If you return UITableViewAutomaticDimension, you want the system to decide the best height for you (in this case, you'd better set autolayout for the cell in storyboard).
I also suggest you take the stanford course CS193p on iTunes U, it would be of great help to you :)
the easiest way is to override heightForRowAtIndexPath
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let section = indexPath.section
let row = indexPath.row
if section == 0 && row == 2{
return 50.0
}
return 22.0
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
if indexPath.section == 5
{
if indexPath.row == 3
{
return 150.0
}
}
return 200.0
}
Following Zhu Shengqi's answer, here is the Swift 5+ code.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == SECTION_INDEX {
return 160
} else {
return UITableView.automaticDimension
}
}
the easiest way is to override heightForRowAtIndexPath delegate method is there in tableview.
These method based on content it will change the height automatically.
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableView.AutoDiemensions
}