Esquema de implementação de clareamento preto (cinza) do iOS

Dependendo do negócio, geralmente há dois requisitos para os produtos:

Requisito 1: Defina tudo como preto e branco
Requisito 2: Defina uma determinada interface como preto e branco
Implementação aproximada:

Opção um:

O servidor envia todas as imagens em preto (cinza) e a cor da fonte suporta entrega dinâmica
. Tudo bem se houver apenas uma interface, mas se você substituir todas as imagens, a carga de trabalho será muito grande

Opção II:

Envolve aproximadamente: imagem, cor do UILabel, cor do UIButton, webView, vídeo, etc.

Para imagem, UIImageView é geralmente usado para exibir, portanto, use o método exchange em tempo de execução para permitir que o método setImage: tome conta dele.
Em seguida, adicione um filtro à imagem no método privado

+ (void)load {     Method customMethod = class_getInstanceMethod([self class], @selector(setImage:));     Método originMethod = class_getInstanceMethod([autoclasse], @selector(gl_setImage:));     method_exchangeImplementations(customMethod, originMethod);//方法交换}



- (void)gl_setImage:(UIImage *)image {       //Se para preto e branco, 1 significa aberto     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel == 1) {         [self gl_setImage :[ self gl_grayImage:image]];     } else {         [self gl_setImage:image];     } }







- (UIImage *)gl_grayImage:(UIImage *)image {         //UIKBSplitImageView是为了键盘     if (image == nil || [self.superview isKindOfClass:NSClassFromString(@"UIKBSplitImageView")]) {         return image;     }     //Aplicativo     do CIPhotoEffectNoir//     Aplicativo do CIPhotoEffectMono     NSString *filterName = @"CIPhotoEffectMono";     CIFilter *filter = [CIFilter filterWithName:filterName];     CIImage *inputImage = [[CIImage alloc] initWithImage:image];     [filtro setValue:inputImage forKey:kCIInputImageKey];     CGImageRef cgImage = [self.filterContext createCGImage:filter.outputImage fromRect:[extensão da imagem de entrada]];     UIImage *resultImg = [UIImage imageWithCGImage:cgImage];




    









    CGImageRelease(cgImage);
    return resultImg;
}

- (CIContext *)filterContext {     CIContext *con = objc_getAssociatedObject(self, @selector(filterContext));     if (!con) {         con = [[CIContext alloc] initWithOptions:nil];         self.filterContext = con;     }     return con; }






- (void)setFilterContext:(CIContext *)filterContext {     objc_setAssociatedObject(self, @selector(filterContext), filterContext, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }

H5 acinzentado - classificação

Arquivo WKWebView+blackWhiteModel.m:

#import "WKWebView+blackWhiteModel.h"
#import <objc/runtime.h>

@implementation WKWebView (blackWhiteModel)
+ (void)load {     Method customMethod = class_getInstanceMethod([self class], @selector(gl_initWithFrame:configuration:));     Método originMethod = class_getInstanceMethod([autoclasse], @selector(initWithFrame:configuration:));     method_exchangeImplementations(customMethod, originMethod);//方法交换}




- (instancetype)gl_initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
{     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel) {         // js脚本         NSString *jScript = @"var filter = '-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%); -ms-filter:grayscale(100% ); -o-filter:grayscale(100%) filter:grayscale(100%);';document.getElementsByTagName('html')[0].style.filter = 'grayscale(100%)';";         // Nome do         WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScriptjectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];






                     
        WKUserContentController *wkUController = [[WKUserContentController alloc] init];
           [wkUController addUserScript:wkUScript];
        // Configuração
        do WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
        wkWebConfig.userContentController = wkUController;
        configuração = wkWebConfig;
        WKWebView *webView = [self gl_initWithFrame:configuração do quadro:configuração];
        retornar webView;
    }
    
    return [self gl_initWithFrame:configuração do quadro:configuração];
}
@end

Processamento preto e branco da interface do aplicativo iOS (processamento em tons de cinza) (preparado para o dia do memorial)

Há um problema com a solução acima, porque é um método init de substituição, que fará com que o webView antes do switch seja 0 seja colorido e o webView após o switch seja 1 para ser cinza. Portanto, certifique-se de confirmar que o resultado da solicitação de alternar é antes de criar o webView
. ou posteriormente

H5 acinzentado - único

Pode ser acinzentado para um único H5

Igual ao código js acima:

    BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];
        
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userController = [[
    WKUserContentController alloc]
    
    init]; {         //modo Memorial Day substitui o tema geral cor de wkView         [userController addUserScript:[self getJsStr]];     }


-(WKUserScript *)getJsStr{     NSString *jScript = @"var filter = '-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%); -ms-filter:grayscale(100%); -o-filter:grayscale(100%) filter:grayscale(100%);';document.getElementsByTagName('html')[0].style.filter = 'grayscale(100%)';";     // Nome do     WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScriptjectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];     retornar wkUScript; }




iOS Modo Memorial Day

Para outras classificações de UILabel, UIButton, etc., consulte:

https://github.com/GeLeis/App_NoirDemo

terceira solução:

O processamento de imagem é semelhante à Solução 2
, mas as cores de Label, View, etc. não são mais classificadas uma a uma e a classificação de Color é modificada diretamente


+ (void)load {     //关键方法交换     Method customMethod = class_getClassMethod([self class], @selector(gl_colorWithRed:green:blue:alpha:));     Método originMethod = class_getClassMethod([autoclasse], @selector(colorWithRed:green:blue:alpha:));     method_exchangeImplementations(customMethod, originMethod);//方法交换}




+ (UIColor *)gl_colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { // Se for modo monocromático (modo preto e branco), a     média r, g, valor b     //se preto e branco, 1 significa aberto     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel) {         //r, g, b ajuste de peso para evitar ocorrência, 1 0 0, 0 1 0 ,0 0 1 the same result         //0.2126, 0.7152, 0.0722 Esses três são calculados de acordo com a força do olho humano para o r, g, b percepção de superfície de três cores CGF         brilho flutuante = (vermelho * 0,2126 + 0,7152 * green + 0.0722 * blue);         return [self gl_colorWithRed:brightness green:brightness blue:brightness alpha:alpha];     }     return [self gl_colorWithRed:red green:green blue:blue alpha:alpha]; }











iOS implementa app em modo preto e branco

Opção quatro:

Não mais pelo método de tempo de execução, mas adicione diretamente um filtro cinza à exibição

    //Obtém valor de cor RGBA
   CGFloat r,g,b,a;
   [[UIColor lightGrayColor] getRed:&r green:&g blue:&b alpha:&a]; //
   Cria
   ID de filtro cls = NSClassFromString(@"CAFilter");
   id filter = [cls filterWithName:@"colorMonochrome"];
   //Definir os parâmetros do filtro
   [filter setValue:@[@(r),@(g),@(b),@(a)] forKey:@"inputColor "] ;
   [filter setValue:@(0) forKey:@"inputBias"];
   [filter setValue:@(1) forKey:@"inputAmount"];
   //Definir para a janela
   self.window.layer.filters = [NSArray arrayWithObject: filtro];

Os valores de r, g, b e a podem ser modificados diretamente em vez de [UIColor lightGrayColor]

Se for apenas um determinado controlador A, A.view.layer.filters = [NSArray arrayWithObject:filter];basta configurá-lo

A página do aplicativo iOS está esmaecida

Claro, existem outros filtros que podem ser usados

id cls = NSClassFromString(@"CAFilter");
id filtro = [cls filterWithName:@"colorSaturate"];
[filter setValue:@(0) forKey:@"inputAmount"];
//Configuração da janela
self.window.layer.filters = [NSArray arrayWithObject:filter];

Filtros do CALayer

CAFilter é um método privado da Apple, que pode ser rejeitado, portanto, este método não é usado

abordagem final

Adicionar uma exibição que não recebe eventos de clique

@interface ZRLandlordHPGrayView : UIView

@fim

@implementation ZRLandlordHPGrayView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{     return nil; }

@fim

Em seguida, na interface que precisa exibir o modo preto e branco, adicione o seguinte método:

- (void)showGrayViewWithSuperView:(UIView *)superView
{     //Este método é usado para armazenar se é o modo preto e branco     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel) {         if ( @available( iOS 12.0, *)) {//Somente compatível com ZRLandlordHPGrayView 12 e superior             *overlay = [[ZRLandlordHPGrayView alloc] initWithFrame:superView.bounds];             overlay.userInteractionEnabled = NO;             overlay.translatesAutoresizingMaskIntoConstraints = false;             overlay.backgroundColor = [ UIColor grayColor];             overlay.layer.compositingFilter = @"saturationBlendMode";             [superView addSubview:overlay];










            [superView bringSubviewToFront:overlay];
        } }
    }

Este método suporta apenas 12 e acima.
Depois de olhar para nosso aplicativo, há basicamente muito poucos abaixo de 12, então finalmente escolhi este método

Outros artigos de referência:
Discussão da solução de cinza da interface do iOS
Modo de dia de luto do iOS
usando magia negra no iOS para obter uma solução global de cinza de imagem com um clique
Interface do aplicativo iOS Processamento em preto e branco (processamento em escala de cinza) (preparado para o dia de luto)

CALayer 的 filtros
CAFilter

Acho que você gosta

Origin blog.csdn.net/ForeverMyheart/article/details/128187220
Recomendado
Clasificación