UITableViewCell custom reorder control

Viewed 17542

Is there any way to change the image of the reorder control that is displayed when the UITableView is in edit mode? I have a UIImage that I’d like to display instead of the usual grey bars.

Do I have to subclass UITableViewCell to accomplish this?

6 Answers

Here is my Swift solution based on Rick Morgan's answer:

func adjustSize() {
    // we're trying to leverage the existing reordering controls, however that means the table must be kept in editing mode,
    // which shrinks the content area to less than full width to make room for editing controls
    let cellBounds = bounds
    let contentFrame = contentView.convert(contentView.bounds, to: self)

    let leftPadding = contentFrame.minX - cellBounds.minX
    let rightPadding = cellBounds.maxX - contentFrame.maxX

    // adjust actual content so that it still covers the full length of the cell
    contentLeadingEdge.constant = -leftPadding
    // this should pull our custom reorder button in line with the system button
    contentTrailingEdge.constant = -rightPadding

    // make sure we can still see and interact with the content that overhangs
    contentView.clipsToBounds = false

    // recursive search of the view tree for a reorder control
    func findReorderControl(_ view: UIView) -> UIView? {
        // this is depending on a private API, retest on every new iPad OS version
        if String(describing: type(of: view)).contains("Reorder") {
            return view
        }
        for subview in view.subviews {
            if let v = findReorderControl(subview) {
                return v
            }
        }
        return nil
    }

    // hunt down the system reorder button and make it invisible but still operable
    findReorderControl(self)?.alpha = 0.05   // don't go too close to alpha 0, or it will be considered hidden
}

This worked pretty well. contentLeadingEdge and contentTrailingEdge are layout constraints I set up in Interface Builder between the contentView and the actual content. My code calls this adjustSize method from the tableView(_:, willDisplay:, forRowAt:) delegate method.

Ultimately, however, I went with Clifton's suggestion of just covering the reorder control. I added a UIImageView directly to the cell (not contentView) in awakeFromNib, positioned it, and when adjustSize is called I simply bring the image view to the front, and it covers the reorder control without having to depend on any private APIs.

Related