UITableViewCell frame margins in Swift - ios

I want to enter cell coordinates. When I apply the following code, the cell disappears from the application. How do I adjust the frame margin?
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
cell.layoutMargins = UIEdgeInsets(top: 50, left: 25, bottom: 0, right: 25)
cell.preservesSuperviewLayoutMargins = false
}

For cells, try this:
override func tableView(tableView: UITableView,
willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath)
{
cell.separatorInset = UIEdgeInsetsZero
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
}
But based on the edited information, it seems that you have margin in the container view of the table view. Either this comes from your constraints between table view and view (check them one by one) or you have layout margins in the view, in which case try;
override func viewDidLoad() {
// ...
self.view.layoutMargins = UIEdgeInsetsZero
}

You need to set the row height to be the sum of the desired content height plus the desired margin height.
If all rows are the same height, set the rowHeight property of the table view to a number that is big enough for your needed content height plus the desired top and bottom margin.
If each row is a different height, then implement the heightForRowAt delegate method and return the needed total height (including margin).

Related

Auto layout issue in TableView

I use dynamic height cells for my UITableView with this code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "QuestionsCell", for: indexPath) as! QuestionsCell
cell.label1.text = ""
cell.label2.text = ""
cell.label1.text = some text from array
cell.label2.text = some text from array
cell.label1.lineBreakMode = .byWordWrapping
cell.label1.numberOfLines = 0
cell.label1.sizeToFit()
return cell
}
Then I've pinned all constraints in Storyboard for each element (top, bottom, leading and trailing). On iPhone everything works fine, but on iPad when I scroll the UITableView this is happening (dynamic label height):
sizeToFit() only makes cell1 as big as it needs to be for the text.
You also need to use automatic height sizing for the table view cells.
In viewDidLoad,
self.tableView.rowHeight = UITableViewAutomaticDimension
You will also want to make sure you have a vertical constraint from your bold label to the "12 days ago" label, to ensure there is always vertical space between them, so they don't overlap.
you need to implement this delegate method:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
if this does not work then check if there is vertical spacing constraints between top textView and bottom textView.

spacing between UITableViewCells swift3

I am creating a IOS app in swift and want to add spacing between cells like this
I would like to give space of each table view cell same like my attach image.
How I can do that? and Right now all cells are coming without any space.
swift3
you can try this in your class of tableView cell:
class cell: UITableViewCell{
override var frame: CGRect {
get {
return super.frame
}
set (newFrame) {
var frame = newFrame
frame.origin.y += 4
frame.size.height -= 2 * 5
super.frame = frame
}
}
}
From Storyboard, your view hierarchy should be like this. View CellContent (as highlighted) will contain all the components.
Give margin to View CellContent of 10px from top, bottom, leading & trailing from its superview.
Now, select the tblCell and change the background color.
Now run your project, make sure delegate and datasource are properly binded.
OUTPUT
NOTE: I just added 1 UILabel in View CellContent for dummy purpose.
Update: UIEdgeInsetsInsetRect method is replaced now you can do it like this
contentView.frame = contentView.frame.inset(by: margins)
Swift 4 answer:
in your custom cell class add this function
override func layoutSubviews() {
super.layoutSubviews()
//set the values for top,left,bottom,right margins
let margins = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
contentView.frame = UIEdgeInsetsInsetRect(contentView.frame, margins)
}
You can change values as per your need
***** Note *****
calling super function
super.layoutSubviews()
is very important otherwise you will get into strange issues
If you are using UITableViewCell to achieve this kind of layout, there is no provision to provide spacing between UITableViewCells.
Here are the options you can choose:
Create a custom UIView within UITableViewCell with clear background, so that it appears like the spacing between cells.
You need to set the background as clear of: cell, content view.
You can use UICollectionView instead of UITableView. It is much more flexible and you can design it the way you want.
Let me know if you want any more details regarding this.
One simple way is collection view instead of table view and give cell spacing to collection view and use
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
let widthSize = collectionView.frame.size.width / 1
return CGSize(width: widthSize-2, height: widthSize+20)
}
And if you want tableview only then add background view as container view and set background color white and cell background color clear color set backround view of cell leading, trilling, bottom to 10
backgroundView.layer.cornerRadius = 2.0
backgroundView.layer.masksToBounds = false
backgroundView.layer.shadowColor = UIColor.black.withAlphaComponent(0.2).cgColor
Please try it. It is working fine for me.
You can use section instead of row.
You return array count in numberOfSectionsInTableView method and set 1 in numberOfRowsInSection delegate method
Use [array objectAtIndex:indexPath.section] in cellForRowAtIndexPath method.
Set the heightForHeaderInSection as 40 or according to your requirement.
Thanks,Hope it will helps to you
- Statically Set UITableViewCell Spacing - Swift 4 - Not Fully Tested.
Set your tableView Row height to whatever value you prefer.
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = <Your preferred cell size>
tableView.rowHeight = UITableViewAutomaticDimension
// make sure to set your TableView delegates
tableView.dataSource = self
tableView.delegate = self
}
extension YourClass : UITexFieldDelegate, UITextFieldDataSource {
//Now set your cells.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! UITableViewCell
//to help see the spacing.
cell.backgroundColor = .red
cell.textLabel?.text = "Cell"
return cell
}
//display 3 cells
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
//now lets insert a headerView to create the spacing we want. (This will also work for viewForHeaderInSection)
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//you can create your own custom view here
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: tableView.frame.width, height: 44) //size of a standard tableViewCell
//this will hide the headerView and match the tableView's background color.
view.backgroundColor = UIColor.clear
return view
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
}

