我在UITableViewCell中有一个TrailingSwipeAction,其背景颜色必须清晰。
这是我设置操作的代码:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let myAction = UIContextualAction.init(style: .normal, title: nil) {
// My action code
}
myAction.backgroundColor = .clear
myAction.image = UIImage.init(named: "my-icon")
return UISwipeActionsConfiguration.init(actions: [myAction])
}
但是当我期望没有颜色时,我将获得灰色背景的动作:
答案 0 :(得分:3)
您必须访问UIActionStandardButton
内UISwipeActionPullView
内的UIView。然后更改其背景颜色。
您可以看到应用程序的视图层次结构在某个单元格上滑动,然后进入Xcode中的Debug
菜单,然后进入View Debugging
,然后选择Capture View Hierarchy
。
首先,让我们添加一个有用的extension,它将所有子视图及其子视图放入一个数组中:
extension UIView {
var allSubViews : [UIView] {
var array = [self.subviews].flatMap {$0}
array.forEach { array.append(contentsOf: $0.allSubViews) }
return array
}
}
然后在viewWillLayoutSubviews()
中输入:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let btn = tableView
.allSubViews //get all the subviews
.first(where: {String(describing:type(of: $0)) == "UISwipeActionStandardButton"}) // get the first one that is a UISwipeActionStandardButton
//This UISwipeActionStandardButton has two subviews, I'm getting the one that is not a UILabel, in your case, since you've set the image, you should get the one that is not an imageView
if let view = btn?.subviews.first(where: { !($0 is UILabel)})
{
view.backgroundColor = .clear //Change the background color of the gray uiview
}
}
我正在使用viewWillLayoutSubviews()
,因为它被调用来通知视图控制器其视图即将布局其子视图。请查看here了解更多详细信息。
此解决方案针对一个轻扫操作按钮进行了优化。如果您有多个按钮,代码将如下所示:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let buttons = tableView
.allSubViews //get all the subviews
.filter {String(describing:type(of: $0)) == "UISwipeActionStandardButton"}
buttons.forEach { btn in
if let view = btn.subviews.first(where: { !($0 is UIImageView)}) //If you're sure that other than the uiview there is a UIImageView in the subviews of the UISwipeActionStandardButton
{
view.backgroundColor = .clear //Change the background color of the gray uiview
}
}
}
答案 1 :(得分:3)
显然,如果您将背景颜色设置为白色且 alpha 为零,它将保持清晰但没有灰色默认颜色。
试试这个:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let deleteAction = UIContextualAction(style: .destructive, title: nil) { [weak self] (action, view, completion) in
// weak self to prevent memory leak if needed
guard let self = self else { return }
// do your nasty stuff here
completion(true)
}
deleteAction.backgroundColor = UIColor(white: 1, alpha: 0)
deleteAction.image = UIImage(systemName: "trash")
return UISwipeActionsConfiguration(actions: [deleteAction])
}
答案 2 :(得分:1)
感谢 Carpsen90
您必须将该UIImageView的backgroundColor设置为.clear,但在viewWillLayoutSubviews时不存在。滑动后即可创建。
可能的解决方案是使用计时器:
var timerCellSwipeButtons: Timer?
滑动完成后启动:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let editAction = UIContextualAction.init(style: .normal, title: nil) { [weak self] (action, view, completion) in
// editAction code
}
let deleteAction = UIContextualAction.init(style: .normal, title: nil) { [weak self] (action, view, completion) in
// deleteAction code
}
// Set the button's images
editAction.image = UIImage.init(named: "editIcon")
deleteAction.image = UIImage.init(named: "deleteIcon")
// You also must set the background color of the actions to .clear
editAction.backgroundColor = .clear
deleteAction.backgroundColor = .clear
// Launch the timer, that will run a function every 10 milliseconds
self.timerCellSwipeButtons = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(timerCellSwipeButtonsFunction), userInfo: nil, repeats: true)
// Return the actions
return UISwipeActionsConfiguration.init(actions: [deleteAction, editAction])
}
现在每10毫秒一次(您可以根据需要增加频率),此函数检查tableView子视图以查找所有UISwipeActionStandardButton并将其设置为.UI的backgroundColor清除。
@objc func timerCellSwipeButtonsFunction() {
// Gets all the buttons, maybe we have more than one in a row
let buttons = tableView.allSubViews.filter { (view) -> Bool in
String(describing: type(of: view)) == "UISwipeActionStandardButton"
}
// Loops through all the buttons
for button in buttons {
if let view = button.subviews.first(where: { !($0 is UIImageView)})
{
// We are interested in the UIView that isn't a UIImageView
view.backgroundColor = .clear
}
}
// When finish, timer is invalidated because we don't need it anymore.
// A new one will be launched with every swipe
self.timerCellSwipeButtons?.invalidate()
}
要获取UIView的所有子视图,我使用了 Carpsen90 给出的功能:
extension UIView {
var allSubViews : [UIView] {
var array = [self.subviews].flatMap {$0}
array.forEach { array.append(contentsOf: $0.allSubViews) }
return array
}
}
出于安全原因,您还应该在viewWillDisappear方法中使计时器无效:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.timerCellSwipeButtons?.invalidate()
}
这是结果:
但是正如您所看到的,当您在单元格的同一侧进行多个动作并且完全滑动时,效果会不太好:
为避免图标重叠,我在每一侧只做一个动作:
// Remember to launch the timer in both swipe functions, like in the example above
// Function to add actions to the leading side of the cell
tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
// Function to add actions to the trailing side of the cell
tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
答案 3 :(得分:1)
您可以将操作的背景色的Alpha值设置为0 这是示例
let modifyAction = UIContextualAction(style: .normal, title: "", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
print("Update action ...")
success(true)
})
modifyAction.backgroundColor = UIColor.init(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 0.0)
答案 4 :(得分:1)
100%在IOS swift中进行更改以滑动按钮图像颜色和背景颜色。
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
if isInbox
{
let action = UIContextualAction(style: .normal, title: "", handler: { (action,view,completionHandler ) in
self.selectedIndex = indexPath.row
self.deleteNotification()
completionHandler(true)
})
let cgImageX = UIImage(named: "delete-1")?.cgImage
action.image = OriginalImageRender(cgImage: cgImageX!)
action.backgroundColor = UIColor.init(hex: "F7F7F7")
let confrigation = UISwipeActionsConfiguration(actions: [action])
return confrigation
}
return nil
}
还为原始图像彩色显示添加该类,否则仅显示白色图像
class OriginalImageRender: UIImage {
override func withRenderingMode(_ renderingMode: UIImage.RenderingMode) -> UIImage {
return self
} }
答案 5 :(得分:0)
我在项目中所做的是
func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) {
let subViews = tableView.subviews.filter { (view) -> Bool in
if NSStringFromClass(view.classForCoder) == "UISwipeActionPullView" {
return true
}
return false
}
if subViews.count > 0 {
let bgView = subViews[0]
bgView.backgroundColor = bgColor
}
}
我的项目目标是iOS 9.0及更高版本
答案 6 :(得分:0)
按照@Maulik Patel 的解决方案,我刚刚在 action.image 中添加了一个色调选项:
let imageDelete = UIImage(systemName: "trash")?.cgImage
deleteAction.image = OriginalImageRender(cgImage: imageDelete!).withTintColor(UIColor(named: ("colorButton"))!)
deleteAction.backgroundColor = UIColor.init(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 0.0)
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
return configuration