简体   繁体   English

使用位于uiscrollview顶部的隐形按钮隐藏键盘时遇到问题

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

I have 3 items in play... 我有3件物品在玩......

1) UIView sits at the base of the hierarchy and contains the UIScrollview. 1)UIView位于层次结构的基础并包含UIScrollview。 2) UIScrollview that is presenting a lengthy user form. 2)呈现冗长用户表单的UIScrollview。 3) An invisible button on the UIScrollview that I'm using to provide "hide the keyboard" features. 3)UIScrollview上的一个隐形按钮,我用它来提供“隐藏键盘”功能。

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. 请参阅下面我将按钮插入视图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. 但是,如果我插入atIndex:1,按钮会在文本输入字段的顶部被强加,因此按钮会对任何触摸起作用,这会立即抑制键盘然后消失。

How do I insert the button on top of the UIScrollview but behind the UITextfields that sit there? 如何在UIScrollview的顶部插入按钮,但是在位于那里的UITextfields后面?


other logistics: I have a -(void) hidekeyboard function that I have setup with the UIButtion as an IBAction(). 其他后勤:我有一个 - (void)hidekeyboard函数,我已将UIButtion设置为IBAction()。 And I have the UIButton connected to "files owner" via a ctrl-drag/drop. 我通过ctrl-drag / drop将UIButton连接到“文件所有者”。 (Do I need both of those conventions?) (我需要这两个约定吗?)

This code in ViewDidLoad()... 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. 这种方法只适用于3.2以北的设备,但由于我们已经在NSNotificationCenter上使用块方法,我们知道我们至少在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. 这个点击手势识别器调用-dismissKeyboard:然后我们要求我们的视图结束所有编辑。 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 . 此方法仅在3.2及更高版本中可用,并通过它的子视图工作,直到它找到当前的firstResponder并发送它-resignFirstResponder The boolean argument that -endEditing: takes determines whether the resignation of firstResponder is forced or not. -endEditing:的boolean参数确定是否强制firstResponder的重新签名。 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. 文档有点模糊,但我认为如果强制,则不会调用UITextField上的-textFieldShouldEndEditing委托方法。

- (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). 您可以将该按钮作为滚动视图的子项插入(在所有文本字段后面),或者您可以在上部视图上覆盖pointInside:withEvent:以在文本字段上方返回false,否则返回true(有效地“打孔” “ 在里面)。

Figured it out.... 弄清楚了....

Here is the answer. 这是答案。

The code below is all within the ViewDidLoad() of the UIViewController. 下面的代码都在UIViewController的ViewDidLoad()中。 Begin by removing the button altogether from the UIView. 首先从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. 请注意下面的键盘“WillShow”通知我将按钮插入到我的UIScrollView层而不是UIView层,就像之前一样。 However, once the button is clicked and the keyboard is about to be dismissed, I remove the button altogether from the UIView (ie self). 但是,一旦单击按钮并且键盘即将被解除,我将从UIView(即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];

}];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM