0

Im trying to implement a tableview that has cells with a product image on the left side and a listing of various product details such as price, title, etc. to the right of the image, however, I have been having trouble with setting up the appropriate spacing/padding between the cells. I want each cell to have some white space between them. Here is an image showing what i have so far, and what the issue is.

TableView

I am using a stackview as a container for the labels with the product details, and am implementing the dynamic row height feature: self.tableView.rowHeight = UITableViewAutomaticDimension

Everything seems to work great except wajjhen the stackview height is smaller than the imageview height. I can't get the spacing to show in that scenario. I have tried everything for the past 2 days, and it is driving me crazy. Take it easy on me guys as I am an Android guy :)

All I want is for the I want the separators of tableview cells to have a bit of space between either the top and bottom of the imageview or the stackview(whichever is taller/higher).

I have attached a SS of the storyboard to show the layouts and constraints. Please let me know if any more information is need.

Storyboard

Jacman4146
  • 41
  • 3
  • Why not get rid of the UITableControl? Use nested UIStackViews? The "substack" is horizontal, containing your single product views (image and details), with the "main stack" being vertical, containing a list of products? –  Mar 18 '17 at 19:17

4 Answers4

0

for adding consitent spacing to your cell better way is to treat your each item as a section because you can set spacing easily between sections by creating a header view between section. So logically if you have 10 objects than you will be having 10 section with each section have only one row.

1.Each section with only one row

 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

2.Number of section is equal to count array of items

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return array.count 
    }

3.Set Hieght for spacing/header view

 func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 10 
    }

4.create your header view and customise it

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {      
       if let view = view as? UITableViewHeaderFooterView{
      view.backgroundView?.backgroundColor = UIColor.clearColor()
       }
}
Jagdeep
  • 1,158
  • 11
  • 16
0

Assuming that you have no problem with setting the appropriate height for each cell (if you have, you might want to check this Q&A), I suggest to let each cell on a section instead adding them in the same one.

Technique:

By default, if you are not implementing number​Of​Sections(in:​), it returns 1. You should:

  • implement it and let it returns the number of array data source -for example- (instead of doing it in table​View(_:​number​Of​Rows​In​Section:​)).

  • Let table​View(_:​number​Of​Rows​In​Section:​) returns 1. Each section will has only one cell.

  • After that, the trick is to add a header view for the sections (with a clear background color) with desired height, the height will be the margin between the section (cells in your case). You should achieve this by implementing:

table​View(:​view​For​Header​In​Section:​) and table​View(:​height​For​Header​In​Section:​).

The code will be similar to:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    // ...

    // MARK:- UITableViewDataSource
    func numberOfSections(in tableView: UITableView) -> Int {
        return dataSource.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell-ID")

        // note that you should read from 'indexPath.section' instead of 'indexPath.row'
        let currentObejct = dataSource[indexPath.section]
    }

    // MARK:- UITableViewDelegate
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        // here, you can customize the header
        // or your case want to let it clear...
        let margin = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 20.0))
        margin.backgroundColor = UIColor.clear

        return margin
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 20.0
    }

    // ...
}

Hope this helped.

Community
  • 1
  • 1
Ahmad F
  • 30,560
  • 17
  • 97
  • 143
0

You can try giving the Fruit Image a top and a bottom constraint but they must be >= so it doesn't mess your auto layout

what it looks like in size inspector

And your constraints will probably look like this

constraints

hermannb
  • 58
  • 2
  • 6
  • Thank you all for your answers and responses, but I decided to go with this one as it was the easiest to implement, and works perfectly. Thanks again everyone. – Jacman4146 Mar 19 '17 at 10:39
  • Almost. But this causes the stackview to become stretched out when it is shorter than the image. – Jacman4146 Mar 19 '17 at 10:44
0

3 days later, I finally found a solution I am content with, albeit it is quite janky, but at this point(3 days of dealing with this issue), I don;t really care. I am posting my solutuion in case it helps anyone in the future.

I ended up pinning a view to the tableviewcell with a minimum height of 130 to contain the imageview and stackview. Since I know the minimum height of the tableviewcells is 120, 130 gave a padding of 5 on the top and bottom. I attached the screenshot of my storyboard:

Storyboard TableView

Jacman4146
  • 41
  • 3