2

I have a screen with various elements, including a UITextField, and I want to show coach marks on the screen (I'm using the Instructions library). However, I need to freeze interactions with the elements when the coach marks are displayed (so the user can't type stuff in the text field, for example).

My problem is with the keyboard (which is always displayed in this screen): if I just set the text field's isEnabled property to false, or set isUserInteractionEnabled = false, the field resigns first responder and the keyboard disappears, which is unnatural for this screen. If, however, I use the textField:shouldChangeCharactersIn range: delegate method and return false, the keyboard remains visible, but enabled. So when the coach marks appear, the user can tap around the keyboard. While this has no effect on the text field, it's still weird and annoying.

So how do I temporarily keep the keyboard up, but have it disabled (preferably behind the coach marks blur view)? I saw this, but that doesn't provide a solution that I think Apple would accept.

Thanks,

Yariv.

Community
  • 1
  • 1
Yariv Adam
  • 844
  • 9
  • 24
  • 1
    Try textField.resignFirstResponder = true it will remove keyboard – jignesh Vadadoriya Mar 03 '17 at 07:15
  • Try self.view.endEditing(true) – RajeshKumar R Mar 03 '17 at 07:20
  • 1
    you just need to disable userInteraction of main window (AppDelegate's window object) while you are showing helping stuff and enable when you finish – Prashant Tukadiya Mar 03 '17 at 07:23
  • Jignesh - the whole point was NOT to hide the keyboard. Rajeshkumar: this also dismisses the keyboard, and has the added drawback that the text field loses focus and the user has to re-tap it when the coach marks are dismissed. Mike: this seemed like the best, cleanest answer. Unfortunately, however, this seems to also call resignFirstResponder, and also, even worst, renders the coach marks themselves unresponsive, and the user can't dismiss them. – Yariv Adam Mar 03 '17 at 08:13

2 Answers2

1

You can add a UIButton dynamically when the keyboard is visible. You can add keyboardDidShow & keyboardDidHide observer to know when the keyboard is up and visible.

You might face a problem related to keyboard being top most on screen but, you can deal with it by making the newly added UIButton the top most on your current view/window.

Don't forget to set userInteractionEnabled to false for that UIButton

Comment to your question by @MikeAlter would be the best (and clean) solution. But, that also means that you don't have any control with navigating/interacting to other controls on your screen.


EDIT

Keyboard has specific region on screen covered when shown. My solution suggested that you can add a UIButton on your view with the exact rectangle/frame same as of keyboard. A view/button that covers the keyboard overall. So, your keyboard will not take any user interaction.

The following code can get you size of keyboard. You can add a UIButton of same size in exactly same place which will make your keyboard inactive as user interaction will be taken care by the button itself.

- (void)keyboardDidShow:(NSNotification *)notification {
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    int height = MIN(keyboardSize.height,keyboardSize.width);
    int width = MAX(keyboardSize.height,keyboardSize.width);

    ... Add UIButton here with the CGRect of keyboard
}

You need to register to UIKeyboardDidShowNotification for above to work, like following:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardDidShow:)
                                             name:UIKeyboardDidShowNotification
                                           object:nil];
viral
  • 4,168
  • 5
  • 43
  • 68
  • I'm not sure I understand what you mean - do you mean to add a UIButton that will become first responder itself? How does this help me? I'll have the same problem with the keyboard disappearing when I call userInteractionEnabled = false, won't I? Can a UIButton become first responder (show the keyboard)? Maybe I didn't understand your solution, I'd appreciate it if you could be more specific. Thanks! – Yariv Adam Mar 03 '17 at 08:20
0

If you want to make keyboard behind coach marks blur view then add coach marks blur view to last window:

UIApplication.shared.windows.last?.addSubview(coachMarksBlurView)
UIApplication.shared.keyWindow?.bringSubview(toFront: coachMarksBlurView)

And if you want to block keyboard you can use these two functions:

func addBlockView(){
    view.addSubview(viewBlock)
    viewBlock.frame = CGRect.init(x: 0, y: 0, w: 
    UIScreen.main.bounds.size.width, h: 
    UIScreen.main.bounds.size.height)
    viewBlock.backgroundColor = UIColor.clear
    UIApplication.shared.windows.last?.addSubview(viewBlock)
    UIApplication.shared.keyWindow?.bringSubview(toFront: viewBlock)
}

func removeBlockView(){
    viewBlock.removeFromSuperview()
}
Arnav
  • 668
  • 6
  • 14