There is a property on CALayer that has been overlooked for a long time: filters. The official Documentation of Apple only provides an example of CIFilter, but in fact CIFilter has no effect after being set. At the same time, it is also indicated below that CIFilter is not supported on iOS. (Here is the full list of CIFilters)

@interface CALayer : NSObject <NSSecureCoding.CAMediaTiming>

/* An array of filters that will be applied to the contents of the * layer and its sublayers. Defaults to nil. Animatable. */

@property(nullable.copy) NSArray *filters;

@end
Copy the code

In fact, iOS does support live filters, but with a private class called CAFilter. It is defined as follows and looks like CIFilter’s full brother:

@interface CAFilter : NSObject <NSSecureCoding.NSCopying>
@property (readonly) NSString* type;
@property (copy) NSString* name;
@property (getter=isEnabled) BOOL enabled;
@property BOOL cachesInputImage;

+ (instancetype)filterWithType:(NSString *)type;
+ (instancetype)filterWithName:(NSString *)name;
+ (NSArray <NSString *> *)filterTypes;

- (instancetype)initWithType:(id)type;
- (instancetype)initWithName:(id)name;

- (void)setDefaults;
@end
Copy the code

Currently supported filter names (iOS 13) include the following:

  • multiplyColor
  • colorAdd
  • colorSubtract
  • colorMonochrome
  • colorMatrix
  • colorHueRotate
  • colorSaturateparameterinputAmount
  • colorBrightness
  • colorContrast
  • colorInvert
  • compressLuminance
  • meteor
  • luminanceToAlpha
  • bias
  • distanceField
  • gaussianBlurparameterinputRadius
  • luminanceMap
  • luminanceCurveMap
  • curves
  • averageColor
  • lanczosResize
  • pageCurl
  • vibrantDark
  • vibrantLight
  • vibrantColorMatrix

Recently, the whole country mourned for the Tomb Sweeping Day. In order to pay respects to the martyrs who sacrificed their lives in the fight against the epidemic and the people who died, in addition to the offline flag flying at half-mast and the air defense siren, the online app and web page were also requested to suspend, or painted in black and white, which was a big test of the app operation and configuration ability. With the CAFilter above, you can pre-embed 5 lines of code to make the entire app black and white:

self.window.layer.filters = @[({
    CIFilter *filter = [NSClassFromString(@"CAFilter") filterWithName:@"colorSaturate"];  // CIFilter = CAFilter
    [filter setValue:@0 forKey:@"inputAmount"];
    filter;
})];
Copy the code

Note: This private API is at risk of being rejected