如何在swift 5中实现滑动中的两个垂直按钮以删除

Posted

技术标签:

【中文标题】如何在swift 5中实现滑动中的两个垂直按钮以删除【英文标题】:How can implement two vertical button in swipe to delete in swift 5 【发布时间】:2020-07-01 06:08:56 【问题描述】:

我正在尝试实现滑动删除功能,有两个选项,一个是删除,另一个是编辑。我想要的是这些选项应该是垂直的而不是水平的。 提前感谢您的支持。

【问题讨论】:

您能否添加一些您想要实现的视觉表示?回答您的问题会很有帮助。 我附上图片请检查。@JarvisTheAvenger 你用的是tableView、collectionView还是别的什么? 带表格视图 【参考方案1】:

您可以使用Custom TablViewCell轻松实现此滑动以显示选项功能

设计一个带有两个按钮的视图并向视图添加滑动手势以显示垂直对齐的按钮

【讨论】:

它的效果是否与 editActionsForRowAt 相同?你会提到任何与此相关的链接吗? @PuNeetPal 是的,它与editActionsForRowAt具有相同的效果 参考:***.com/questions/19164188/… 如果对答案感到满意,您可以将其标记为正确并点赞。 @JarvisTheAvenger 你的答案是什么?【参考方案2】:

无论如何,我认为您宁愿在类似情况下使用默认方法editActionsForRowAt。如果没有,我希望这段代码对您有所帮助。

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)
    ])


【讨论】:

以上是关于如何在swift 5中实现滑动中的两个垂直按钮以删除的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 3.0 中实现滑动以在没有导航栏的情况下向后导航

在android蜂窝webview/webkit中实现水平/垂直手指滑动滚动?

如何在 ViewPager 中实现 Swipe 事件以查看 Flipper?

如何在android中实现视图滑动

VoiceOver:如何在计算器中实现类似于键的按钮

如何在ios的页面控件中实现水平和垂直滚动