Using buttons/images in tableView:editActionsForRo

2019-08-26 22:39发布

问题:

I am trying to use tableView:editActionsForRowAt:, having buttons with images instead of the usual texts. But there are some challenges. Can some one help me?

First here is what I have already working, -- with some precious help from SOF --

and here is what I would like to get ideally:

The relevant code is below. The first case above is obtained when having xShift and xShiftInc both set to 0.0. The second case is obtained by initializing xShift to 30.0 and xShiftInc to 20.0.

Graphically I get the result I want, but the problem is that the touch areas for the buttons have not moved as the image. In other words in the second case, if I touch the trash it prints "upBtn touched!". To get "rmvBtn touched!" printed I need touch at the left of the trash.

Beside, I am not very happy with using 46.0 for the height of the cell, I would like a more generic parameter (rowHeigh equals -1 so can't be used). But this is a different issue.

func tableView(_ tableView: UITableView,
               editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    var patternImg:UIImage?, xShift = CGFloat(30.0)//CGFloat(0.0)//
    let xShiftInc = CGFloat(20.0)//CGFloat(0.0)//

    let downBtn = UITableViewRowAction(style: .normal, title: "") {
        action, index in
        print("downBtn touched!")
    }
    patternImg = swipeCellImage(named: "DownIcn", side: 46.0, horizOffSet: xShift)
    downBtn.backgroundColor = UIColor(patternImage: patternImg!)

    let upBtn = UITableViewRowAction(style: .normal, title: "") {
        action, index in
        print("upBtn touched!")
    }
    xShift += xShiftInc
    patternImg = self.swipeCellImage(named: "UpIcn", side: 46.0, horizOffSet: xShift)
    upBtn.backgroundColor = UIColor(patternImage: patternImg!)

    let rmvBtn = UITableViewRowAction(style: .destructive, title: "") {
        action, index in
        print("rmvBtn touched!")
    }
    xShift += xShiftInc
    patternImg = swipeCellImage(named: "TrashIcn", side: 46.0, horizOffSet: xShift)
    rmvBtn.backgroundColor = UIColor(patternImage: patternImg!)

    return [downBtn,upBtn,rmvBtn]
}


func swipeCellImage(named name: String, side: CGFloat, horizOffSet: CGFloat) -> UIImage? {
    let theImage = UIImage(named: name)
    UIGraphicsBeginImageContextWithOptions(CGSize(width: UIScreen.main.bounds.width,
                                                  height: side), false, UIScreen.main.scale)
    let context = UIGraphicsGetCurrentContext()
    context!.setFillColor(UIColor.clear.cgColor)
    theImage?.draw(in: CGRect(x: horizOffSet, y: 0, width: side, height: side))
    let resultImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return resultImage
}

回答1:

Simple logic..!! Manually we dont give xshift and xshiftinc.

Case 1:

let downBtn = UITableViewRowAction(style: .normal, title: "") {
        action, index in
        print("downBtn touched!")
}

Here title's text is "" [empty string with no spaces]

So, tableview automatically takes width 30px for each one. If we add text, it will increase it width sizes automatically.

Case 2:

let downBtn = UITableViewRowAction(style: .normal, title: " ") {
        action, index in
        print("downBtn touched!")
}

Here title's text is "" [empty string with 1 space]

So, tableview automatically takes width 35px for this.

Hope you understand above thing.

Now, I modified your code.

 func tableView(_ tableView: UITableView,
               editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {


    let cell = tableView.cellForRow(at: indexPath) as!      myTableViewCell

    print("cell_height    ", cell.frame.size.height) // U MAY GET ROW HEIGHT HERE

    var patternImg:UIImage?

    let downBtn = UITableViewRowAction(style: .normal, title: "  ") {
        action, index in
        print("downBtn touched!")
    }
    patternImg = swipeCellImage(named: "down", rowHeight: cell.frame.size.height)
    downBtn.backgroundColor = UIColor(patternImage: patternImg!)

    let upBtn = UITableViewRowAction(style: .normal, title: "  ") {
        action, index in
        print("upBtn touched!")
    }

    patternImg = self.swipeCellImage(named: "up", rowHeight: cell.frame.size.height)
    upBtn.backgroundColor = UIColor(patternImage: patternImg!)

    let rmvBtn = UITableViewRowAction(style: .destructive, title: "  ") {
        action, index in
        print("rmvBtn touched!")
    }

    let patternIm = swipeCellImage(named: "trash", rowHeight: cell.frame.size.height)

    rmvBtn.backgroundColor = UIColor(patternImage: patternIm!)


    return [downBtn,upBtn,rmvBtn]
}


func swipeCellImage(name: String, rowHeight: CGFloat) -> UIImage? {

    let imgYposition : CGFloat = (rowHeight - 30) / 2

    // NOTE: This 30px is image height. Image height is always should be less than Rowheight.

    let theImage = UIImage(named: name)
    UIGraphicsBeginImageContextWithOptions(CGSize(width: UIScreen.main.bounds.width,
                                                  height: rowHeight), false, UIScreen.main.scale)
    let context = UIGraphicsGetCurrentContext()
    context!.setFillColor(UIColor.yellow.cgColor)
    context!.fill(CGRect(x: 0, y: 0, width: (self.view.frame.width) / 3, height: side))

    theImage?.draw(in: CGRect(x: 5, y: imgYposition, width: 30, height: 30))

    // In this sample, am taking rowHeight as 44px.
    // Images should be 30 * 30 sizes.
    // I gave two spaces in title. So total width is 40px.
    // So,x = 5px and y = 7px.

    let resultImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return resultImage
}

Output

If you want to give more gap between three buttons, just increase title's empty text and calculate width and keep your image center.