显示 window 级别的视图 UIWindowLevelStatusBar 退出当前的第一响应者

Showing view with window level UIWindowLevelStatusBar resign the current first responder

我在尝试在应用程序中显示应用内横幅(在状态栏上方)时遇到问题。问题是,当我在文本字段中输入文本时,如果横幅出现,它会移除键盘,然后一旦横幅消失(它在计时器上),键盘就会再次出现。有没有办法在状态栏上方有一个横幅视图,同时如果键盘是第一响应者,键盘不会消失。

InAppNotificationView* _sharedPushView = nil;
NSArray              * nibArr          = [[NSBundle mainBundle] loadNibNamed: @"InAppNotificationView" owner: self options: nil];
for (id currentObject in nibArr)
{
    if ([currentObject isKindOfClass: [InAppNotificationView class]])
    {
        _sharedPushView = (InAppNotificationView*) currentObject;
        break;
    }
}
_sharedPushView.delegate = self;

[self.displayedPushViews addObject: _sharedPushView];
                   _topView.window.windowLevel = UIWindowLevelStatusBar;
                   [UIView animateWithDuration: 0.25
                                    animations: ^
                                    {
                                        CGPoint centerPoint  = _sharedPushView.center;
                                        centerPoint.y       += _sharedPushView.frame.size.height;
                                        _sharedPushView.center      = centerPoint;
                                    }
                                    completion: nil];

                   [self.closeTimer invalidate];
                   self.closeTimer = nil;
                   self.closeTimer = [NSTimer scheduledTimerWithTimeInterval: 3.0f
                                                                      target: self
                                                                    selector: @selector(close)
                                                                    userInfo: nil
                                                                     repeats: NO];

我找到了解决办法。创建自定义 UIWindow 并将 UIView 作为子视图添加到其中。这为我解决了问题。还有一件事是您必须重写 'hitTest:withEvent' 方法,因为默认情况下所有触摸都会转到 window。因此,对于自定义 window 不应该处理的点击,它必须进一步委托它。

我创建了一个自定义 UIWindow class :

@interface InAppNotificationWindow : UIWindow
@property (assign, nonatomic) CGFloat notificationHeight;
@end
@implementation InAppNotificationWindow

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
      if (point.y > 0 && point.y < self.notificationHeight)
      {
          return [super hitTest: point withEvent: event];
      }
     return nil;
}
@end

在我的控制器文件中

- (InAppNotificationWindow* ) notificationWindow
{
     if (_notificationWindow == nil)
     {
            _notificationWindow = [[InAppNotificationWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
            _notificationWindow.backgroundColor        = [UIColor clearColor];
           _notificationWindow.userInteractionEnabled = YES;
           _notificationWindow.hidden                 = NO;
          _notificationWindow.autoresizingMask       = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            _notificationWindow.windowLevel            = UIWindowLevelStatusBar;
     }

return _notificationWindow;

}

然后将自定义视图作为子视图添加到自定义window。

 [self.notificationWindow addSubview: _topView];