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
}
Related
I am having trouble making a table view with one static cell at the very top of my table view. This table view will hold 4 buttons and the rest of the views will hold a list of the user's songs.
I have already looked into other answers on here but all of them seem to be written in Objective C not swift.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sortedSongs.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RecentCell", for: indexPath) as! RecentCell
//cell.songTitle.text = albumList[indexPath.row]
//cell.songArtist.text = artistList[indexPath.row]
//cell.songImage.image = imageList[indexPath.row]
return cell
}
This is what I have been using to just set the regular table views. How would I go about modifying this code to allow for a static cell at the top and dynamic cells for the rest?
Don't use Static Cells. Choose Dynamic Prototypes in your table view and create 2 prototype cells.
And return first cell in first section, other cells in second section
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
} else if section == 1 {
return sortedSongs.count
} else if section == 2 {
return anotherArrayCount
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "FirstCell", for: indexPath) as! FirstCell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "RecentCell", for: indexPath) as! RecentCell
//cell.songTitle.text = albumList[indexPath.row]
//cell.songArtist.text = artistList[indexPath.row]
//cell.songImage.image = imageList[indexPath.row]
return cell
}
}
You can use the HeaderView of the table for that, just give your custom view to the . tableHeaderView property
Example:
override func viewDidLoad() {
super.viewDidLoad()
let myCustomView = MyCustomView()
tableView.tableHeaderView = myCustomView
}
Documentation: https://developer.apple.com/documentation/uikit/uitableview/1614904-tableheaderview
I have a tableview and I'm downloading data from firebase after that I reload tableview but I want to add more different cell to tableview too. For example my datas count is six and I want to add to second row and fifth row different cell. In the end I want to show eight cell.
I tried this code;
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 1 {
let cell = myTableView.dequeueReusableCell(withIdentifier: "makeLiveWallpaper") as! LiveWallTableViewCell
if indexPath.row == 1 {
cell.titleLabel.text = "Let's make LiveWallpaper"
}
return cell
}else{
if let cell = myTableView.dequeueReusableCell(withIdentifier: "CategoryTableViewCell", for: indexPath) as? CategoryTableViewCell{
cell.category = category(at: indexPath)
cell.delegate = self
cell.setScrollPosition(x: offsets[indexPath] ?? 0)
return cell
}
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 1 {
return 140
}else{
return 255
}
}
But it is not adding new cell it is over write on cell
Once you got the data update your dataSource like given below:
data.insert("", at: 1)
data.insert("", at: 4)
self.tableView.reloadData()
update your Data Source Method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 1 {
// your custom Cell
return cell
} else if indexPath.row == 5 {
// you custom Cell
return cell
} else {
// normal cell
}
return UITableViewCell()
}
Hope it will hep you.
I am currently using two prototype cells to have my collectionView in top cell moving horizontally while all other cells moves vertical. It's still short one cell count at the bottom and I can't seem to figure out why.
This is the code. Can you point out where the issue is please?
//Mark:- Data arrays
var dataArray: [String] = ["c1","c2","c3","c4","c5"]
var cellArray: [String] = ["10","11","12","13","14","15"]
//Mark:- UITableView Delegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell") as! MainTableViewCell
return cell
} else {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell") as! CustomTableViewCell
cell2.cellImage.image = UIImage(named: cellArray[indexPath.row])
return cell2
}
}
//Mark:- UICollectionView Delegate
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "InsideCollectionViewCell", for: indexPath) as! InsideCollectionViewCell
cell.myImage.image = UIImage(named: dataArray[indexPath.row])
return cell
}
It seems you want your table view to contain the values in your cellArray array plus one extra special row at index 0.
In order to do this you need to indicate that there is an extra row and your indexing needs to account for the extra row.
But a simpler approach is to use multiple sections in your table view. Use section 0 for the extra special row and use section 1 for the values in your cellArray.
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ? 1 : cellArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell") as! MainTableViewCell
return cell
} else {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell") as! CustomTableViewCell
cell2.cellImage.image = UIImage(named: cellArray[indexPath.row])
return cell2
}
}
Make sure you adjust for the use of multiple sections in any other table view method you may implement (such as didSelectRowAt, etc.).
For the sake of comparison, here is how you would need to change your code if you want all of the rows in one section:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellArray.count + 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell") as! MainTableViewCell
return cell
} else {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell") as! CustomTableViewCell
cell2.cellImage.image = UIImage(named: cellArray[indexPath.row - 1])
return cell2
}
}
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
}
}
Only those cell are displaying which are fitting on screen. if scrolled to next(offscreen) cell only white screen is displayed. it allows to scroll but only white space is displayed. Even the last row which was half displayed is also remains half only.
extension LiveTVController: UITableViewDataSource,UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 10
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let reuseIdentifier = tableView.tag == 1 ? ProgrammeListCell.reuseIdentifier : StreamListCell.reuseIdentifier
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
if let cell = cell as? StreamListCell {
cell.programmeList.delegate = self
cell.programmeList.dataSource = self
}
return cell
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return tableView.tag == 2 ? 10 : 0
}
Now after scrolled down for next rows. there are total 10 sections returned and each section have 1 row.
Specify the height of cell according to cell type.And also place this video view in a table view header instead of using cell for first element.