How to stretch cell to full screen? - swift

I have a UIView inside a table cell. I need to stretch my cell on full screen.
In my table view I have this:
table.rowHeight = UITableView.automaticDimension
But now I can't to make this.
My code is:
containerView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
verticalStackView.snp.makeConstraints { make in
make.center.equalToSuperview()
make.leading.trailing.equalToSuperview().inset(20)
}
I need to get this:
But I have:

So UITableView.automaticDimension will tell the program to find the minimum height this cell can be without any clipping (to simplify it)
What you'll need to do is intercept the cell in
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if self.myData.isEmpty {
return tableView.frame.height
}
return UITableView.automaticDimension
}
Assuming you show that cell when there Is no data to be shown, you can just do a check to see if you data array isEmpty, and if so, make the cell the height of the tableView

Related

Expandable table cell content overflowing from cell

I have an expandable tableview in my project as part of my tableviewcontroller. The issue is that when the table is not expanded, the rest of the cell is displayed anyway, overlapping with the next cell. The method I used to create expandable tables is from this tutorial: https://dev.to/lawgimenez/implementing-the-expandable-cell-in-ios-uitableview-f7j
I think they changed some things because this code was written in an older version of xcode and swift.
I have tried changing some properties of the cells and the tableview but nothing has worked so far.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableViewData[indexPath.row].opened = !tableViewData[indexPath.row].opened
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if tableViewData[indexPath.row].opened == true {
return 99.5
}
else {
return 40.5
}
}
I expected the cell in the tableview to cut off the custom cell at the exact height of the cell in the tableview but instead the cell is small when not expanded but all of the custom cell is diaplayed and overflows from assigned area for the cell.
You should use
tableView.reloadRows(at: [indexPath], with: .automatic)
instead of
tableView.reloadData()
Another thing, you should use
if tableViewData[indexPath.row].opened {
}
instead of
if tableViewData[indexPath.row].opened == true {
}

Swift Changing the size of tableview cells

just like the title says I'm searching for a way to change the size of each cell in my tableview. I have 2 questions:
1) How can I change the size of all cells by the same amount in my tableview?
2) Is it possible to automatically adjust the size of the cell based on the length of the text in that particular cell?
I'm aware that there are already similar questions asked before but I couldn't manage to implement their answers correctly as they've been outdated for some time now. I'd appreciate any help, thank you in advance!
1) To change size of all cells with same type, first you need to create CellType, here is the explanation how to do this.
https://stackoverflow.com/a/51979506/8417137
or you can check for indexPath.row, but it's not cool :)
Than here:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch cellType {
case firstType:
return firstCellTypeHeight
case secondType:
return secondCellTypeHeight
default:
return defaultCellHeight
}
}
2) Yes, its possible. You create your CustomCell. In your CustomCell you should
setup your textFields or labels inside ContentView. Your views with text will stretch your cell.
Important thing. In method above you must return special height like that.
return UITableViewAutomaticDimension
For example your code will looks like that.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch cellType {
case firstType:
return firstCellTypeHeight
case secondType:
return secondCellTypeHeight
// Your stretching cell
case textCellType:
return UITableViewAutomaticDimension
}
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
switch cellType {
case firstType:
return firstCellTypeHeight
case secondType:
return secondCellTypeHeight
// Your stretching cell
case textCellType:
return UITableViewAutomaticDimension
}
}

Dynamic cell size with resize cell animation

I have a table view with a dynamic height of cells. Above the table is menu with buttons. When I click on the menu button, the data is loaded into the table. When data is loaded, I want to have an animation in a cell that changes the height of a cell. I wonder how this can be done?
Thanks for the help.
Swift 4
Create a boolean variable in your model for checking if your cell is expanded or not.
if you want to expand the cell as long as your label height you should connect you labels constraint to your contentView in all directions and set number of lines to 0 in your storyboard.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
details[indexPath.row].cellIsOpen = !details[indexPath.row].cellIsOpen
detailTableView.reloadData()
detailTableView.beginUpdates()
detailTableView.endUpdates()
detailViewHeightConstraint.constant = CGFloat(detailTableView.contentSize.height) // the height of whole tableView
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if details[indexPath.row].cellIsOpen {
return UITableViewAutomaticDimension // or any number you wish
} else {
return 60 // default closed cell height
}
}
}
Also you can place this two lines in your viewDidLoad() function:
detailTableView.estimatedRowHeight = 60
detailTableView.rowHeight = UITableViewAutomaticDimension

Dynamically Resize one Static Table View Cell's Height in Swift

I am trying to do as the title suggests dynamically allocate a certain height dependent on the height of the users device. I have, right now a table view of 8 static cells and in the last one it contains a container view that points to a another table view controller of dynamic cells, Image posted below. Everything was done through to story board so far, however, since there is no way for me to "constrain" a single cell like I can with other elements I was hoping for a solution to my problem here.. Basically in the last cell, the static cell has to dynamically change its height based of the coordinates of "Height of users phone" - "Y coordinate of 7th static cell" is what I would imagine.
For what I understand, if all the cells have the same high except the last, what you have to do is implementing the method heightForRowAtIndexPath. For the last cell you make the calculation that you need. I give you an example
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 8 {
//Returns UITableViewAutomaticDimension or the size you have calculated
return UITableViewAutomaticDimension
} else {
return x.x
}
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 8 {
//Returns UITableViewAutomaticDimension or the size you have calculated
return UITableViewAutomaticDimension
} else {
return x.x
}
}

swift tableview image and label

I can't seem to figure how to have a tableview that contains a subject, body and image so that if there is not an image to have the subject and body together. see imageauto lay with table prototype
I would like the subject and body together when there is an image in the database and then if there is an image, then subject image body
pin the labels to the top and bottom of the cell. When you don't have an image you set the imageView.isHidden = true. You also return the regular cell height minus the imageView.frame.size.height in UITableViewDelegate.tableview(_:heightForRowAt:).
If you don't like approach just make two different tableViewCells and deque the one with the image when you have an image and the one without the imageView when you don't have an image.
You can do this in your dataSource methods for the tableview. Something like this should work:
//Model:
var model = [Stuff]
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myprototype", for: indexPath)
cell.subjectLabel.text = model[indexPath.row].subject
cell.bodyLabel.text = model[indexPath.row].body
//assuming the image is an optional
if let image = model[indexPath.row].image {
cell.imageView.image = image
}
return cell
}
You might have to set the autolayout constraints for the imageView to have a low compression resistance.
You might also want to make the cells resize by implementing the following in the UITableViewDelegate methods:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}