0

I'm trying to place a red tint on all the screens of my iPhone application. I've experimented on a bitmap and found I get the effect I want by compositing a dark red color onto the screen image using Multiply (kCGBlendModeMultiply).

So the question is how to efficiently do this in real time on the iPhone?

One dumb way might be to grab a bitmap of the current screen, composite into the bitmap and then write the composited bitmap back to the screen. This seems like it would almost certainly be too slow. In addition, I need some way of knowing when part of the screen has been redrawn so I can update the tinting.

I can almost get the effect I want by putting a red, translucent, fullscreen UIView above everything. That tints everything red within further intervention on my part, but the effect is much "muddier" than results from the composite.

So do any wizards out there know of some mechanism I can use to automatically composite the red over the app in similar fashion to what the translucent red UIView does?

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
btschumy
  • 1,435
  • 1
  • 18
  • 35

2 Answers2

3

I managed to somewhat make this work but with some side-effects:

  1. I setup a UIView on top of all my app-views (attached to the window) which is not userInteractionEnabled and which is opaque

  2. This UIView carries some custom drawRect-method which first fills the complete area with red color and then after having made a "screenshot" of my window-viewhierarchy I am rendering this image with

    CGContextSetBlendMode( c, kCGBlendModeMultiply);
    

    to the UIView.

  3. To constantly update this UIView to the current state of the apps UIViews I constantly produce "screenshots" and render them as fast as possible.

  4. I setup an NSTimer which is doing this snapshotting/rendering in a defined frequency and which is added to the the NSRunLoop for "Tracking".

  5. RESULT: some really laggy response from the UI with several fancy effects, but still usable though if you do not set the frequency of snapshotting/rendering to high.

See screenshot here...

enter image description here

The result looks okay, but the usability really suffers a lot. I had a look at the OpenGL-examples before trying this aproach, but OpenGL is a whole lot of different (mostly C) code which seems to be very near to the hardware and which gives you a real headache.

So, the described approach is what I will shoot for with my next app. I hope Apple accepts it even though it degrades UXP during nightvision mode. They should simply make CALayer filter-backed then my problem will definitely be solved a whole lot better and performing nicely.

Mohsen Safari
  • 6,669
  • 5
  • 42
  • 58
0

You could try this: subclass UIView. Add code to -drawRect method to draw the overlay. Make your UIView subclass pose as UIView everywhere in your app with

class_poseAs ([CustomUIView class], [UIView class]);
luvieere
  • 37,065
  • 18
  • 127
  • 179
  • Yes, I was looking into poseAs, but as PeyloW says, Apple doesn't seem to want you to use it anymore. Even if it weren't I think it was not recommended to call the original routine you were overriding. – btschumy Sep 24 '09 at 16:23