UITableViewAutomaticDimension not working properly with Subtitle UITableViewCells - ios

I'm creating a 2 sections UITableView. The first section uses UITableViewCells with the Default style, the second uses Subtitle style. Both cells may have a multiline text label.
I've set the table's rowHeight to UITableViewAutomaticDimension.
As you can see from the screenshot below, UITableViewAutomaticDimension is respected only partially when using the Subtitle style: the height seems to fit the textLabel's height but not the detailLabel's one.
How can i make a Subtitle cell getting the right height?
Some code:
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.estimatedRowHeight = 80
tableView.rowHeight = UITableViewAutomaticDimension
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "defaultCell")
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "subtitleCell")
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section === 1 {
var cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "subtitleCell")
cell.textLabel?.numberOfLines = 0
cell.textLabel?.text = "A Long text..."
cell.detailTextLabel?.numberOfLines = 0
cell.detailTextLabel?.text = "A Long text..."
return cell
}
else {
var cell = tableView.dequeueReusableCellWithIdentifier("defaultCell") as! UITableViewCell
cell.textLabel!.text = "A long text..."
cell.textLabel?.numberOfLines = 0
return cell
}
}
I've tried to implement a subclass of UITableViewCell but I many problems with autolayout and section titles (a long story), so I wonder if I could fix the issue in a simpler way.

Just tried on Xcode 9 and iPhone 8 simulator, works very well.
code is here https://github.com/williamhqs/testSubtitleCellLayout

Related

How to adjust label height and width in custom tableView Cell

I have a expandable tableView, in which when i expand a section, than there are three cell. On firth Cell there is only name and in second cell. It have a big content. Now I want to auto adjust this label height and width according to content.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tblView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
let dataArrayTblView = dataArrayForTableView
let titleName = dataArrayTblView.valueForKey("name")
let dueDate = dataArrayTblView.valueForKey("deadlinedate")
let description = dataArrayTblView.valueForKey("description")
cell.titleLabel.text = titleName[indexPath.row] as AnyObject! as! String!
cell.dueDateLabel.text = dueDate[indexPath.row] as? String
cell.descriptionLabel.text = description[indexPath.row] as? String
cell.descriptionLabel.sizeToFit()
cell.textLabel?.backgroundColor = UIColor.clearColor()
cell.selectionStyle = .None
return cell
}
But not getting complete content
Try to set this. It will automatically adjust the height of the row for you. If it is not working, then you have something wrong with your constraints inside your storyboard.
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 40
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
You should use UITableViewAutomaticDimension as row height something like,
// this should be set in viewDidload
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
for that you must use autolayout and should set proper constraints to your label in cell.
Constraint should be in linear chain, I mean your label's top and bottom both constraint must be set and your label should resize according to content so your cell will resize accordingly!
You can refer Self-sizing Table View Cells by Raywenderlich !
Put below in viewDidLoad and set autolayout as per below screenshots.
tblview.rowHeight = UITableViewAutomaticDimension
tblview.estimatedRowHeight = 44
Screenshot 1
Screenshot 2
Screenshot 3
Screenshot 4
Use heightForRowAtIndexPath method to adjust height of row. Calculate
size of string with boundingRectWithSize this method. example:
Try This:
if let YOUR_STRING:NSString = str as NSString? {
let sizeOfString = ns_str.boundingRectWithSize(
CGSizeMake(self.titleLabel.frame.size.width, CGFloat.infinity),options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: lbl.font], context: nil).size
}

How to add spacing between UITableViewCells - Swift

