Grouped UITableview remove outer separator line

前端 未结 19 2130
遇见更好的自我
遇见更好的自我 2020-12-02 10:58

I have a grouped UITableview which is created programatically. Also I have a cell with xib file populated in tableview programmatically as well. So far so good. But I want t

相关标签:
19条回答
  • 2020-12-02 11:45

    I had a similar issue, where I had a Grouped UITableView with custom cells, all designed with Interface Build as .xib files. The cells had white backgrounds, removed the default separators, and added my own ones. I also had custom Header Views for each section. I set the height of those Header Views to be 44 (could be anything...). There was a 1 point height view between my sections, which seemed weird. Apparently, the system adds some clear background view between the sections, even if we specify the custom height to be, say 44, and the custom Header View we return has a white (or some concrete background color). The color we see behind that clear view is the color of of the Table View's background actually. In my case, both the table views and the cells had to be of white color, and setting the background of table view to be white solved the problem (at least visually, but that's what I wanted anyway). Second solution would be to keep the Table View's style as plain, but implement the UITableView delegate method to return 2 or more sections, and also create custom headers if you need to. But that will make header views to stick to the top for a while (while scrolling), until the next section's header view gets closer to it, and then it starts going up too (and that may not be what you really want, but there may be an easy way to fix that, not sure though).

    0 讨论(0)
  • 2020-12-02 11:46

    You can remove separators even in grouped UITableView with Static Cell:

    class CustomCell: UITableViewCell {
    
    override func layoutSubviews() {
        super.layoutSubviews()
        for view in subviews where view != contentView {
            view.removeFromSuperview()
        }
    }
    
    0 讨论(0)
  • 2020-12-02 11:46

    Here the solution. This is for static cells. If you want dynamic then just rewrite "count". Hope it helps.

    extension NSObject {
       var theClassName: String {
           return    NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
       }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.separatorStyle = .None
    }
    override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        let count = tableView.numberOfRowsInSection(indexPath.section)
        if ( indexPath.row != count - 1 ) {
            for view in cell.subviews {
                if view.theClassName == "_UITableViewCellSeparatorView" {
                    view.backgroundColor = UIColors.redColor()
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 11:48

    For removing the top and bottom part of separator line for each section. Add this to your static cell.

    override func layoutSubviews() {
        super.layoutSubviews()
    
        //Get the width of tableview
        let width = subviews[0].frame.width
    
        for view in subviews where view != contentView {
            //for top and bottom separator will be same width with the tableview width
            //so we check at here and remove accordingly
            if view.frame.width == width {
                view.removeFromSuperview()
            }
        }
    }
    

    Result as below image

    0 讨论(0)
  • 2020-12-02 11:48

    Here's a Swift solution that works on iOS 8 and 9.

    Define a protocol with a default implementation:

    protocol CellSeparatorRemovable { }
    
    extension CellSeparatorRemovable {
        func removeSeparatorLinesFromCell(cell: UITableViewCell, section: Int, row: Int, indexPath: NSIndexPath) {
            guard (section, row) == (indexPath.section, indexPath.row) else { return }
    
            for view in cell.subviews where view != cell.contentView {
                view.removeFromSuperview()
            }
        }
    }
    

    Then, wherever you want to use it, conform to the CellSeparatorRemovable protocol and call its method from …willDisplayCell…:

    class SomeVC: UITableViewController, CellSeparatorRemovable {
        override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
            removeSeparatorLinesFromCell(cell, section: 1, row: 1, indexPath: indexPath)
        }
    }
    

    This is a minimal solution; you may need to refactor it if you're dealing with many cells to avoid excessive recursion and/or cell reuse issues.

    0 讨论(0)
  • 2020-12-02 11:49

    That is a really old question, still it's one of the first entries on google when searching for how to remove the top and bottom separators for each section.

    After some investigation, I found out that there is no way and just no intention from Apple to make this somehow happen without stupidly complicated hacks of the view hierarchy.

    Fortunately there is a absolutely simple and easy way of achieving such a look:

    I say simple but for a beginner, this might be difficult because of a lack of understanding how UITableView works and how to implement your own cells. Let me try to explain it:

    1. Create a UITableViewCell subclass
    2. In your cell, create a @IBOutlet weak var separatorView: UIView! property
    3. In your Storyboard, select the tableview cell and select your own cell as the class which backs up the cell. Note: You do not have to use custom style. You still can use Basic, Subtitle, etc.
    4. Set your UITableViews Separator Style to None to hide the default separator
    5. Drag a UIView onto your cell and resize it so it is on the bottom (or the top) of the cell. Use the Size Inspectors Autoresizing to pin it to start/end/bottom and give it a flex width (or Autolayout but thats just over the top in this case)
    6. Connect the view to the outlet of your cell class
    7. In your UITableViewDataSources cellForRowAtIndexPath: set the isHidden property of your custom separator based on if the indexPath.row is the last row (or the first, if your view is at the top) in the section

    Heres some example code:

    class MyCell: UITableViewCell {
        @IBOutlet weak var separatorView: UIView!
    }
    
    class ViewController: UITableViewController {
    
    
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 3
        }
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 3
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MyCell
            cell.separatorView.isHidden = indexPath.row == 2
            return cell
        }
    
    }
    

    And here some screenshots:

    Yes, it is some work but there is just no way to something for free when coding. In the end, we are programmers and it is up to us to do the coding. It's always better to spend the 5-10 minutes setting this up than just copy pasting some hacky code which might not continue to work in the future when Apple decides to change the view hierarchy.

    It was actually more work to write this answer than implementing the separator. I as well was searching for a easy and quick solution but in the end there just wasn't a good enough one which I felt was worth using.

    I hope you also feel skeptical when you see for-loops iterating over subviews of cells to hide or even remove views at runtime from the view hierarchy Apple provides you, when there is an easy, versatile, stable and future proof solution right around the corner. 7 little steps is really all you need and they are easy to understand.

    0 讨论(0)
提交回复
热议问题