有没有办法防止键盘被解雇?

Posted

技术标签:

【中文标题】有没有办法防止键盘被解雇?【英文标题】:Is there a way to prevent the keyboard from dismissing? 【发布时间】:2011-05-15 01:57:37 【问题描述】:

我知道这与大多数帖子相反,但我希望键盘保持向上即使按下“键盘向下”按钮

具体来说,我有两个UITextFields 的视图。使用以下委托方法

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
    return NO;

即使用户按下键盘上的Done 按钮或点击屏幕上的任何其他位置(除了键盘右下角那个讨厌的键盘向下按钮),我也能够保持键盘向上。

我像模态视图一样使用这个视图(尽管该视图与被推送到 UINavigationController 中的 ViewController 相关联),所以从用户的角度来看,它确实最适合让键盘始终保持打开状态。如果有人知道如何实现这一点,请告诉我!谢谢!

更新仍然没有解决方案!当Done被按下时,它会触发textFieldShouldReturn,但是当Dismiss按钮被按下时,它会触发textFieldDidEndEditing。我无法阻止 textField 结束编辑,否则它永远不会消失。不知何故,我真的很想有一种方法可以检测到Dismiss 按钮并忽略它。如果你知道方法,请赐教!

【问题讨论】:

这是您设计的 UI 交互不符合 Apple 官方指南的情况之一。我认为你应该花时间重新思考应用程序,而不是“打破”基本 ios SDK 的规则。 哪条指南建议在屏幕上保留带有文本字段的键盘是糟糕的 UI? UI 交互很差,无法让用户移除键盘,就像在所有 iOS 应用程序中一样。如果您查看 iOS 应用程序的默认外观和感觉,您正在尝试做一些“奇怪”的事情。我不记得有一个(有效)应用程序不能让我卸下键盘。这就是我要你思考的问题。 我尊重您对此事的看法,但不同意。我相信关闭键盘只会出错,在这种特殊情况下,用户可能会不知如何与屏幕交互。在这种情况下,我认为键盘类似于选择器,但我很欣赏你的观点。 我应该补充一点,我的评估基于测试用户的反馈,我相信这胜过假设场景。 【参考方案1】:

有办法做到这一点。 因为UIKeyboardUIWindow 的子类,所以唯一一个大到足以进入UIKeyboard 的方式是另一个UIWindow.

- (void)viewDidLoad 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(coverKey) name:UIKeyboardDidShowNotification object:nil];
    [super viewDidLoad];


- (void)coverKey 
    CGRect r = [[UIScreen mainScreen] bounds];
    UIWindow *myWindow = [[UIWindow alloc] initWithFrame:CGRectMake(r.size.width - 50 , r.size.height - 50, 50, 50)];
    [myWindow setBackgroundColor:[UIColor clearColor]];
    [super.view addSubview:myWindow];
    [myWindow makeKeyAndVisible];

这适用于 iPhone 应用程序。 iPad 没试过。您可能需要调整myWindow 的大小。另外,我没有对myWindow 进行任何内存管理。所以,也考虑这样做。

【讨论】:

我应该补充一点,我假设了一个实例字段方法,其中 previousTextField 和 someTextField 是实例字段。因此,keyboardWillHide 方法不需要参数。 即使这涵盖了“隐藏键盘”按钮,您仍然应该使用 UITextField 委托方法处理第一响应者逻辑,以便适当的 UITextField 接收来自 UIKeyboard 的输入。 我对这个想法的问题是它取决于键盘的特定布局/语言。总的来说,我并不反对 hack,但必须针对每个键盘以及不同的方向定制这个。 您可能只需要创建一个实用程序类,它会根据方向更改、UITextField 之间的焦点更改等触发类方法。类方法将负责添加/删除/修改所需的 UIWindows覆盖键盘的特定区域。这很骇人听闻,但它可能是唯一的方法。 由于赏金即将到期,我在忘记之前奖励它。这个解决方案并非没有问题,我仍然希望有一个更好的解决方案(因此我不接受这个答案),但在建议的答案中,这是唯一能达到预期结果的解决方案。它绝对值得我赏金。谢谢 JacobB。【参考方案2】:

我想我找到了一个很好的解决方案。

添加一个 BOOL 作为实例变量,我们称之为shouldBeginCalledBeforeHand

然后实现以下方法:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

    shouldBeginCalledBeforeHand = YES;
    return YES;


- (BOOL)textFieldShouldEndEditing:(UITextField *)textField

    return shouldBeginCalledBeforeHand;


- (void)textFieldDidBeginEditing:(UITextField *)textField

    shouldBeginCalledBeforeHand = NO;

还有

- (BOOL)textFieldShouldReturn:(UITextField *)textField

    return NO;

防止键盘随着返回按钮消失。诀窍是,从一个文本字段到另一个文本字段的焦点切换将预先触发 textFieldShouldBeginEditing。如果按下关闭键盘按钮,则不会发生这种情况。在文本字段获得焦点后重置标志。

【讨论】:

@PengOne 找到了另一个解决方案。 这仅适用于模态视图,但它可以防止键盘完全消失,即使视图消失了:-( 你想把这个分成两个答案吗?我更喜欢旧的解决方案,因为虽然不完美,但它不会破坏其他任何东西。由于解决方案如此不同,我认为将它们分开是有意义的。 @PengOne 划分了答案,你能添加一些代码来告诉我你是如何关闭模态视图的吗?我认为键盘不消失的问题可以解决。 谢谢!这有助于我在使用页面视图控制器时防止键盘消失。【参考方案3】:

旧的不完美的解决方案

我只能想到一个不完美的解决方案。收听通知UIKeyboardDidHideNotification 并再次使文本字段成为第一响应者。这会将键盘移出视线并再次移回。您可以通过监听 UIKeyboardWillHideNotification 来记录哪个文本字段是最后一个 firstResponder,并将焦点放在 didHide 中。

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(keyboardDidHide:) 
                                             name:UIKeyboardDidHideNotification
                                           object:nil];

...

- (void)keyboardDidHide:(id)sender

    [myTextField becomeFirstResponder];

【讨论】:

+1,因为它是一个接近解决方案。键盘下降然后备份的事实使这一点变得不那么好。我真的希望有一个 -(BOOL)keyboardWillHide 方法,我可以从中返回 NO 有一个 UIKeyboardWillHideNotification,见UIWindow doc,使用它应该让你设置另一个文本字段作为第一响应者,这应该取消键盘隐藏/显示动画(但我不是一定)。 @progrmr 试过了,没用。也许您对此有解决方案?【参考方案4】:

对于 iOS 9/10 和 Swift 3,使用它来创建一个与“隐藏键盘”重叠的矩形 - 按钮

override func viewDidLoad() 
    NotificationCenter.default.addObserver(self, selector: #selector(coverKey), name: .UIKeyboardDidShow, object: nil)


func coverKey() 
    if let keyboardWindow = UIApplication.shared.windows.last 
        let r = UIScreen.main.bounds
        let myWindow = UIWindow.init(frame: CGRect(x: r.size.width - 50 , y: r.size.height - 50, width: 50, height: 50))
        myWindow.backgroundColor = UIColor.clear
        myWindow.isHidden = false
        keyboardWindow.addSubview(myWindow)
        keyboardWindow.bringSubview(toFront: myWindow)
    
 

请注意,这会将子视图添加到键盘窗口而不是主窗口

【讨论】:

运行良好,需要在键盘隐藏时移除此视图? 添加到键盘窗口后,如果隐藏键盘应该会自动移除。【参考方案5】:

尝试在键盘关闭按钮的顶部添加一个自定义项,这样用户将无法点击关闭按钮。我在我的一个应用程序中使用了这种方法。

- (void)addButtonToKeyboard 

    // create custom button
    UIButton *blockButton = [UIButton buttonWithType:UIButtonTypeCustom];
    blockButton.frame = //set the frame here, I don't remember the exact frame
    [blockButton setImage:[UIImage imageNamed:@"block_button.png"] forState:UIControlStateNormal];

    // locate keyboard view
    UIWindow *appWindows = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
    UIView *keyboard;
    for (int i=0; i<[appWindows.subviews count]; i++) 
        keyboard = [appWindows.subviews objectAtIndex:i];
        // keyboard found, add the button
        if ([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES && [self.textField isFirstResponder]) 
            [keyboard addSubview:doneButton];

        
    


【讨论】:

这是 JabocB 的解决方案。一个 hack,而且是特定于键盘的。【参考方案6】:

试试这个...

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
   return NO;

您可以使用 Nick Weaver 提到的通知。

【讨论】:

如多处提到的,有多个文本字段,因此实现这一点将不允许用户在文本字段之间移动。

以上是关于有没有办法防止键盘被解雇?的主要内容,如果未能解决你的问题,请参考以下文章

底部对话框打开时如何防止键盘关闭?

Swift 防止 TabBar 在键盘处于活动状态时向上移动

如何防止通过推送 SFSafariViewController 解雇 UITabBarController?

有没有办法防止查询字符串被篡改或查询字符串丢失?

防止在presentViewController上隐藏键盘(显示弹出窗口)

有没有办法防止使用依赖项提供的特定功能?