Ich habe eine benutzerdefinierte UITableViewRowAction erstellt. Jetzt möchte ich anstelle des Textes ein Bild hinzufügen. Ich weiß, dass es möglich ist, weiß aber nicht, wie es geht. Weiß jemand von Ihnen, wie man das in Swift macht und möchte mir helfen? Danke für Ihre Antworten!
Sie müssen UIImage auf backgroundColor der Zeilenaktion setzen, konkret durch:
Schnell:
UIColor(patternImage: UIImage(named: "IMAGE_NAME"))
Ziel c:
[UIColor colorWithPatternImage:[UIImage imageNamed:@"IMAGE_NAME"]];
Ich habe diese einfache UITableViewRowAction-Kategorie erstellt, um das Symbol für meine Aktionen festzulegen .. Sie können das Bild, die Hintergrundfarbe, die Zellenhöhe (zur Verwaltung dynamischer Zellen) und die Symbolgröße in Prozent festlegen.
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!)
}
}
Swift 4 (iOS 11+):
iOS 11 unterstützt jetzt (nur) Bilder zur Anzeige in Aktionstasten. Sie müssen lediglich ein UISwipeActionsConfiguration-Objekt in Ihrem Tabellensicht-Delegatenobjekt initialisieren:
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])
}
}
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]
}
Ich implementiere einfach eine bessere Version von https://stackoverflow.com/a/48122210 1. In den meisten Fällen unterscheiden sich die Zellenhöhe und die Breite des benutzerdefinierten Swipe-Teils. Sie müssen dies in Ihrer Funktion berechnen 2. Das Bild kann eine andere Größe haben als das Quadrat, daher müssen Sie die Proportionen nicht nur für die Höhe berechnen, sondern auch mit meinen Korrekturen
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!)
}
Bei meiner Variation wird versucht, das Verhalten von UImageView mit contentMode zu verwenden. Wenn dies nicht ausreichte, fand ich eine gute Verwendung für einige der Core Geometry Rect-Methoden, da der Zielrahmen innerhalb des Zellenrahmens zentriert bleibt. Bei einem Sehtest scheint das Wischen die Hälfte meiner normalen Zellbreite zu entfernen, so dass die magischen Zahlen angezeigt werden.
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)
}
}
Verwendung: Aus der editActions ... -Methode des Tableview-Delegaten.
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)
Das Problem mit dem grundlegenden Musterfarbenansatz besteht darin, dass Ihr Bild die gleiche Größe wie die Aktionstaste haben muss oder zumindest einen flacheren Hintergrund am unteren Rand haben muss, um die Wiederholung des Bildes zu verhindern (auch wenn es verankert ist top, was nicht wirklich schön ist).
Ich musste mich mit Zellen mit dynamischer Höhe beschäftigen, also habe ich Folgendes implementiert:
- (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];
}
Sie müssen noch die erwartete Breite einstellen, damit sie mit dem leeren Label übereinstimmt, das Sie in den Titel der Aktion einfügen. z.B.: @ "" -> 64.f
Wie Sie mit diesem Ansatz sehen, können Sie den Hintergrund und die Farbtonfarbe der Schaltfläche im Code und nicht im Bildmaterial selbst festlegen.
delActions.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"delete.png"]];