I have a table with some customizations.
Here is my code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
var exercises : [String] = ["Swimming", "Running", "Weight Lifting", "Biking", "Climbing"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
//Necessary for basic tableView setup. Defines number of rows in a specific section.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
//Setting the amount of rows to the number of elements in exercises. This function returns that.
tableView.backgroundColor = UIColor.clearColor()
return exercises.count
}
//Necessary for basic tableView setup. Helps us out content for every cell in the index path. Runs = rows
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
tableView.separatorColor = UIColor.clearColor()
//Setting the footer to default so the extra junk does not show
tableView.tableFooterView = UIView()
//This will be returned. This automatically creates a prototype cell
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
//Setting every cell to the respective item in exercises
cell.textLabel?.text = exercises[indexPath.row]
cell.textLabel?.font = UIFont(name: "Avenir-Light", size: 17)
cell.textLabel?.textColor = UIColor.whiteColor()
cell.textLabel?.textAlignment = .Center
//Border Code
cell.layer.borderWidth = 2.0
cell.layer.borderColor = UIColor.whiteColor().CGColor
//Round Corners
cell.layer.cornerRadius = 20
return cell
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.backgroundColor = UIColor.clearColor()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I want to have some spacing between each UITableViewCell. I have already tried the following:
Change the height of each row. This option does not work because I have borders. Adding more height just makes each row look larger.
Convert each row into a section and then use heightForHeader in section.The post. I want to avoid this option because I would have to convert all my rows to sections.
Add a transparent UIView within each row. Again, this option does not work because I have borders.
Is there any other alternative?
Thanks
First of all, you should move tableView related code out of tableView:cellForRowAtIndexPath, preferably to viewDidLoad:
override func viewDidLoad {
super.viewDidLoad()
tableView.separatorColor = UIColor.clearColor()
tableView.tableFooterView = UIView()
}
Secondly, UITableViewCells are reusable objects so they are dequeued by the tableView when required:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell")
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
...
}
As for your problem, you should either set rowHeight on tableView
override func viewDidLoad {
super.viewDidLoad()
...
tableView.rowHeight = 100.0
}
or implement tableView:heightForRowAtIndexPath: instead:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100.0
}
You should also update textLabel's border and corner radius value instead of the cell:
//Border Code
cell.textLabel.layer.borderWidth = 2.0
cell.textLabel.layer.borderColor = UIColor.whiteColor().CGColor
//Round Corners
cell.textLabel.layer.cornerRadius = 20
I tried ozgur's method but it didn't work because I had borders between my table view cells. Eventually, I used the answer from this post. Hope it helps
You can add spacing by creating an extra view inside the cell that contains the content of the cell that has spacing between the top and the bottom. Make the background color of the cell translucent and it'll appear as though the cell has spacing above and below it

iOS TableView Multiline text

I have this table and I want the lines to be multiline text.
How can I achieve this? This is the way I read everywhere.
This is my code to setup my cells:
let cell = tableView.dequeueReusableCellWithIdentifier("SchoolCell", forIndexPath: indexPath)
if searchController.active && searchController.searchBar.text != "" {
cell.textLabel?.text = filteredSchools[indexPath.row].name
} else {
cell.textLabel?.text = schools[indexPath.row].name
}
cell.backgroundColor = ColorsPlus.instance.VLDMediumBlue()
cell.textLabel?.textColor = UIColor.whiteColor()
cell.textLabel?.font = UIFont(name: "TitilliumWeb-Regular", size: 16.0)
cell.selectedBackgroundView?.backgroundColor = ColorsPlus.instance.VLDDarkBlue()
cell.textLabel?.numberOfLines = 0
cell.textLabel?.sizeToFit()
Add UITableViewCell in your tableView in storyboard.
Set number of lines equal to zero in interface builder. You are setting after cell has been instantiated and height already been calculated.
You should have autolayout enabled and constraints setup for the label, enough to determine the height of cell. In your case, set top, bottom , left and right constraint.
Set tableView.height = UITableviewAutomatic;
This should result in multi-line text with dynamic cell height.
Or if you are not interested in dynamic cell height, then simply increase UITableCellView height in tableView Delegate
override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
return 60.0;
}
or simply update the default height as below
self.tableView.rowHeight = 60.0

Swift Tableview always showing separator lines

