Set tableview row height to label height - xcode

I have a label and an image.
if image != nil {
cell height = 445
} else {
//how do i set the cell height according to the label?
}

You should set the height of tableView cells in heightForRowAt. This function returns the height of the cell for a given indexPath (as you probably have guessed). Inside there you can use return label.frame.height
In Swift 3:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if image != nil {
return 445
} else {
return label.frame.height
}
}
Edit: You can't use cellForRowAt until cells are initialized in cellForRowAt. So Try this instead. It assumes the image and label are #IBOutlets

Related

swift 3: UITable cell multiple lines issue

So Im attempting to create a multiple line text for the suitable cell detailedTitle however when I set the cell.numberOfLines = 0 I get multiple lines but without correct spacings for the cells. I have also tried calling cellAutoDimentions but it made no difference
cell.detailTextLabel?.numberOfLines = 0
I Get the following result when I run that code in my program
enter image description here
as you can see the text if getting pushed out of the cell's bounds in this case I'm talking about the top and bottom not the right side, that issue i know how to fix by changing the CGRect. Also the code doesn't allow for more than 2 lines
UPDATE:
The following is the entire section of my code
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itorStorage.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.messageField.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MessageCustomCell
cell.backgroundColor = LightBlue
cell.textLabel?.text = itorStorage[indexPath.row].name
cell.textLabel?.textColor = .white
cell.detailTextLabel?.text = itorStorage[indexPath.row].text
cell.detailTextLabel?.textColor = .white
cell.pic.image = itorStorage[indexPath.row].image
cell.timeStamp.text = itorStorage[indexPath.row].time
cell.detailTextLabel?.numberOfLines = 0
cell.detailTextLabel?.lineBreakMode = .byWordWrapping
return cell
}
override init() {
super.init()
messageField.delegate = self
messageField.dataSource = self
messageField.tableFooterView = UIView(frame: CGRect.zero)
messageField.rowHeight = UITableViewAutomaticDimension
messageField.allowsSelection = false
self.messageField.register(MessageCustomCell.self, forCellReuseIdentifier: "Cell")
ratingView.didFinishTouchingCosmos = didTouchCosmos
}
I think you need to implement estimatedHeightForRowAt as well as setting rowHeight to UITableViewAutomaticDimension. Something like this:
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 120.0
}

Xcode Storyboard - Where to set UITableViewCell height

I am using Xcode 7 and I am trying to set the height of a UITableViewCell in the storyboard settings to have a different cell height for different devices (eg. normal and compact x regular).
I cannot find a place for these settings. Is this only possible by doing it programmatically?
Click on Table View after that click on Size Inspector
and adjust your cell row height here -
Add this below code in your controller class viewDidLoad
tableView.estimatedRowHeight = 100.0 // Adjust Primary table height
tableView.rowHeight = UITableViewAutomaticDimension //This line adjust cell height according to containts
Swift 4 or later
You need to change from UITableViewAutomaticDimension to UITableView.automaticDimension
tableView.estimatedRowHeight = 100.0 // Adjust Primary table height
tableView.rowHeight = UITableView.automaticDimension
Go to the storyboard, find you table view and select the cell. You will notice a white square at the bottom middle of the cell. You can drag it to change the cell height.
You can set UITableView height in this way.Try this code
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath(NSIndexPath *)indexPath
{
if UIDevice.currentDevice().userInterfaceIdiom == .Phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
{
return 97
}
if UIDevice.currentDevice().userInterfaceIdiom == .Phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
{
return 115
}
if UIDevice.currentDevice().userInterfaceIdiom == .Phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
{
return 135
}
if UIDevice.currentDevice().userInterfaceIdiom == .Phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
{
return 150
}
return 90
}
You can set height from user interface and to reflect your set value you need to override table view heightForRowAt method e.g.
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 73
}

How to load images from Images.xcassets into a UIImage

I am trying to code images to UIImage but I am having trouble. I am not sure how code it for each different image per list item. The app I am building is a List with pictures attached to each list item.
Below is the MyWhatsit class:
class MyWhatsit {
var name: String {
didSet {
postDidChangeNotification()
}
}
var location: String {
didSet {
postDidChangeNotification()
}
}
var image: UIImage? {
didSet {
postDidChangeNotification()
}
}
var viewImage: UIImage {
return image ?? UIImage(named: "camera")!
}
init( name: String, position: String = "" ) {
self.name = name
self.location = location
}
func postDidChangeNotification() {
let center = NSNotificationCenter.defaultCenter()
center.postNotificationName(WhatsitDidChangeNotification, object: self)
}
}
Below is the Table View:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return things.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let thing = things[indexPath.row] as MyWhatsit
cell.textLabel?.text = thing.name
cell.detailTextLabel?.text = thing.location
cell.imageView?.image = thing.viewImage
return cell
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
things.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
I believe all you need to do is create an array of images like you are with the title and subtitle. When you add another picture, add the image name to the array and append the tableView.
What I see in your code is a name and position. It looks like you need to add "image" and set it to the name of the image. For example, MyWhatsit(name: "Bob Smith", position: "midfielder", image: "bobSmithImage")... and then you set the cell's image view equal to the image name.
Hope this gets you moving!
You need to create your own personal category. For example sorting your players based on positions they play. Using a class that stores your images into an array. For example:
let goalkeeper = [UIImage(named:"ivanlucic"), UIImage(named:"manuelneuer")]
let rightBack = [UIImage(named:"danialves"), UIImage(named:"sergioramos")]
After you have a list of images, inside your cellForRowAtIndexPath you can do a checking, and reference it to the array your created.
Didn't get how you are setting the code in the tableview but you can add image name with names like
Where image key contains the image name you have stored in the XCAssets
var things: [MyWhatsit] = [
MyWhatsit(name: "Ivan Lucic", position: "Goalkeeper","image":"ivan"),
MyWhatsit(name: "Manuel Neuer", position: "Goalkeeper","image":"manuel")...]
And you can init the image at the same time you init the name
init( name: String, position: String = "", imagename:string ) {
self.name = name
self.position = position
self.imgview = UIImage(named:imagename)
}

