5

I have been able to put a semitransparent view above all the other views, including the keyboard, to tint the screen using this code:

int count = [[[UIApplication sharedApplication]windows]count];
[[[UIApplication sharedApplication] windows] objectAtIndex:count-1]addSubview:tintView];

Now I've run across a problem. My app uses MessageUI.framework to display a MFMessageComposeViewController, which allows the user to send a text message. Here is where I run across the problem.

When I execute the above code in this case (when the message view is showing), it works correctly. The problem is, the user can no longer interact with the message view below it. I have been setting userinteractionenabled to NO on my tintView, but in this case it does not help the problem.

Setting the tint view hidden to YES, however, does allow interaction. Something does by changing this property allows the message view to be interacted with. Obviously I want the tintView to be visible, though.

I NSLogged the views in the topmost UIWindow and found that the UIRemoteView (which I could find no info whatsoever about but seems to be what displays the views in the MessageUI.framework) is the view not receiving the touch when the tintView is above it.

How can I allow interaction with the MFMessageComposeViewController even with another UIView displayed over it. Userinteractionenabled does not work in this case, but setting the view to hidden (which isn't what I want) does.

NSProgrammer
  • 2,387
  • 1
  • 24
  • 27
jadengeller
  • 1,307
  • 1
  • 14
  • 26
  • 1
    Did you try `[tintView becomeFirstResponder];` – Scar Jul 18 '12 at 06:08
  • 1
    I want the tintView to ignore user inputs and allow the view below it to handle them. This works fine except when I try to use the MessageUI.framework. So, no, I did not try that, because I don't want tintView to respond to input. I did however try "[tintView resignFirstResponder]" and "[[[[[[UIApplication sharedApplication] windows]objectAtIndex:0]subviews]objectAtIndex:0]becomeFirstResponder]" – jadengeller Jul 18 '12 at 06:13
  • Any result on this? This is still an issue that I see. – NSProgrammer Feb 28 '14 at 18:34
  • If the tintView is visible, you can't perform any action on the views beneath it. – Himanshu Joshi Mar 05 '14 at 13:09

1 Answers1

6

I think you can override -hitTest: in your tint view to return nil

BUT: It seems like bad practice to insert subviews into windows that you don't "own"... You might preferably create your own window for this.. Can I ask why you want to tint the keyboard?

EDIT:

I wrote some code that demonstrates this working:

https://gist.github.com/3139219

EDIT 2: Well this works for just a keyboard, but breaks for modal view controllers, so back to the drawing board.. sorry!

nielsbot
  • 15,922
  • 4
  • 48
  • 73
  • I want to tint it to change its appearance. It is actually tinted with a view containing a AVCaptureVideoPreviewLayer to show the camera, but I didn't mention that in order to simplify the question. Is there a way I could create my own UIWindow above the keyboard (and all other views-I'm actually tinting the whole screen)? I'm new to this so I wasn't sure how. – jadengeller Jul 18 '12 at 06:17
  • Overriding hitTest on the UIView does not fix the problem. It would be useful to know exactly what setting a view to hidden does besides not drawing it since setting it to hidden does fix the problem (but it isn't visible). – jadengeller Jul 18 '12 at 06:21
  • 1
    You can create a window--they work mostly like views: `[ [ UIWindow alloc ] initWithFrame: ]`, but I think it's discouraged.. but for your case maybe it is ok. (I've done it before for help popovers) – nielsbot Jul 18 '12 at 07:13
  • I found a way to do the same thing I was previously doing using UIWindows. Thanks for the tip. However, the message view still isn't receiving the touch input when this is visible, despite userinteractionenabled being set to NO. It seems what anything in front of a MFMessageComposeViewController blocks user interaction. Any tips? – jadengeller Jul 18 '12 at 07:15
  • sorry--I meant you should override `-[ CALayer hitTest: ]`, not `-[UIView hitTest:withEvent:]` (which means you need to override `+layerClass` in your tint view. You can also try overriding `-[CALayer containsPoint:]`... if those don't work, not sure... – nielsbot Jul 18 '12 at 07:15
  • in any case, you should stick with creating a UIWindow if this solution does work – nielsbot Jul 18 '12 at 07:17
  • 1
    one more idea--make sure your window isn't becoming the key window... (i.e. to show it use `setHidden:NO`, not `-makeKeyAndVisible` – nielsbot Jul 18 '12 at 07:19
  • Could you clarify the overriding? I am now just using a UIWindow with a AVCaptureVideoPreviewLayer (which is a CALayer) as a sublayer. What should I override? Edit: To clarify, the problem still persists even while using a UIWindow. – jadengeller Jul 18 '12 at 07:23
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/14042/discussion-between-nielsbot-and-jaden10) – nielsbot Jul 18 '12 at 07:27
  • Sorry to ask this again, but do you want to tint only the keyboard or the whole view? – Anindya Sengupta Mar 07 '14 at 15:31