테이블 뷰의 reorder 버튼을 변경해야 하는데, API가 없어 고생했던 경험을 공유한다.

해결 방법

UITableViewtableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)에서 cell 내부에 있는 UITableViewCellReorderControl를 변경하면 된다.

TableView

extension SomeViewController: UITableViewDelegate {
 
    public func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        self.moveRow(at: sourceIndexPath.row, to: destinationIndexPath.row) // dataSource 변경
    }
 
    public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        guard let selectedCell = cell as? ReorderControlAppearanceReplaceable else {
            return
        }
        selectedCell.replaceReorderImage()
    }
 
}

Cell

internal protocol ReorderControlAppearanceReplaceable {
 
    func replaceReorderImage()
 
}
 
internal class SomeCell: UITableViewCell, ReorderControlAppearanceReplaceable {
 
    private let reorderControlView = UIImageView(image: UIImage(image: "이미지 이름"))
 
    internal func replaceReorderImage() {
        guard let reorderControlView = self.subviews.filter({ String(describing: type(of: $0)) == "UITableViewCellReorderControl" }).first else {
            return
        }
 
        _ = reorderControlView.subviews
            .first(where: { $0 is UIImageView })
            .map {
                $0.removeFromSuperview()
            }
 
        self.reorderControlView.frame.size = CGSize(width: Constants.reorderViewWidth, height: Constants.reorderViewWidth)
 
        reorderControlView.addSubview(self.reorderControlView)
 
        self.reorderControlView <- Layouts()
            .move(to: .right, margin: .zero, alignment: nil)
            .move(toCenter: .vertical)
    }
 
}

정리

  • 약간 hack 같은 느낌이 있지만, 현재로서는 이 방법밖에 없다고 한다.

Reference