Skip to content

Instantly share code, notes, and snippets.

@timonus
Last active January 1, 2024 12:08
Show Gist options
  • Save timonus/8b4feb47eccb6dde47ca6320d8fc6b11 to your computer and use it in GitHub Desktop.
Save timonus/8b4feb47eccb6dde47ca6320d8fc6b11 to your computer and use it in GitHub Desktop.
Programmatically create iOS 13 dynamic images
- (UIImage *)dynamicImage
{
UITraitCollection *const baseTraitCollection = /* an existing trait collection */;
UITraitCollection *const lightTraitCollection = [UITraitCollection traitCollectionWithTraitsFromCollections:@[baseTraitCollection, [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]];
UITraitCollection *const purelyDarkTraitCollection = [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark];
UITraitCollection *const darkTraitCollection = [UITraitCollection traitCollectionWithTraitsFromCollections:@[baseTraitCollection, purelyDarkTraitCollection]];
__block UIImage *lightImage;
[lightTraitCollection performAsCurrentTraitCollection:^{
lightImage = /* draw image */;
}];
__block UIImage *darkImage;
[darkTraitCollection performAsCurrentTraitCollection:^{
darkImage = /* draw image */;
}];
[lightImage.imageAsset registerImage:darkImage withTraitCollection:purelyDarkTraitCollection];
return lightImage;
}
@lafezhang
Copy link

After creating an imageAsset and registering the image with traitCollection more than 65535 times, the image taken by imageAsset.image(with:) will always be wrong. P.S. Tried all of the above solutions.

@cragod did you find any solution?

@cragod
Copy link

cragod commented Dec 28, 2023

After creating an imageAsset and registering the image with traitCollection more than 65535 times, the image taken by imageAsset.image(with:) will always be wrong. P.S. Tried all of the above solutions.

@cragod did you find any solution?

not yet, just use the cache to delay its occurrence.

@lafezhang
Copy link

After creating an imageAsset and registering the image with traitCollection more than 65535 times, the image taken by imageAsset.image(with:) will always be wrong. P.S. Tried all of the above solutions.

@cragod did you find any solution?

not yet, just use the cache to delay its occurrence.

The reason has been identified:

  1. When creating UIImageAsset and registering images, Apple will use an auto-increment as the identifier for the image asset and cache it in a global container. And it will also bind the identifier to the imageAsset object. You can inspect the auto-increment identifier using po [[UIImage new] valueForKeyPath:@"imageAsset._unsafe_mutableCatalog._themeStore._maxNameIdentifier"] in the debugger.
  2. However, when retrieving from the cache, Apple will the identifier = {original identifier} & 0xffff. So, the identifier 65536 becomes 1, which causes the unexpected result.
    image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment