7

I have been looking everywhere and have not quite found my answer.

I populating a UITableView with dynamic cells from JSON and I am trying to hide any extra cells. I turned off the separators in IB, and of course all the cell separators disappear. How do I add a line to the bottom and top of each tableviewcell so that only the cells that have information show a border? I have imported Quartz and have been playing with CALayer but can't find a solution.

I found a similar question here, but the only answer was not very helpful.

What would be a better, different way of doing this?

Here are my cellForRowAtIndexPath and my numberOfRowsInSection:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    //set equal to the information in the array

    return [_jsonDataArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    //create Dictionary of data in row
    NSDictionary *jsoninfo = [_jsonDataArray objectAtIndex:indexPath.row];

    //get required keys from dictionary and assign to vairables
    NSString *title = [jsoninfo objectForKey:@"title"];
    NSString *subtitle = [jsoninfo objectForKey:@"subtitle"];
    NSURL *imageURL = [NSURL URLWithString:[jsoninfo objectForKey:@"series_image_URL"]];

    //download the images.
    NSData *imgData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *img = [[UIImage alloc] initWithData:imgData];


    //set boarder for custom cells... I need to have a border on the top and bottom of the cells I am creating so xcode does not autofill the empty space.



    //fill in text to cells
    cell.textLabel.text = title;
    cell.detailTextLabel.text = subtitle;
    cell.imageView.image = img;

    return cell;
}
Siriss
  • 3,737
  • 4
  • 32
  • 65

5 Answers5

26

I also think it's not the best idea, but if you really want to do this, here's code that will achieve what you want:

tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

// Draw top border only on first cell
if (indexPath.row == 0) {
    UIView *topLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)];
    topLineView.backgroundColor = [UIColor grayColor];
    [cell.contentView addSubview:topLineView];
}

UIView *bottomLineView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.bounds.size.height, self.view.bounds.size.width, 1)];
bottomLineView.backgroundColor = [UIColor grayColor];
[cell.contentView addSubview:bottomLineView];

Put this code in the tableView:cellForRowAtIndexPath: method. The final look of your UITableView will be like this:

Table view with selective borders

Take into account that this is not very good for performance, especially if you have a lot of cells. If you have a bigger amount of data, refer to this SO question for help on how to optimize the drawing.

Community
  • 1
  • 1
nikolovski
  • 4,049
  • 1
  • 31
  • 37
  • Thank you for the help. What would be the best way to do it? I want to make it is fast as possible. – Siriss Dec 20 '12 at 22:17
  • The better way would be subclassing `UITableViewCell` and overriding the `drawRect:` method with the code in my linked question. EDIT: The code as you can see in the answer with more upvotes. – nikolovski Dec 20 '12 at 22:20
  • I think that you should at least try the "easier" method before you go on optimizing the solution — you might find it is fast enough. – nikolovski Dec 20 '12 at 22:22
  • Ok thanks, I was just looking at that linked question. This worked quite well, although I need to add padding to my tableviewcells to fit my thumbnails... but that is a different issue. I will give both a whirl and see which is better. Thank you very much!! – Siriss Dec 20 '12 at 22:25
  • What is one would enable cell reordering? How to fix the problem if the user drags the first row lower and another one takes its place? – Majster Aug 20 '13 at 09:09
  • Good answer from a long time ago... I don't know if this is new behavior since 2012, but the beginning `y` coordinate for the bottom frame needs to be `cell.bounds.size.height -1` Otherwise, it's 1 "pixel" under the next cell, and thus not visible if the cell below is opaque. – Chris Ostmo Apr 03 '16 at 22:05
1

Only try this at tableView:cellForRowAtIndexPath: method

[cell.contentView.layer setBorderColor:[UIColor grayColor].CGColor];
[cell.contentView.layer setBorderWidth:1.0f];
User2103
  • 7
  • 2
seufagner
  • 1,290
  • 2
  • 18
  • 25
0

It sounds like a sub-optimal solution to try to "distinguish" your valid cells from empty ones with lines. A superior approach would be to clean up the data source before populating the table with it.

HackyStack
  • 4,887
  • 3
  • 22
  • 28
  • I don't create them, but xcode fills in the empty tableview space with empty cells. I only create the number of cells in numberOfRowsInSection equal to the number of objects in my data array. Currently there are two objects and cells created, but xcode fills in the rest. – Siriss Dec 20 '12 at 21:48
  • I edited my answer. I could probably help you create lines, but it just sounds like SUCH a bad idea... – HackyStack Dec 20 '12 at 21:52
  • I still don't get what you mean by "clean up the data source". How does the data source have anything to do with the boarders on a UITableViewCell? I am only creating 2 cells, xcode is doing the rest automatically, I imagine because it is prototype cells. I am open to any way of doing this – Siriss Dec 20 '12 at 22:03
0

This is not the answer to the question, but the clean solution for the original problem.

Add an empty UIView as the footer of the UITableView. Then the empty cells will be hidden. See this answer.

Community
  • 1
  • 1
wrtsprt
  • 5,319
  • 4
  • 21
  • 30
-1

Use Custom Cells. Your Datasoure (Models) should drive the information into the Custom Cells. Create a setter within the Custom Cell class that can be set at each row. as in....


  1. Allocation your Custom Cell with reuse Id,

  2. Pass the property that is determing if the line should show:
    [cell setCustomLines:Model.property];

  3. return the cell;


You will have far more flexibility to design the CustomCell any way you want, Images, Lines, Colors, or other ways of letting your user's see a difference among your cells.

Technically, Marco's Answer will work, and good job on a simple solution. But you will not be able to expand this very much farther this this.

Newbyman
  • 1,144
  • 10
  • 14