Setting textAlignment doesn't fully right align UILabel - ios

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.

Related

Swift: Images placed in a tableviewcell are not visible

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "approve_cell");
let event = self.events[indexPath.row];
cell.textLabel?.text = event.name;
return cell;
}
I placed 2 images and a label in tableviewcell. When i run the app, images are not visible. What could be the reason?
Check that you are not using the basic style of the UITableViewCell because if you are then that style only includes labels.. no image views. Change it to subtitle or one of the details.
For reference, see: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
You probably forgot to set AutoLayoutConstraints of your image view. You could either add constraints to that image view through storyboard or through code. The other method is setting the frame of your image view in -(void)viewDidLayoutSubviews, because when you're using auto-layout, the layout of those views will be undefined if its constraints doesn't fulfill system's computing need. So you should either set right constraints or give a specific frame to those undefined views after all of the others has-constraints-views are arranged.
You creat cell in storyboard but you never use this cell created from storyboard. instead you manually creat it by UITableViewCell's designated initializer without override layout method of it.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "approve_cell", for: indexPath)
let event = self.events[indexPath.row];
cell.textLabel?.text = event.name;
return cell;
}
You need to set either Autolayout or used Autoresizing. For autolayout just pinned the proper leading, trailing, top and bottom constraint.

Adding Margins to Prototype Cells in UITableView

How can I add top, bottom, left, and right margin spacings between each individual prototype cell in UITableView? (storyboard) Seems there are different solutions for different versions of iOS and none for swift yet.
Current Cell
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("OptionCell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = self.options[indexPath.row]
cell.textLabel?.textAlignment = NSTextAlignment.Center
cell.layer.cornerRadius = 5.0;
cell.layer.borderColor = UIColor.whiteColor().CGColor
cell.layer.borderWidth = 1.5
cell.backgroundColor = UIColor.clearColor()
return cell
}
You can't set margins between cells, but you can make it look like there are margins by giving the cell a clear background color, and adding a subview (to which you would add any other subviews you need) that is inset from the edges of the cell by whatever margins you want. Give this view a background color, and turn off the cell separators. This can all be done in IB with no code if you choose.

UITableView, registerClass and detailTextLabel -- strange behavior

Recently I noticed the following behavior and I can't understand why does it work as it is.
I have a UITableView on my storyboard and the following code in the view controller:
override func viewDidLoad() {
super.viewDidLoad()
self.threadsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell? = self.threadsTableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")
}
cell!.detailTextLabel!.text = "str"
}
In this case application crashes at the
cell!.detailTextLabel!.text = "str"
line because detailTextLabel is nil
Then I decided to remove the registerClass function call and noticed that code doesn't really crash anymore, but dequeueReusableCellWithIdentifier function call returns nil every time. I think that I don't somehow enable the "Subtitle" style of the table view's cells in the storyboard, but I don't see any option like this in the Interface Builder.
What am I doing wrong? How can I fix it?
Thanks in advance.
In your storyboard, do you have prototype cells within your tableView? If not, drag a table view cell in from the object library (bottom right) and embed it in the table view. You can then use the attributes inspector for that cell to set the reuseIdentifier. If the cell style defaults to "Custom", amend it to "Subtitle" - IB will then automatically add labels for textLabel and detailTextLabel (and will hook them up to the outlets in UITableViewCell). See below:

Self Sizing Cell in Swift, how do I make constraints programmatically?

I'm trying to do a sidebar with self sizing cells in swift. I found this great tutorial : http://www.appcoda.com/self-sizing-cells/
As far as I know you need 3 things to make a self sizing cell:
Define auto layout constraints for your prototype cell
Specify the estimatedRowHeight of your table view
Set the rowHeight of your table view to UITableViewAutomaticDimension
The last two are covered in the tutorial by code, but the first one is explained by the story board, and my problem is how do I implement it by code??
I have this method where I get my custom cell, I think that I have to implement the constraints(in the tutorial you can see what kind of constrains) here but I don't know how, so please could you give me some help?
override func tableView(tableView: (UITableView!), cellForRowAtIndexPath indexPath: (NSIndexPath!)) -> UITableViewCell{
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CellId")
cell!.backgroundColor = UIColor.clearColor()
cell!.textLabel?.textColor = UIColor.darkTextColor()
let selectedView:UIView = UIView(frame:CGRect(x: 0, y: 0, width: cell!.frame.size.width, height: cell!.frame.size.height))
selectedView.backgroundColor = UIColor.orangeColor().colorWithAlphaComponent(0.3)
cell!.selectedBackgroundView = selectedView
//asignar valores a la celda
cell!.textLabel?.text = tableData[indexPath.row]
cell!.textLabel?.numberOfLines = 0
cell!.setTranslatesAutoresizingMaskIntoConstraints(false)
}
return cell!
}
Update 1:
The text goes beyond the 3rd break of line in the 1st and the 3rd row, but here only show me max. of 3 breaklines
Thanks!
Don't add layout constraints in tableView(_:cellForRowAtIndexPath:).
You should not instantiate a table view cell in that method yourself. Instead, you should register one with the UITableView (probably in the viewDidLoad() method of your view controller) (registerClass(_:forCellReuseIdentifier:) or registerNib(_:forCellReuseIdentifier:)).
In tableView(_:cellForRowAtIndexPath:) you use dequeueReusableCellWithIdentifier(_:forIndexPath:) to get an instance of the cell. The table view will reuse cells as you scroll, so that it doesn't have to create new ones all the time. Essentially, let's say you never see more than 15 cells on screen at the same time, then there won't be more than that many instances.
Now, when you register your table view cells (see above) you should probably subclass UITableViewCell and then either set your layout constraints in code (maybe override init(style:reuseIdentifier:)) or you can create a .nib file and use that. Then you can set up the constraints in Xcode through the graphical UI.
Let me know if you have any questions.
I found a good function to make cell dynamic size
func dynamicHeight(text:String, font:UIFont, width:CGFloat) -> CGFloat{
let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.height
}
Call this function in heightForRowAtIndexPath
I hope it works.
Try this:-
First add this two functions in your class
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Second in order to make the UITableViewAutomaticDimension work make sure you have added all the left, right, bottom, and top constraints relative to cell container view.

How to add more than 2 detailTextLabel in TableView (Swift)

I tried to add many details (fields) to display in TableView. by concat each fields and put in for detailTextLabel e.g.:
From:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!{
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier:"test")
cell.textLabel.text = taskMgr.tasks[indexPath.row].name
cell.detailTextLabel.text = taskMgr.tasks[indexPath.row].desc
return cell
}
To
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Test")
cell.textLabel?.text=tasksList[indexPath.row].name
var yString = tasksList[indexPath.row].desc
var xString = tasksList[indexPath.row].amnt
var zString = xString+" "+yString
cell.detailTextLabel?.text=zString
return cell
}
Could anyone point out any other ways for better code for many fields to display in the view.
I think your first method is great. In storyboard inside a prototype cell you can place several UILabels. Then just update each label as you did. You can place labels in a xib or create them in code. But there is nothing wrong with having several labels and then updating them individually. This gives more flexibility that concatenation because you can justify the text in each label as required to make the tableview pretty. So each cell row has good alignment with the one above it.

Resources