【问题标题】:Keyboard intermittently disappears when editing using IOS 8使用 IOS 8 编辑时键盘间歇性消失
【发布时间】:2014-09-25 21:31:16
【问题描述】:

我有几个案例,测试人员报告说,只要他们开始在我的应用程序的某些字段中输入,键盘就会消失。我使用模拟器跟踪了流程,并且在手机上进行调试时,问题从未发生过。但是,当我在不受限制的手机上尝试时,它发生的情况相当一致。

这里有一些相关的代码。所有这些都是为了在用户在文本字段之外点击时隐藏键盘。我的 UIViews 是我的 Touchview 类的子类,它接收所有的触摸:

TouchView.h:

@protocol TouchViewDelegate <NSObject>

-(UIView *) handleTouches:(NSSet *)touches withEvent:(UIEvent *)event inView:(UIView *) view;

@end

@interface TouchView : UIScrollView

@property (nonatomic, strong) id <TouchViewDelegate> touchDelegate;

@end

TouchView.m:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView * touchedView = [super hitTest:point withEvent:event];
    NSSet* touches = [event allTouches];
    [self.touchDelegate handleTouches:touches withEvent:event inView:touchedView];
    return touchedView;

}

我将主视图配置为 Touchview 并将其包含在 viewDidLoad 中:

- (void)viewDidLoad
{
[super viewDidLoad];

HMWTouchView * touchView = (HMWTouchView*) self.view;

touchView.touchDelegate = self;
...
}

这是委托方法的一个实现:

-(UIView *) handleTouches:(NSSet *)touches withEvent:(UIEvent *)event inView:(UIView *) hitView {

if (![hitView isKindOfClass:[UIButton class]]) {
    [[UIResponder firstResponder] resignFirstResponder];
}
return self.view;
}

这看起来至少是 IOS 8 响应点击的方式发生了变化。

【问题讨论】:

  • 我遇到了类似的问题:请参阅 tackoverflow.com/questions/26651384/prevent-or-detect-events-passed-on-from-ios-8-keyboard。特别是:只有在应用程序进入后台并再次被带到前台时才会发生。
  • 在我的测试中,您所要做的就是显示键盘、挂起/恢复,然后显示键盘。此时将在键盘后面的视图上进行 hitTest 调用。我最后的解决办法是添加 didShow 和 willHide 监听器并自己跟踪键盘状态。

标签: uitextfield ios8


【解决方案1】:

在 iOS 8.0.2 中已修复 不再需要。

【讨论】:

  • 这个问题在 8.1 中对我来说仍然存在
【解决方案2】:

问题在于 IOS 8.0(至少)改变了点击发送到视图的方式。以前,键盘窗口或文本字段中的点击被吸收,而不是传递到点击视图,这对这个应用程序很有效。 8.0 改变了这一点,所有的命中都通过了。

为了解决这个问题,我在命中测试代码中捕获了键盘窗口,并将 hitView 与文本字段视图进行比较以过滤掉它们:

Touchview.m 现在有以下内容。 keyboardView 方法改编自这个 Stack Overflow 答案:iOS: How to access the `UIKeyboard`?

-(UIView *) keyboardView {
//Return the current keyboard view
UIWindow * keyboardWindow;

UIView* keyboardView;

UIView* primaryKeyboardView;

for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
    if ([NSStringFromClass([window class]) isEqualToString:@"UITextEffectsWindow"])
    {
        keyboardWindow = window;
        break;
    }
}

for(int i = 0 ; i < [keyboardWindow.subviews count] ; i++)
{
    keyboardView = [keyboardWindow.subviews objectAtIndex:i];
    // keyboard found, add the button

    if([[keyboardView description] hasPrefix:@"<UIPeripheralHost"] == YES){
        primaryKeyboardView = keyboardView;
    }
    //This code will work on iOS 8.0
    else if([[keyboardView description] hasPrefix:@"<UIInputSetContainerView"] == YES){

        for(int i = 0 ; i < [keyboardView.subviews count] ; i++)
        {
            UIView* hostkeyboard = [keyboardView.subviews objectAtIndex:i];

            if([[hostkeyboard description] hasPrefix:@"<UIInputSetHost"] == YES){
                primaryKeyboardView = hostkeyboard;
            }
        }
    }
}
return primaryKeyboardView;
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView * touchedView = [super hitTest:point withEvent:event];
NSSet* touches = [event allTouches];
UIView * keyboardView = [self keyboardView];
if (touchedView != keyboardView) { //Ignore the hit if it's a keyboard
    [self.touchDelegate handleTouches:touches withEvent:event inView:touchedView];
}
return touchedView;
}

新的委托方法:

-(UIView *) handleTouches:(NSSet *)touches withEvent:(UIEvent *)event inView:(UIView *) hitView {

if (![hitView isKindOfClass:[UIResponder class]]) {
    [[UIResponder firstResponder] resignFirstResponder];
}
return hitView;
}

firstResponder 方法来自这个要点:https://gist.github.com/vilanovi/e52face5c6f00ce5254d

【讨论】:

  • hitTest 在我的键盘被点击时没有被触发?对于其余的视图,当我在键盘外触摸时它会被触发。有什么解决办法吗?
【解决方案3】:

这对我来说仍然发生在 8.02 中

【讨论】:

  • 我最终放弃了 hitTest。它总是产生不可靠的结果。有时他们代表每次点击会触发两次,有时会触发 3 次。有时发送者是一个已知的类,有时它是一个内部类,而且它通常与实际被点击的对象无关。 HitTest 似乎已损坏。我更改了我的实现以使用 guestureRecognizers,它工作正常。
【解决方案4】:

我观察到同样的问题 - 当用户尝试在键盘上键入时,键盘会被关闭。

我的解决方案是一种解决方法。为了解决这个问题,我在键盘下方创建了一个虚拟的空 UIView。这个虚拟视图吸收并消耗点击事件,并且键盘不会被关闭。我在“UIKeyboardDidShowNotification”上创建视图并在“UIKeyboardWillHideNotification”上删除它。这样可以解决问题,并且可以很好地适应屏幕方向的变化。

这是我的视图控制器中的代码,其中包含显示键盘的文本字段:

/** Dummy view placed underneath the keyboard to prevent its dismissal. */
@property(nonatomic, strong) UIView *dummyView;

viewDidLoad 方法中,我们注册键盘显示/隐藏通知:

// keyboard notifications - we need this to prevent keyboard dismissal
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillBeHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];

然后,在收到“显示键盘”通知后,我们在键盘下方创建虚拟视图:

- (void)keyboardWasShown:(NSNotification*)notification {
    // we need this to prevent keyboard dismissal    
    NSDictionary* info = [notification userInfo];
    CGRect keyboardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardFrame = [self.view convertRect:keyboardFrame fromView:nil];
    self.dummyView = [[UIView alloc] initWithFrame:keyboardFrame];
    [self.view addSubview:self.dummyView];
}

...并在键盘隐藏时将其删除:

- (void)keyboardWillBeHidden:(NSNotification*)notification {
    [self.dummyView removeFromSuperview];
    self.dummyView = nil;
}

【讨论】:

    猜你喜欢
    • 2014-10-13
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2014-11-12
    相关资源
    最近更新 更多