How do I make table cells fit the size of contained images?

I'm trying to figure out how to make a table of images with varying sizes. Where the images get resized to fit the width of the device, and the cells fit the height of the image. Currently the images are getting sized to the table cells.
Xcode project
ViewController
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
var images = ["abstract","city","city2","nightlife"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageTableViewCell
cell.configureCellWith(images[indexPath.item])
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return images.count
}
}
ImageTableViewCell
import UIKit
class ImageTableViewCell: UITableViewCell {
#IBOutlet weak var tableImage: UIImageView!
func configureCellWith(image: String) {
tableImage.image = UIImage(named: image)
}
}
Implement heightForRowAtIndexPath to set the cell height to the correct height for that cell's image.
(You can determine that height by examining the image's width and height, and divide to give the aspect ratio. Now use that aspect ratio to determine the height based on the cell width, which is the table width.)
This is actually fairly simple. You just have to implement heightForRowAtIndexPath function and return height of image for each cell.
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return image[indexPath.row].size.height
}

swift UITableView set rowHeight

I am trying to set the height of each row in the tableView to the height of the corresponding cell with this code:
override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
var cell = tableView.cellForRowAtIndexPath(indexPath)
return cell.frame.height
}
I get this error when initialising var cell :
Thread 1:EXC_BAD_ACCESS(code=2,address=0x306d2c)
For setting row height there is separate method:
For Swift 3
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100.0;//Choose your custom row height
}
Older Swift uses
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100.0;//Choose your custom row height
}
Otherwise you can set row height using:
self.tableView.rowHeight = 44.0
In ViewDidLoad.
Put the default rowHeight in viewDidLoad or awakeFromNib. As pointed out by Martin R., you cannot call cellForRowAtIndexPath from heightForRowAtIndexPath
self.tableView.rowHeight = 44.0
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var height:CGFloat = CGFloat()
if indexPath.row == 1 {
height = 150
}
else {
height = 50
}
return height
}
yourTableView.rowHeight = UITableViewAutomaticDimension
Try this.
As pointed out in comments, you cannot call cellForRowAtIndexPath inside heightForRowAtIndexPath.
What you can do is creating a template cell used to populate with your data and then compute its height.
This cell doesn't participate to the table rendering, and it can be reused to calculate the height of each table cell.
Briefly, it consists of configuring the template cell with the data you want to display, make it resize accordingly to the content, and then read its height.
I have taken this code from a project I am working on - unfortunately it's in Objective C, I don't think you will have problems translating to swift
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
static PostCommentCell *sizingCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tblComments dequeueReusableCellWithIdentifier:POST_COMMENT_CELL_IDENTIFIER];
});
sizingCell.comment = self.comments[indexPath.row];
[sizingCell setNeedsLayout];
[sizingCell layoutIfNeeded];
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
}
Problem Cause:
The problem is that the cell has not been created yet. TableView first calculates the height for row and then populates the data for each row, so the rows array has not been created when heightForRow method gets called. So your app is trying to access a memory location which it does not have the permission to and therefor you get the EXC_BAD_ACCESS message.
How to achieve self sizing TableViewCell in UITableView:
Just set proper constraints for your views contained in TableViewCell's view in StoryBoard. Remember you shouldn't set height constraints to TableViewCell's root view, its height should be properly computable by the height of its subviews -- This is like what you do to set proper constraints for UIScrollView. This way your cells will get different heights according to their subviews. No additional action needed
Make sure Your TableView Delegate are working as well.
if not then
in your story board or in .xib
press and hold Control + right click on tableView drag and Drop to your Current ViewController.
swift 2.0
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 60.0;
}
There is no way to call tableView.dequeueReusableCell from within tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath).
So you have to compute the height from the data.
In my case that was not possible because I have a textView in the cell, which size I did not know.
So I come around with the following strategies:
Do not use tableView.dequeueReusableCell. Just use an array of cells yo have under full control. If your cell is not too large in memory and you don't have too much rows, this is the simplest strategy.
Use a dummy cell, configure it with your data and compute the size.
Try code like this copy and paste in the class
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}

Resources