I have a UITableView and have cells in it and I am using textLabel and detailTextLabel in it along with a accessoryView which is a disclosureIndicator. These are my constraints.
if (cell.contentView.constraints.count == 0) {
cell.textLabel?.translatesAutoresizingMaskIntoConstraints = false
cell.detailTextLabel?.translatesAutoresizingMaskIntoConstraints = false
let margins = cell.contentView.layoutMarginsGuide
// TextLabel constraints
cell.textLabel?.leftAnchor.constraint(equalTo: margins.leftAnchor).isActive = true
cell.textLabel?.centerYAnchor.constraint(equalTo: margins.centerYAnchor).isActive = true
// DetailTextLabel constraints
cell.detailTextLabel?.rightAnchor.constraint(equalTo: margins.rightAnchor, constant: -10).isActive = true
cell.detailTextLabel?.leftAnchor.constraint(equalTo: (cell.textLabel?.layoutMarginsGuide.rightAnchor)!, constant: 10).isActive = true
cell.detailTextLabel?.centerYAnchor.constraint(equalTo: margins.centerYAnchor).isActive = true
}
Now when the Table View is first loaded I see everything fine i.e detailTextLabel is -10 points away from contentView but when I tap the cell the detailTextLabel shifts to the right and hugs to the contentView as if -10 point constraint isn't even there. Now when I come back to this VC again, I still see detailTextLabel hugging to contentView i.e reloadData is not taking any effect. But if I dismiss this VC and come back again here my constraint and in place like they should be and the problem comes up again when I tap on the cell to go to the next screen.
I have a reloadData() call in my viewWillAppear which gets called but doesn't produce any effect.
I hope I am able to explain myself, am I doing anything wrong here?
The problem is that you are using a built in cell type, where the text label and detail label are built in and don’t belong to you. They belong to the cell. The cell repositions them on selection. You are fighting the cell.
If you want to customize a cell’s appearance and change the position of the cell labels, use a custom cell type, and give it custom labels that belong to you. You can given them constraints right in the storyboard designer. Do not use the built in text label and detail label at all.
You cannot change the constraints of the cell labels if it is not a custom type cell. If you want custom constraints then you should create your own custom cell which inherits from UITableViewCell and set your own constraints.
Related
Update:
I have found that the problem occurs because of the date labels top constraint when removed the wrapped text becomes visible. The issue is then the date label is under the other text. Could the real problem be that the cell is not dynamically changing based on the constraints?
I am trying to make text in a UILabel to wrap (at the same time I am trying to make the cell change based on the text)
In the .xib I setup the cell, doing this:
self.notifInfoLabel.numberOfLines = 0
self.notifInfoLabel.lineBreakMode = .byWordWrapping
sizeToFit is called right before returning the cell in the delegate method.
cell.notifInfoLabel.sizeToFit()//EDIT: turns out this is not needed
return cell
}
The configure method is called on viewDidLoad and right before .reloadData()
func configureTableView() {
self.tableView.estimatedRowHeight = 82
self.tableView.rowHeight = UITableView.automaticDimension
}
Currently, the text in the label seems to wrap underneath the date label...
How can I make it work as intended?
You have confusing constraints for Auto layout engine.
You want some space from bottom of image view if text is small , And
you want text to dynamic in that case label should grow.
Solution is very simple.
Bottom constraint of Imageview change = to >= with 750 priority
Bottom constraint of Date change = to >=
Hope it is helpful
I'm having a problem with my table view cells as they do not adjust automatically with its content.
I have a label for a title and another label for a name. There is a text view below the two labels which is never displayed when the simulator runs.
This is
what the Table View Cell is supposed to look like, however, this is what the Table View Cell displays.
I have pinned all elements inside the table view cell to the content view using constraints. I read up that adjusting the table view cell height itself will not work, so, I have to adjust the height from the table view itself.
It is set to automatic but it is not adjusting as seen here. I have also tried to set the estimated height to automatic but to no avail. The only solution was to set a custom height but it would look extremely weird if the text view contains only a few text as there would be a large white space. I did not add any code at all to adjust the size.
These are the following constraints:
Table View
Name Label
Title Label
Text View
First You need to add height constraint for textview and add its IBOUTlet then you need to override the updateconstraint of cell and do following in update constraints method.
override func updateConstraints() {
super.updateConstraints()
self.textViewHeightConstraint.constant = self.textView.contentSize.height
}
and also for name label add bottom constraint.
By default the UITextView will not resize itself to fit its content. While you could use #Waqas Sultan approach, I would recommend to let the textView size itself. To achieve that, just use this:
textView.isScrollEnabled = false
Or, in storyboards, find the Scroll Enabled attributed and uncheck it.
This would make textView to size itself.
However, from the constraints you show it is hard to tell if there are really enough constraints to determine the proper frames for all the content - there are constraints related to Review label, but who knows how you constrained that label.
Not seeing all the relevant constraints in the tableView cell, I cannot guarantee that this will be enough to make it work as you expect (you might have forgotten about just a single one constraint, and it might be messing up your whole layout).
Hey buddy i would like you to try this way.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == desiredIndexPath { // the index where you want automatic dimension
return UITableViewAutomaticDimension
} else {
return 100 // the height of every other cell.
}
}
note: Make sure that you do not give height to the label. Otherwise the label wont expand according to content.
I have searched but couldnt find an answer.
Is there a way to make only one specific cell overlap other cell and the rest cells be laid out in default layout.
Yes this is possible very easily. You can make the views inside of the cell overlap the other cells. So just add a subview to your UITableViewCell that overlaps the cells bounds. You could for example use auto layout constraints to position them outside the view or you just give the cell a lower height than its subview.
Then you need to make sure, that your that your cells subviews can be displayed outside of its bounds. You need to set clipsToBounds for this:
let cell = tableView.dequeueReusableCell(withIdentifier: "OverlapCell")
cell?.contentView.clipsToBounds = false
cell?.clipsToBounds = false
Also it is important to set the zPosition of your cell in order to make it appear above all other cells.
cell?.layer.zPosition = 10
Hope this helps.
I have a label in cell and I want to change the position of the label when swiping the cell.
For example, when swiping cell to left, label will be moved to right.
I didn't find any delegate for swiping to add some point in label constraint.
There is UISwipeGestureRecognizer so you can use that for recognition. You can use that for cell, in you cellForRow add that to each cell. Than you can use delegate for the cell to return self. Add leading or trailing constraint of your label as outlet in your cell. You can change constraint like this:
labelConstraint.constant = 0
UIView.animateWithDuration(1.0) {
self.view.layoutIfNeeded()
}
Edit:
If swipe to delete is enabled: Override willTransitionToState method in your custom cell and detect delete state or use tableView's willBeginEditingRowAtIndexPath and change there constant of your constraint
In a tableview one cell overlaps the cell displayed under it when initially presented. When you scroll down until the top cell is not longer visible and then scroll back up the cell are ok again.
I deactivated the separators with this line:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
The second cell has a view that fill it from top to bottom, that was a border radius. When the cells are initially presented the border is covert.
How can i fix the spacing of the tableviewCells when they are initially loaded? Can i set the z index the second cell, so that the second cell is above the first one?
I finally found that the constraint of the the top cells where causing the trouble. I found a workaround by storing the layout constraint in a property and adjusting the constant of the constraint as needed.
For "Can i set the z index the second cell, so that the second cell is above the first one?"
UITableViewCell is subclass of UIView so in table view delegate use this :
secondCell.layer.zPosition = 1;