I seem to have a weird problem with one of my tableviews where I can't hide the separator lines ( I think they're separator lines, except that they're centred on the screen instead of hard up against the right hand side ).
I create everything programmatically so no storyboard issues here.
You can see the tiny 1px line above each of the cells below.
I load my table using:
self.tableView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.tableView.backgroundColor = UIColor.whiteColor()
self.tableView.scrollEnabled = true
self.tableView.bounces = false
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
self.view.addSubview(self.tableView)
I also have a custom header which I implement using the following code:
func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let header:UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
header.textLabel.textColor = UIColor.whiteColor()
header.textLabel.frame = header.bounds
header.textLabel.textAlignment = NSTextAlignment.Center
view.tintColor = constants.getTintColor()
header.textLabel.textColor = UIColor.whiteColor()
}
I've tried loading the table without the willDisplayHeaderView and the issue persists.
I have also tried adding
tableview.separatorStyle = UITableViewCellSeparatorStyle.None
and
tableView.separatorColor = UIColor.clearColor()
to the following methods:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
return self.boards.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
return self.boards[section].items.count
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
return self.boards[section].name
}
EDIT:
The cells are standard UITableViewCells with alternating colors for the cells, this is being set through:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
cell.selectionStyle = UITableViewCellSelectionStyle.None
if indexPath.row % 2 == 0 {
// Even
cell.backgroundColor = constants.UIColorFromRGB(0x1EACE0)
} else {
// Odd
cell.backgroundColor = constants.UIColorFromRGB(0x6FBEE5)
}
cell.textLabel?.textColor = UIColor.whiteColor()
cell.textLabel?.text = self.boards[indexPath.section].items[indexPath.row].title
return cell
}
EDIT 2:
I've now added separator lines in and these aren't separators because you can still see them below the separator line.
HELP! I'm confused. I have a number of other tableviews setup the same (as far as I can see) and they work fine.
Thanks SO!
You can either use the Table View property for the seperatorStyle and use the property as such UITableViewCellSeparatorStyleNone
or use remove the separator from the StoryBoard
Set the property of the Seperator to None
Or one thing more while you are using header and Footer so the separator line would be Zero but there might be a extra separator or header and footer so refer to this link
Eliminate extra separators below UITableView
in your viewDidLoad() function, add this:
tableView.tableFooterView = UIView()
Since you are not using custom cell's you need to do the following.
Create cell's as let cell : UITableViewCell = UITableViewCell(style:UITableViewCellStyle.Subtitle, reuseIdentifier:"cell")
and remove self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
Here's a little additional information about eliminating the spurious separators that might be helpful. The solution that the originator said worked was this one that creates a new cell:
let cell : UITableViewCell = UITableViewCell(style:UITableViewCellStyle.Subtitle, reuseIdentifier:"cell")
But the originator did not say how he worked this into his code, whose original version used the two argument version of dequeueReusableCellWithIdentifier:
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
I experienced the same problem of spurious separators and found that using the single argument version of dequeueReusableCellWithIdentifier also fixes the problem:
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
I ran into same issue recently, and finally fixed by this in cell's init:
self.contentView.backgroundColor = UIColor.AppBgColor;
self.backgroundColor = UIColor.AppBgColor;
If you look closely in View Hierarchy, the cell's background and it's contentView's background are not same, which leads to this issue.

Setting textAlignment doesn't fully right align UILabel

I have some UITableViewCells and I want each of them to have two labels: one left aligned, one right aligned. The problem I'm having is that the right-aligned labels come very close but still not quite properly aligned. To be honest, I'm not entirely sure if I've even implemented it the correct way.
Here's a screenshot:
(a link because I need 10 rep to embed images)
Here's my tableView function:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = "Row \(indexPath.row)"
var secondLabel = UILabel(frame: cell.frame)
secondLabel.textAlignment = NSTextAlignment.Right
secondLabel.text = "Label \(indexPath.row)"
cell.textLabel?.addSubview(secondLabel)
return cell
}
Does anybody have any ideas?
I've fixed it by following Dreaming in Binary's suggestion and making a xib file and adding constraints via the interface builder. I wasn't adding any constraints to the cell previously, so I guess it was a constraint problem.

Resources