I am trying to implement swipe to delete feature with two options, one is to delete and another one is to edit. The things I want is these options should be vertical rather than horizontal.
Thanks in advance for support.
Asked
Active
Viewed 425 times
0

PuNeet Pal
- 59
- 7
-
Can you please add some visual representation of what you want to achieve? it will be helpful to answer your question. – Jarvis The Avenger Jul 01 '20 at 06:11
-
I attached image please check.@JarvisTheAvenger – PuNeet Pal Jul 01 '20 at 06:17
-
Do you use tableView, collectionView, or something else? – Andrey Maksimkin Jul 01 '20 at 06:43
-
with table View – PuNeet Pal Jul 01 '20 at 07:15
2 Answers
0
You can easily achieve this swipe to reveal option feature using Custom TablViewCell
Design a view with two buttons and add a swipe gesture to the view to reveal the vertically aligned buttons

Jarvis The Avenger
- 2,750
- 1
- 19
- 37
-
Does it give same effect as editActionsForRowAt gives? and will you mention any link related this? – PuNeet Pal Jul 01 '20 at 07:51
-
@PuNeetPal yeah it will have same effect as a `editActionsForRowAt` – Jarvis The Avenger Jul 01 '20 at 09:03
-
Reference : https://stackoverflow.com/questions/19164188/custom-edit-view-in-uitableviewcell-while-swipe-left-objective-c-or-swift – Jarvis The Avenger Jul 01 '20 at 09:03
-
If satisfied with answer you can mark it correct and upvote it. – Jarvis The Avenger Jul 01 '20 at 09:04
-
0
Anyway, I think you would rather use default method editActionsForRowAt
for similar cases. If not I hope this code will help you.
class TableViewController: UIViewController {
let tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.register(CustomCell.self,
forCellReuseIdentifier: CustomCell.identifier)
return tableView
}()
var selectedCell: CustomCell?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(tableView)
setupConstraints()
tableView.dataSource = self
tableView.delegate = self
tableView.reloadData()
}
func setupConstraints() {
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
}
extension TableViewController: UITableViewDelegate & UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath) as? CustomCell else {
return UITableViewCell()
}
cell.delegate = self
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
44
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
selectedCell?.setInitialState()
}
}
extension TableViewController: CustomCellDelegate {
func didUpdateState(customCell: CustomCell?) {
if customCell != selectedCell {
selectedCell?.setInitialState()
}
selectedCell = customCell
}
}
protocol CustomCellDelegate: class {
func didUpdateState(customCell: CustomCell?)
}
class CustomCell: UITableViewCell {
weak var delegate: CustomCellDelegate?
static let identifier = "Cell"
private let customViewWidth: CGFloat = 100
private let customView: CustomView = {
let view = CustomView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .yellow
return view
}()
private let fakeContentView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
enum CustomCellState {
case hiddenCustomView
case showedCustomView
}
private var trailingConstraint = NSLayoutConstraint()
private var cellState: CustomCellState = .hiddenCustomView
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = .yellow
let panGesture = UIPanGestureRecognizer(target: self, action:(#selector(handleGesture(_:))))
fakeContentView.addGestureRecognizer(panGesture)
contentView.addSubview(fakeContentView)
fakeContentView.addSubview(customView)
setConstraints()
updateCellState()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setInitialState() {
self.trailingConstraint.constant = 0
UIView.animate(withDuration: 0.5, animations: {
self.contentView.layoutIfNeeded()
})
}
@objc private func handleGesture(_ recognizer: UIPanGestureRecognizer) {
let location = recognizer.location(in: fakeContentView)
let dx = frame.width - location.x
updateFrame(deltaX: dx)
if recognizer.state == .ended {
cellState = dx > customViewWidth / 2 ? .showedCustomView : .hiddenCustomView
updateCellState()
delegate?.didUpdateState(customCell: self)
}
}
private func updateFrame(deltaX: CGFloat) {
guard abs(deltaX) <= customViewWidth else {
return
}
trailingConstraint.constant = -deltaX
contentView.layoutIfNeeded()
}
private func updateCellState() {
let dx: CGFloat = cellState == .hiddenCustomView ? 0 : customViewWidth
self.trailingConstraint.constant = -dx
UIView.animate(withDuration: 0.5, animations: {
self.contentView.layoutIfNeeded()
}, completion: nil)
}
private func setConstraints() {
trailingConstraint = fakeContentView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
trailingConstraint.isActive = true
NSLayoutConstraint.activate([
fakeContentView.topAnchor.constraint(equalTo: contentView.topAnchor),
fakeContentView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
fakeContentView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
customView.topAnchor.constraint(equalTo: fakeContentView.topAnchor),
customView.bottomAnchor.constraint(equalTo: fakeContentView.bottomAnchor),
customView.leadingAnchor.constraint(equalTo: fakeContentView.trailingAnchor),
customView.widthAnchor.constraint(equalToConstant: customViewWidth)
])
}
}
class CustomView: UIView {
private let button1: UIButton = {
let button = UIButton(type: .custom)
button.backgroundColor = .blue
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
private let button2: UIButton = {
let button = UIButton(type: .custom)
button.backgroundColor = .black
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .gray
addSubview(button1)
addSubview(button2)
setConstraints()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setConstraints() {
NSLayoutConstraint.activate([
button1.topAnchor.constraint(equalTo: topAnchor),
button1.leadingAnchor.constraint(equalTo: leadingAnchor),
button1.trailingAnchor.constraint(equalTo: trailingAnchor),
button1.bottomAnchor.constraint(equalTo: centerYAnchor),
button2.bottomAnchor.constraint(equalTo: bottomAnchor),
button2.leadingAnchor.constraint(equalTo: leadingAnchor),
button2.trailingAnchor.constraint(equalTo: trailingAnchor),
button2.topAnchor.constraint(equalTo: button1.bottomAnchor)
])
}
}

Andrey Maksimkin
- 183
- 8