开发者

Having trouble hiding keyboard using invisible button which sits on top of uiscrollview

I have 3 items in play...

1) UIView sits at the base of the hierarchy and contains the UIScrollview. 2) UIScrollview that is presenting a lengthy user form. 3) An invisible button on the UIScrollview that I'm using to provide "hide the keyboard" features.

Notice in the code below that I'm registering to be notified when the keyboard is going to appear and again when it's going to disappear. These are working great.

My problem is seemingly one of "layers". See below where I insert the button into the view atIndex:0. This causes the button to be activated and "stuffed" behind the scrollview so that when you click on it, the scrollview grabs the touch and the button is unaware. There is no way to "reach" the button and suppress the keyboard.

However, if I insert atIndex:1, the button gets super imposed on top of the text entry fields and so any touch at all is acted upon by the button, which immediately suppresses the keyboard and then disappears.

How do I insert the button on top of the UIScrollview but behind the UITextfields that sit there?


other logistics: I have a -(void) hidekeyboard function that I have setup with the UIButtion as an IBAction(). And I have the UIButton connected to "files owner" via a ctrl-drag/drop. (Do I need both of those conventions?)

This code in ViewDidLoad()...

[[开发者_运维知识库NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:nil usingBlock:^(NSNotification *notification){

[self.view insertSubview:self.keyboardDismissalButton atIndex:0];

}];


Here's a nifty way to do this without even needing the invisible button. This approach will only work on devices north of 3.2, but since we're already using the block methods on NSNotificationCenter, we know that we're at least at 4.0.

In lieu of a button, we instead add a tap gesture recognizer to our view. This tap gesture recognizer calls -dismissKeyboard: and then we ask our view to end all editing. This method is only available on 3.2 and later and works through it's subviews until it locates the current firstResponder and sends it -resignFirstResponder. The boolean argument that -endEditing: takes determines whether the resignation of firstResponder is forced or not. The documentation is a little vague, but I take it to mean that if forced, the -textFieldShouldEndEditing delegate method on UITextField will not be called.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:nil usingBlock:^(NSNotification *notification) {
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard:)];
        tap.numberOfTapsRequired = 1;
        tap.numberOfTouchesRequired = 1;
        [self.view addGestureRecognizer:tap];
    }];

    [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:nil usingBlock:^(NSNotification *notification) {
        [self.view removeGestureRecognizer:[self.view.gestureRecognizers lastObject]];
    }];
}

- (void)dismissKeyboard:(UIGestureRecognizer *)gesture
{
    [self.view endEditing:NO];
}


There is no way to have a view be in front of a sibling but behind the sibling's children. You can insert the button as a child of the scroll view (behind all the text fields), or you can override pointInside:withEvent: on the upper view to return false where it is over a text field and true otherwise (effectively "punching holes" in it).


Figured it out....

Here is the answer.

The code below is all within the ViewDidLoad() of the UIViewController. Begin by removing the button altogether from the UIView. (it will be rendered when the keyboard is activated).

Notice in the keyboard "WillShow" notification below that I am inserting the button onto my UIScrollView layer rather than the UIView layer, as before. However, once the button is clicked and the keyboard is about to be dismissed, I remove the button altogether from the UIView (i.e. self).

[self.keyboardDismissalButton removeFromSuperview];


[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:nil usingBlock:^(NSNotification *notification){

[theScroller insertSubview:self.keyboardDismissalButton atIndex:0];

}];



[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:nil usingBlock:^(NSNotification *notification){

        [self.keyboardDismissalButton removeFromSuperview];

}];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