直观地改进 iOS 11 个用于异步操作的 leadingSwipeActions

Visually improve iOS 11 leadingSwipeActions for async actions

我想在用户向右滑动单元格时显示加载指示器,这会触发异步操作。虽然此操作正在进行,但我想将标签隐藏在里面,保留单元格 "inlined",而不是 "re-swipeable" 并显示已经提到的指示器。

这是我到目前为止得到的,它已经部分工作了:

override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

let action = UIContextualAction(style: .normal, title: "My Action") { (action, view, handler: @escaping (Bool) -> Void) in

    // Getting UIButtonLabel, which is a subclass of UILabel
    guard let label = view as? UILabel else {
        return
    }

    // Not used right now
    guard let superView = label.superview else {
        return
    }


    // Try to hide the existing label
    label.text = "" // Doesn't work
    label.attributedText = nil // Doesn't work
    label.textColor = UIColor.clear // Doesn't work

    // Add a loading indicator at the position of the label, works!
    let loadingIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.white)
    loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
    loadingIndicator.startAnimating()
    label.addSubview(loadingIndicator)
    NSLayoutConstraint.activate([
        loadingIndicator.centerXAnchor.constraint(equalTo: label.centerXAnchor),
        loadingIndicator.centerYAnchor.constraint(equalTo: label.centerYAnchor),
        loadingIndicator.heightAnchor.constraint(equalTo: label.heightAnchor, multiplier: 0.8),
        loadingIndicator.widthAnchor.constraint(equalTo: loadingIndicator.heightAnchor)
    ])

    self.viewModel.doAsyncAction(completionHandler: { (success) in
        loadingIndicator.stopAnimating()
        loadingIndicator.removeFromSuperview()
        handler(true)
    })))
}

action.backgroundColor = .darkGray

return UISwipeActionsConfiguration(actions:[action])

}

我可以在正确的位置添加加载指示器。我仍然无法隐藏标签。删除它或将其设置为 alpha 或隐藏状态将不起作用,因为加载指示器必须是它​​的子视图(用于 UITableView 的内部定位)。

此外,我可以通过延迟调用回调处理程序来阻止用户再次拉动操作,但我无法使单元格保持在 "one-level inline" 滑动位置。当用户没有滑动单元格并单击按钮,而是决定滑动整个单元格以触发操作时,这尤其难看。在这种情况下,我希望单元格自动移动到 "one level inline" 位置。

有人知道这方面的窍门吗?我已经在一些应用程序中看到了这一点。这种东西有通用的 UIKit 添加吗?

我发现的一种方法是禁用超级视图,它是 UIButton 的子类。

您可以通过

获取
            guard let superView = label.superview as? UIButton else {
                return
            }

然后通过

禁用它
            superView.isEnabled = false
            label.isEnabled = false
            label.isUserInteractionEnabled = false // Probably not required

这样,按钮内的标签就显得有些褪色了。此外,它还可以防止用户多次单击按钮。

当用户"swipes to action"时看起来不太好,因为操作按钮将保持在滑动位置。但也许这也是可以轻松调整的东西?!