UIActivityViewController no longer displaying application activity icons under iOS 17

644 Views Asked by At

I'm just now testing my app under iOS 17 (beta 7). One strange issue I'm seeing is with UIActivityViewController. My app provides several custom application UIActivity instances. Under iOS 17.0 beta 7 on an iPhone 14 Pro simulator, none of the icons for my custom activities appear. These are activities declared in the "share" category which are the row of activities along the top of the activity view. Instead of the expected icon, only the rounded rect shadow appears. The activity name appears as expected.

Oddly, custom activities declared in the "action" category appear just fine. It's only an issue with the "share" activities. iOS provided activities are showing their icons as expected.

This picture shows where 3 of my custom activities are. None of the icons are displayed. The "Freeform" activity is provided by iOS.

enter image description here

This is code that has worked for a decade. It works just fine if I run against an iOS 15 or 16 simulator. The problem is only with iOS 17.

I don't see anything in the documentation for UIActivityViewController or UIActivity. I've looked at the HIG and don't see anything relevant in there. I've found no reference to this issue on SO or the Apple developer forums.

The relevant images are setup in an image asset in my project. The images are 60pt for scales 1, 2, and 3. The documentation for UIActivity still states that the icons should be 60pt for iOS 7 and later (no mention of any change for iOS 17).

The relevant code in my custom UIActivity is as follows:

- (UIImage *)activityImage {
    return [UIImage imageNamed:@"activity1"];
}

I have verified that this activityImage property is being called and it is returning the same image it always has. The PNG is an 8-bit/color RGBA, non-interlaced image.

I'm not having any issues with any other images or icons in the rest of my app. Only with UIActivityViewController.

Has anyone encountered this issue with iOS 17? Is there some change I'm not aware of?

1

There are 1 best solutions below

1
HangarRash On

I don't know why this works but if I change the activityImage code from:

- (UIImage *)activityImage {
    return [UIImage imageNamed:@"activity1"];
}

to:

- (UIImage *)activityImage {
    UIImage *res = [UIImage imageNamed:@"activity1"];
    if (@available(iOS 17.0, *)) {
        res = [res imageByPreparingThumbnailOfSize:res.size];
    }
    return res;
}

then the activity image appears on the UIActivityViewController. The image is still the same size, the same rendering mode, the same format, etc. But clearly the call to imageByPreparingThumbnailOfSize: must be making some relevant change to make it work.

If I look at the image before and after calling imageByPreparingThumbnailOfSize: there is one very tiny difference in the output but I don't know what it represents.

Output of po res.CGImage before calling imageByPreparingThumbnailOfSize::

<CGImage 0x11755ed20> (IP)
    <<CGColorSpace 0x60000260c300> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1)>
        width = 180, height = 180, bpc = 8, bpp = 32, row bytes = 720 
        kCGImageAlphaNoneSkipLast | 0 (default byte order)  | kCGImagePixelFormatPacked 
        is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes

Output of po res.CGImage after calling imageByPreparingThumbnailOfSize::

<CGImage 0x117778b30> (DP)
    <<CGColorSpace 0x60000260c300> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1)>
        width = 180, height = 180, bpc = 8, bpp = 32, row bytes = 720 
        kCGImageAlphaNoneSkipLast | 0 (default byte order)  | kCGImagePixelFormatPacked 
        is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes

Besides the memory address, the only change in the output is in the first line. The original image shows "(IP)" while the updated images shows "(DP)".

If anyone knows what those represent, please post a comment.


I note that the icons are not automatically given rounded corners like they do on iOS 16 and earlier. But that's a separate issue to resolve. Just a heads-up to anyone else dealing with these undocumented features of UIActivityViewController in iOS 17.


For everyone using Swift, the code is being changed from:

override var activityImage: UIImage? {
    return UIImage(named: "activity")
}

to:

override var activityImage: UIImage? {
    var res = UIImage(named: "activity1")
    if #available(iOS 17.0, *) {
        if let img = res {
            res = img.preparingThumbnail(of: img.size)
        }
    }
    return res
}