Я сделал пользовательский UITableViewRowAction. Теперь я хотел бы добавить изображение вместо текста. Я знаю, что это возможно, но не знаю, как это сделать. Кто-то из вас знает, как это сделать в Свифт и хотел бы мне помочь? Спасибо за ваши ответы!
Изображение UITableViewRowAction для заголовка
Ответ 1
iOS 11.0
Apple представила гибкий способ объявить ряд действий с большими преимуществами.
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let askAction = UIContextualAction(style: .normal, title: nil) { action, view, complete in
print("Ask!")
complete(true)
}
// here set your image and background color
askAction.image = IMAGE
askAction.backgroundColor = .darkGray
let blockAction = UIContextualAction(style: .destructive, title: "Block") { action, view, complete in
print("Block")
complete(true)
}
return UISwipeActionsConfiguration(actions: [blockAction, askAction])
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.textLabel?.text = "row: \(indexPath.row)"
}
}
Пример:
iOS 8.0
Вам нужно установить UIImage для backgroundColor действия строки, конкретно:
Swift:
UIColor(patternImage: UIImage(named: "IMAGE_NAME"))
Objective-C:
[UIColor colorWithPatternImage:[UIImage imageNamed:@"IMAGE_NAME"]];
Ответ 2
Swift 4 (iOS 11+):
iOS 11 теперь поддерживает изображения (только) для отображения в кнопках действий. Вам просто нужно инициализировать объект UISwipeActionsConfiguration в объекте делегата табличного представления:
extension MyTableViewController:UITableViewDelegate {
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .normal, title: nil, handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
debugPrint("Delete tapped")
success(true)
})
deleteAction.image = UIImage(named: "icon_delete.png")
deleteAction.backgroundColor = UIColor.red
return UISwipeActionsConfiguration(actions: [deleteAction])
}
}
Ответ 3
Я сделал эту простую категорию UITableViewRowAction, чтобы установить значок для моих действий. Вы можете установить изображение, цвет фона, высоту ячейки (для управления динамическими ячейками) и размер значка в процентах.
extension UITableViewRowAction {
func setIcon(iconImage: UIImage, backColor: UIColor, cellHeight: CGFloat, iconSizePercentage: CGFloat)
{
let iconHeight = cellHeight * iconSizePercentage
let margin = (cellHeight - iconHeight) / 2 as CGFloat
UIGraphicsBeginImageContextWithOptions(CGSize(width: cellHeight, height: cellHeight), false, 0)
let context = UIGraphicsGetCurrentContext()
backColor.setFill()
context!.fill(CGRect(x:0, y:0, width:cellHeight, height:cellHeight))
iconImage.draw(in: CGRect(x: margin, y: margin, width: iconHeight, height: iconHeight))
let actionImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.backgroundColor = UIColor.init(patternImage: actionImage!)
}
}
Ответ 4
class TableViewRowAction: UITableViewRowAction
{
var image: UIImage?
func _setButton(button: UIButton)
{
if let image = image, let titleLabel = button.titleLabel
{
let labelString = NSString(string: titleLabel.text!)
let titleSize = labelString.sizeWithAttributes([NSFontAttributeName: titleLabel.font])
button.tintColor = UIColor.whiteColor()
button.setImage(image.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
button.imageEdgeInsets.right = -titleSize.width
}
}
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
{
let delete = TableViewRowAction(style: UITableViewRowActionStyle.Default, title: " ") { action, indexPath in }
delete.image = UIImage(named: "trashImg")
let sharing = TableViewRowAction(style: UITableViewRowActionStyle.Default, title: " ") { action, indexPath in }
sharing.backgroundColor = UIColor.lightGrayColor()
sharing.image = UIImage(named: "sharingImg")
return [delete, sharing]
}
Ответ 5
Я просто реализую лучшую версию fooobar.com/questions/93291/... 1. В большинстве случаев высота ячейки и ширина настраиваемой части смахивания различаются, вы должны рассчитать это в вашей функции 2. Изображение может иметь разный размер чем квадрат, так что вы должны рассчитывать пропорции не только по высоте. Итак, код с моими исправлениями
func setIcon(iconImage: UIImage, backColor: UIColor, cellHeight: CGFloat, customSwipPartWidth: CGFloat, iconSizePercentage: CGFloat) {
let iconWidth = customSwipPartWidth * iconSizePercentage
let iconHeight = iconImage.size.height / iconImage.size.width * iconWidth
let marginY = (cellHeight - iconHeight) / 2 as CGFloat
let marginX = (customSwipPartWidth - iconWidth) / 2 as CGFloat
UIGraphicsBeginImageContextWithOptions(CGSize(width: customSwipPartWidth, height: cellHeight), false, 0)
let context = UIGraphicsGetCurrentContext()
backColor.setFill()
context!.fill(CGRect(x:0, y:0, width:customSwipPartWidth, height:cellHeight))
iconImage.draw(in: CGRect(x: marginX, y: marginY, width: iconWidth, height: iconHeight))
let actionImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.backgroundColor = UIColor.init(patternImage: actionImage!)
}
Ответ 6
delActions.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"delete.png"]];
Ответ 7
Проблема с базовым подходом к шаблону заключается в том, что ваше изображение должно быть того же размера, что и кнопка действия, или, по крайней мере, иметь более плоский фон внизу, чтобы предотвратить повторение изображения (хотя это будет быть привязанным сверху, что не очень приятно).
Мне приходилось иметь дело с ячейками динамической высоты, поэтому я реализовал следующее:
- (UIColor *)backgroundImageForActionAtIndexPath:(NSIndexPath *)indexPath withImage:(UIImage *)image tintColor:(UIColor *)tintColor backgroundColor:(UIColor *)backgrounfColor expectedWith:(CGFloat)width {
//
CGRect cellFrame = [self.tableView rectForRowAtIndexPath:indexPath];
CGSize expectedSize = CGSizeMake(width, cellFrame.size.height);
UIGraphicsBeginImageContextWithOptions(expectedSize, NO, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext ();
if (ctx) {
// set the background
CGContextSetFillColorWithColor(ctx, backgrounfColor.CGColor);
CGRect fillRect = CGRectZero;
fillRect.size = expectedSize;
CGContextFillRect(ctx, fillRect);
// put the image
CGContextSetFillColorWithColor(ctx, tintColor.CGColor);
CGRect rect = CGRectMake((expectedSize.width - image.size.width) / 2., (expectedSize.height - image.size.height) / 2., image.size.width, image.size.height);
[image drawInRect:rect];
}
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return [UIColor colorWithPatternImage:newImage];
}
Вам все равно нужно установить ожидаемую ширину так, чтобы она соответствовала пустой метке, помеченной в заголовке действия. например: @"" → 64.f
Как вы видите при таком подходе вы можете установить цвет фона кнопки и оттенка в коде, а не в самом художественном произведении.
Ответ 8
Мой вариант пытается использовать поведение UImageView contentMode, и когда этого было недостаточно, я нашел хорошее применение для пары методов Core Geometry Rect, поскольку они удерживают целевой кадр в центре кадра ячейки. Используя проверку зрения, кажется, что смахивание удаляло половину моей нормальной ширины ячейки, так что там, где появляются магические числа.
Swift 3.0
extension UITableViewRowAction {
func setIcon(iconImage: UIImage, backColor: UIColor, cellHeight: CGFloat, cellWidth:CGFloat) ///, iconSizePercentage: CGFloat)
{
let cellFrame = CGRect(origin: .zero, size: CGSize(width: cellWidth*0.5, height: cellHeight))
let imageFrame = CGRect(x:0, y:0,width:iconImage.size.width, height: iconImage.size.height)
let insetFrame = cellFrame.insetBy(dx: ((cellFrame.size.width - imageFrame.size.width) / 2), dy: ((cellFrame.size.height - imageFrame.size.height) / 2))
let targetFrame = insetFrame.offsetBy(dx: -(insetFrame.width / 2.0), dy: 0.0)
let imageView = UIImageView(frame: imageFrame)
imageView.image = iconImage
imageView.contentMode = .left
guard let resizedImage = imageView.image else { return }
UIGraphicsBeginImageContextWithOptions(CGSize(width: cellWidth, height: cellHeight), false, 0)
guard let context = UIGraphicsGetCurrentContext() else { return }
backColor.setFill()
context.fill(CGRect(x:0, y:0, width:cellWidth, height:cellHeight))
resizedImage.draw(in: CGRect(x:(targetFrame.origin.x / 2), y: targetFrame.origin.y, width:targetFrame.width, height:targetFrame.height))
guard let actionImage = UIGraphicsGetImageFromCurrentImageContext() else { return }
UIGraphicsEndImageContext()
self.backgroundColor = UIColor.init(patternImage: actionImage)
}
}
Использование: из метода editActions... делегата tableview.
let cellHeight = (self.tableView(tableView, cellForRowAt: indexPath)).frame.size.height
let cellWidth = (self.tableView(tableView, cellForRowAt: indexPath)).frame.size.width
let favorite = UITableViewRowAction(style: .normal, title: nil) { action, index in
//perform action
debugPrint("Test")
}
favorite.setIcon(iconImage: #imageLiteral(resourceName: "favorite"), backColor: .green, cellHeight: cellHeight, cellWidth:cellWidth)