How to expand UITableViewCell height in dynamically?

I have a UITableView. In my tableview l I want to dynamically add another view into my cell and expand the cell height. I have seen some examples but those are with UILabels. UILabels can changes the height according to the text height. But how can I manually add another view and expand those cells?
Please help me
Thanks
If you use the manually calculate the cell height,its easy,after you add another view,you calculate the height,then call reloadData or reloadRowsAtIndexPaths,and return the height in tableview:heightForRowAtIndexPath function.
If you use the auto calculate the cell height.you should let system know how to calculate,you should set the autolayout clearly and completely.You should add the another view`s left、right、top、bottom constraint and the system will auto canculate the height.So the cells will Be expanded.
You can set cell height by override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
Implement these two UITableViewDelegate methods:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
// return estimatedHeight
}
View in your dynamic cell needs to have top, bottom, trailing, leading and height constraints. Setting view height constraint constant will set cell height according to view height.
You can have view height constraint property in your dynamic cell:
#IBOutlet weak var customViewHeightConstraint: NSLayoutConstraint!
Constraint constant value can be changed in cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellId", for: indexPath) as! Cell
switch indexPath.row {
case 0:
cell.customViewHeightConstraint.constant = 100
case 1:
cell.customViewHeightConstraint.constant = 200
case 2:
cell.customViewHeightConstraint.constant = 300
case 3:
cell.customViewHeightConstraint.constant = 400
default:
cell.customViewHeightConstraint.constant = 100
}
return cell
}

Adjust UITableViewCell separator line when in multiple edit mode

I'm looking to adjust the separator inset margin when in multiple edit mode in a standard UITableView in iOS 9/10.
My goal is to align the separator line with the left edge of the cell's text label.
In the past, I've removed the margins entirely by doing:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.separatorInset = .zero
cell.layoutMargins = .zero
}
That gives me a view such as:
If I try to increase the separator inset, the entire text label moves over, which I don't want. :
cell.separatorInset = UIEdgeInsetsMake(0, 40, 0, 0)
How can I just move the separator line, without affecting the text layout, and preferably without doing any overriding of layoutSubviews or drawing lines manually?
You can add separator manually, try to use below code
func viewDidLoad() {
self.tableview.separatorStyle = UITableViewCellSeparatorStyle.None
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let separator = CALayer()
separator.backgroundColor = UIColor.grayColor();
separator.frame = CGRectMake(0, 43, self.view.frame.size.width, 1);
cell.layer.insertSublayer(separator, atIndex:0)
return cell;
}
I'm on xcode 8, with ios 9
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
cell.layoutMargins = .zero
}
gives you the what you want as per your third picture.
I've tried
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
cell.layoutMargins = .zero
}
it works too, not sure why its not working on your side..

UITableView row separator cut off when updating cell

I have a grouped UITableView in which I display some car data in the second section. I load the image from a web server using SDWebImage. In its callback I resize the picture and update my image view.
However, as soon as I update my image view, the UITableView separator is cut off.
For illustration purposes I've given the respective elements background colors
When the image is not loaded yet, it looks like this:
When the image is updated, it looks like this
Notice that the row separator is somehow cut off between the UITableView cells even though no subview (the UIImageView) is hiding it.
Depending on the UITableView section the row height varies, so I've overwritten the heightForRowAtIndexPath UITableView delegate
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.section == 0 {
return GFFloat(44)
}
else {
return CGFloat(220)
}
}
Can someone tell me why the separators disappear and how I can fix this? I've read about reloading the next UITableViewCell when I update the image, but since I display a lot of cars, my app crashes when I try this.
Just add below method it will resolve separator issue.
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
cell.preservesSuperviewLayoutMargins = false
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
}
Solution for Swift 5
Add this to your controller:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = UIEdgeInsets.zero
}
if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
if cell.responds(to: #selector(setter: UIView.layoutMargins)) {
cell.layoutMargins = UIEdgeInsets.zero
}
}

Resources