iOS WKWebView get RGBA pixel color from point

1k views Asked by At

How can I get the RGBA pixel color of a point from a WKWebView?

I have a working solution for the UIWebView, but I would like to use the WKWebView instead. When I tap on a point of the screen I'm able to retrieve the color value in RGBA from the UIWebView for example (0,0,0,0) when it's transparent or something like (0.76,0.23,0.34,1) when it not transparent. The WKWebView always return (0,0,0,0) instead.

More details

I'm working on an iOS app with a WebView as a most top ui element.

The WebView has areas which are transparent so that you can see the the underlying UIView.

The WebView shall ignore touches on transparent areas and the underlying UIView shall retrieve the event instead.

Therefor I did override the hitTest function:

#import "OverlayView.h"
#import <QuartzCore/QuartzCore.h>

@implementation OverlayView

-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event {

    UIView* subview = [super hitTest:point withEvent:event];  // this will always be a webview

    if ([self isTransparent:point fromView:subview.layer]) // if point is transparent then let superview deal with it
    {
        return [self superview];
    }

    return subview; // return webview
}

- (BOOL) isTransparent:(CGPoint)point fromView:(CALayer*)layer
{
    unsigned char pixel[4] = {0};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(context, -point.x, -point.y);

    [layer renderInContext:context];

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    return (pixel[0]/255.0 == 0) &&(pixel[1]/255.0 == 0) &&(pixel[2]/255.0 == 0) &&(pixel[3]/255.0 == 0) ;
}

@end

My assumption is that the WKWebView has a different CALayer or an hidden UIView where it draw the actual webpage to.

1

There are 1 answers

1
Tassilo Waldraff On BEST ANSWER
#import "OverlayView.h"
#import <QuartzCore/QuartzCore.h>

@implementation OverlayView

-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event {

    UIView* subview = [super hitTest:point withEvent:event];  // this should always be a webview

    if ([self isTransparent:[self convertPoint:point toView:subview] fromView:subview.layer]) // if point is transparent then let superview deal with it
    {
        return [self superview];
    }

    return subview; // return webview
}

- (BOOL) isTransparent:(CGPoint)point fromView:(CALayer*)layer
{
    unsigned char pixel[4] = {0};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(context, -point.x, -point.y );

    UIGraphicsPushContext(context);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
    UIGraphicsPopContext();

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    return (pixel[0]/255.0 == 0) &&(pixel[1]/255.0 == 0) &&(pixel[2]/255.0 == 0) &&(pixel[3]/255.0 == 0) ;
}

@end

This code fixed my problem.