Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS WKWebView get RGBA pixel color from point

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.

like image 630
Tassilo Waldraff Avatar asked Jun 24 '15 22:06

Tassilo Waldraff


1 Answers

#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.

like image 84
Tassilo Waldraff Avatar answered Nov 15 '22 15:11

Tassilo Waldraff