4

While testing our app we came across an interesting bug. We have some swipe actions in our table configured like so:

let retryAction = UIContextualAction(style: .destructive, title: "Remove")
retryAction.image = UIImage(named: "iconUploadRemove")

let retryAction = UIContextualAction(style: .normal, title: "Retry")
retryAction.image = UIImage(named: "iconUploadRetry")

Since we set an image, users would normally see icons when they swipe on the table row:Swipe Action with Icons

Swipe Action with Icons

But if a user increases their text sizeIncreases their text size

Then the action titles show up along with the icons

the action titles show up along with the icons

Having both text and icon isn't necessarily a problem except for the alignment/spacing of the text between the two actions. It appears to be the length of the string that is causing this. If I set the text to the same string, both actions are aligned equally. I know I can set the title to nil, which would prevent the text from appearing when large text is enabled.

But why does the text show up in this mode? And is it possible to have both the text and the icon display correctly aligned on each action button?

InbetweenWeekends
  • 1,405
  • 3
  • 23
  • 28
TodayMorning
  • 201
  • 2
  • 8
  • Hi, Can you please tell me the size of the icon you set in the UIContextualAction. i am stuck to set image in the UIContextualAction..Please see my question post ..https://stackoverflow.com/questions/50677458/how-can-add-image-in-uicontextualaction-in-uitableview-datasource-method?noredirect=1#comment88364890_50677458 – Niraj Paul Jun 04 '18 at 10:27

4 Answers4

2

I ran into the exact same issue today. The root cause is that UIKit is allowing the UILabel to go on 2 lines even if it's not needed:

This would be the proper use case:

So the only solutions I see are ugly. Overriding, swizzling, drilling through the subviews until we find the label subclass, etc... And I am not clear what (if not all) solution would get you rejected from the store.

Or simply not use this new iOS 11 API and stick with the old one UITableViewRowAction.

Pierre Espenan
  • 3,996
  • 5
  • 33
  • 51
2

You can make those text aligned without method swizzling.

To achieve it, you have to set all of your action images with same height. You can do this at runtime:

    var actionImages = ["TrashCan", "Folder"].map { UIImage(named: $0)! }
    let maxHeight = actionImages.map { $0.size.height }.max()!

    for (index, image) in actionImages.enumerated() where image.size.height < maxHeight {
        let size = CGSize(width: image.size.width, height: maxHeight)
        actionImages[index] = UIGraphicsImageRenderer(size: size).image { context in
            var centralizedRect = CGRect(origin: .zero, size: image.size)
            centralizedRect.origin.y = (maxHeight - image.size.height) / 2
            image.draw(in: centralizedRect)
        }
    }

    // set images to your UIContextualAction…

The result is something like this:

Result

Still not perfect (too much space below the text), but bearable.

Jonny
  • 1,969
  • 18
  • 25
1

It doesn't appear there is an answer to why the text appears, and appears mis-aligned.

For anyone who comes across this question, we ended up setting the titles to nil for these buttons to keep them "icon only".

TodayMorning
  • 201
  • 2
  • 8
1

you need to play with image PNG. make its canvas size increased / adjusted (white space around) until you get result

In my case I set

Cell height : 92 Icon image width : 32 Icon image height : 40

and all is perfectly aligned finally.

Mani
  • 101
  • 10