For anyone still looking for a solution, I found this one on Medium: https://forzfilm.medium.com/how-to-set-image-and-label-in-trailing-swipe-action-with-custom-font-ios11-4a49d4794669.
It turns out that you can render a UIView as an Image.
Note: the answer below is with UICollectionLayoutListConfiguration
, but it you can also use it with tableView since they both use UIContextualAction
. And the cell height in the example is 80.
Tested in XCode 14 with UICollectionLayoutListConfiguration
:
SwipeLayout:
private func swipeLayout(icon: String, text: String, size: CGFloat) -> UIImage {
let config = UIImage.SymbolConfiguration(pointSize: size, weight: .regular, scale: .large)
let img = UIImage(systemName: icon, withConfiguration: config)?.withTintColor(.white, renderingMode: .alwaysOriginal)
let label = UILabel(frame: .zero)
label.font = .systemFont(ofSize: 13, weight: .medium)
label.textColor = .white
label.text = text
let tempView = UIStackView(frame: .init(x: 0, y: 0, width: 50, height: 50))
let imageView = UIImageView(frame: .init(x: 0, y: 0, width: img!.size.width, height: img!.size.height))
imageView.contentMode = .scaleAspectFit
tempView.axis = .vertical
tempView.alignment = .center
tempView.spacing = 2
imageView.image = img
tempView.addArrangedSubview(imageView)
tempView.addArrangedSubview(label)
let renderer = UIGraphicsImageRenderer(bounds: tempView.bounds)
let image = renderer.image { rendererContext in
tempView.layer.render(in: rendererContext.cgContext)
}
return image
}
in trailingSwipeActionsConfigurationProvider
:
// archive
let archiveHandler: UIContextualAction.Handler = { [weak self] action, view, completion in
completion(true)
// self?.updateSnapShot(animated: true)
}
let archiveAction = UIContextualAction(style: .normal, title: nil, handler: archiveHandler)
archiveAction.image = self.swipeLayout(icon: "archivebox.fill", text: "Archive", size: 16)
archiveAction.backgroundColor = .theme.arhiveRow
