web-dev-qa-db-de.com

UITableViewRowAction-Bild für den Titel

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!

29
user3592462

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"]];
40
dimpiax

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!)
  }
}
6
Il Pisanello

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])
    }

}

6
Peter Kreinz
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
Jayesh Miruliya

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)
0
Tommie C.

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.

0
Jim75
delActions.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"delete.png"]];
0
Subhro