-5

In my UITableView, I am setting my separators like this:

    self.tableView.clipsToBounds = true
    self.tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
    self.tableView.separatorColor = UIColor(hex: 0xededed)
    self.tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    self.tableView.layoutMargins = UIEdgeInsetsZero

And my cells are like this:

override func awakeFromNib() {
    super.awakeFromNib()
    self.layoutMargins = UIEdgeInsetsZero
    self.contentView.layer.borderWidth = 0.0
    self.layer.borderWidth = 0.0
}

This allows me to have edge-to-edge separators:

original

I'm trying to create a "down caret" for some of my cells (some cells will have it, some won't). If a cell has it, it will cover the top left portion of the separator, like this:

caret

Notice the caret at the top left of each cell.

What's the best way to achieve this? Maybe use an image and cover the separator? Or should the caret be drawn by code?

jtbandes
  • 115,675
  • 35
  • 233
  • 266
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

6 Answers6

2

The best solution from a design perspective would be to subclass UITableViewCell (see this question).

As for displaying the down arrow you have a lot of options to get some UIView subclas to display an arrow. I used the unicode character for a down arrow with a UILabel and it works well. You could also use custom drawing code with CoreGraphics, an UIImageView or possibly a some polygonal drawing framework.

let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

let downArrowView = UILabel()
downArrowView.text = "\u{25BC}"
downArrowView.sizeToFit()
cell.addSubview(downArrowView)

// Offset to compensate for whitespace around the arrow; adjust to your preference
var frame = downArrowView.frame
frame.origin.y -= 5
frame.origin.x -= 2
downArrowView.frame = frame

Down arrow screenshot

Community
  • 1
  • 1
Kevin
  • 16,696
  • 7
  • 51
  • 68
1

Can probably just use an image of the caret, then use resizeableImageWithCapInsets to make the line stretch to the right of the caret so it wont matter what the width of the cell is, the caret will always be on the left. Also include the separator line as part of the image, otherwise it wont work properly. then maybe have an image that doesnt have the caret and one that does, for when the caret isnt meant to be there.

ive made a demo of what i mean:

class TableViewCell: UITableViewCell {

    @IBOutlet weak var carret: UIImageView!

    override func awakeFromNib() {

        carret.image = carret.image!.resizableImageWithCapInsets(UIEdgeInsetsMake(34,34,0,0))
    }
}

the image i used (in the @3x category in the assets file):

carret with lines

how it looks in the storyboard with some autolayouts:

storyboard

result:

result

this is literally all i needed to do to get it to work, you will have to play around with the resizableImageWithCapInsets a bit to get it to work because your image will be different to mine

Community
  • 1
  • 1
Fonix
  • 11,447
  • 3
  • 45
  • 74
0

It would be better to create your 'down caret' from UIImageView instance.
Drawing it from code with the help of QuartzCore, can decrease UITableView scrolling perfomance.

Evgeny Karkan
  • 8,782
  • 2
  • 32
  • 38
0

As you have displayed some options to draw the down caret I suggest you go for the UILabel or UIImageView.

You can create custom tableview cell by creating subclass of UITableViewCell where you create a label or imageview based on your choice and display in the cell.
more information about creates custom tableview cell:https://stackoverflow.com/a/25545185/4557505

Or if you have created the UITableview in the storyboard you can design the custom cell in the UITableview prototype custom cell itself

By anyway, you create the custom cell, for the displaying the caret in the image view you can give it a static image from the XIB/Storyboard. For the UILabel, you can provide Unicode or you can put emoji's to display the down caret

You can put the below code in the cellForRowAtIndexPath of tableview delegate Ex like this:
lblDownCaret.text = "▼"// or with unicode \u{25BC} lblDownCaret.sizeToFit()

Which will look like this

Down caret tableview
First, two are from the UILabel, the third one is from the UIImageView

Why drawn by code should not be preferred till required:
You can draw this but there can be some drawbacks

  • When you draw any component in using any system or third party component it takes much more processing time. also in the case of UITableView, it will be displayed for the multiple times.
  • While drawing the custom component you have to be very careful with the memory management of the drawing object, as they can be one of the major issues of memory leak or memory warning if they are not carefully handled and code in the best possible way

So if there is option to display the component by UILabel or UIImageView you should go for them first instead of drawing the custom

Community
  • 1
  • 1
HardikDG
  • 5,892
  • 2
  • 26
  • 55
0

I'd create two different views, one for the right line and another for the left one.

mcatach
  • 1,227
  • 13
  • 23
0

It can be possibile with :

  1. UITableViewController (or UIViewController+UITableView)
  2. a UITableViewCell + xib
  3. a down caret image

How to do it

First of all make a custom UITableViewCell called for example SeparatorCell

The UITableViewCell code:

import UIKit

class SeparatorCell: UITableViewCell {
    @IBOutlet weak var downCaretImage: UIImageView!
}

A down caret image:

downCaretImage

The XIB: cell XIB

About cell constraints: all autolayout with auto suggestions + set height constraint for separatorLineView (bgcolor: a very light gray, height size: 1)

P.S. Dont forget to insert identifier :

enter image description here

Now make for example inside the storyboard a default UITableViewController with this code:

import UIKit

class SeparatorTableViewController: UITableViewController {
    var myData : [Bool]! = [true,false,true,false,false,true,true,false,false,true]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 100.0
        tableView.registerNib(UINib(nibName: "SeparatorCell", bundle:nil), forCellReuseIdentifier: "SeparatorCell")
        tableView.separatorStyle = .None
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.myData.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier : String! = "SeparatorCell"
        var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? SeparatorCell!
        if cell == nil {
            cell = SeparatorCell(style: UITableViewCellStyle.Default, reuseIdentifier: (cellIdentifier))
        }
        let isDownCaret : Bool = myData[indexPath.row]
        cell!.downCaretImage.hidden = !isDownCaret
        return cell!
    }
}

Finally the result:

finalStaticImage

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133