为什么 UINavigationBar 会窃取触摸事件?

发布于 2025-01-01 17:56:29 字数 616 浏览 1 评论 0原文

我有一个自定义 UIButton,其中 UILabel 添加为子视图。仅当我触摸顶部边界下方约 15 个点时,按钮才会执行给定的选择器。当我点击该区域上方时,什么也没有发生。

我发现这并不是由错误创建按钮和标签引起的,因为在我将按钮向下移动约 15 px 后,它可以正常工作。

更新 我忘了说位于 UINavigationBar 下方的按钮和按钮上部的 1/3 不会收到触摸事件。

图片位于此处

带有 4 个按钮的视图是位于导航栏下方。当触摸顶部的“篮球”时,后退按钮获得触摸事件,当触摸顶部的“钢琴”时,右栏按钮(如果存在)获得触摸。如果不存在,则什么也没有发生。

我在应用程序文档中没有找到此记录功能。

我还发现这个主题与我的相关问题,但也没有答案。

I have a custom UIButton with UILabel added as subview. Button perform given selector only when I touch it about 15points lower of top bound. And when I tap above that area nothing happens.

I found out that it hasn't caused by wrong creation of button and label, because after I shift the button lower at about 15 px it works correctly.

UPDATE I forgot to say that button located under the UINavigationBar and 1/3 of upper part of the button don't get touch events.

Image was here

View with 4 buttons is located under the NavigationBar. And when touch the "Basketball" in top, BackButton get touch event, and when touch "Piano" in top, then rightBarButton (if exists) get touch. If not exists, nothing happened.

I didn't find this documented feature in App docs.

Also I found this topic related to my problem, but there is no answer too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

謌踐踏愛綪 2025-01-08 17:56:29

我注意到,如果您将 userInteractionEnabled 设置为 OFF,导航栏将不再“窃取”触摸。

因此,您必须对 UINavigationBar 进行子类化,并在 CustomNavigationBar 中执行以下操作:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    if ([self pointInside:point withEvent:event]) {
        self.userInteractionEnabled = YES;
    } else {
        self.userInteractionEnabled = NO;
    }

    return [super hitTest:point withEvent:event];
}

有关如何对 UINavigationBar 进行子类化的信息,您可以找到 此处

I noticed that if you set userInteractionEnabled to OFF, the NavigationBar doesn't "steal" the touches anymore.

So you have to subclass your UINavigationBar and in your CustomNavigationBar do this:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    if ([self pointInside:point withEvent:event]) {
        self.userInteractionEnabled = YES;
    } else {
        self.userInteractionEnabled = NO;
    }

    return [super hitTest:point withEvent:event];
}

Info about how to subclass UINavigationBar you can find here.

黑寡妇 2025-01-08 17:56:29

我在这里(Apple开发者论坛)找到了答案。

Keith 在 Apple 开发者技术支持上,2010 年 5 月 18 日(iPhone OS 3):

我建议您避免在导航栏或工具栏附近使用触摸敏感 UI。这些区域通常被称为“倾斜因子”,使用户可以更轻松地在按钮上执行触摸事件,而无需执行精确触摸。例如,UIButton 也是如此。

但是如果你想在导航栏或工具栏接收到触摸事件之前捕获它,你可以子类化 UIWindow 并重写:
-(void)sendEvent:(UIEvent *)事件;

我还发现,当我触摸 UINavigationBar 下方的区域时,location.y 定义为 64,尽管事实并非如此。
所以我做了这个:

CustomWindow.h

@interface CustomWindow: UIWindow 
@end

CustomWindow.m

@implementation CustomWindow
- (void) sendEvent:(UIEvent *)event
{       
  BOOL flag = YES;
  switch ([event type])
  {
   case UIEventTypeTouches:
        //[self catchUIEventTypeTouches: event]; perform if you need to do something with event         
        for (UITouch *touch in [event allTouches]) {
          if ([touch phase] == UITouchPhaseBegan) {
            for (int i=0; i<[self.subviews count]; i++) {
                //GET THE FINGER LOCATION ON THE SCREEN
                CGPoint location = [touch locationInView:[self.subviews objectAtIndex:i]];

                //REPORT THE TOUCH
                NSLog(@"[%@] touchesBegan (%i,%i)",  [[self.subviews objectAtIndex:i] class],(NSInteger) location.x, (NSInteger) location.y);
                if (((NSInteger)location.y) == 64) {
                    flag = NO;
                }
             }
           }  
        }

        break;      

   default:
        break;
  }
  if(!flag) return; //to do nothing

    /*IMPORTANT*/[super sendEvent:(UIEvent *)event];/*IMPORTANT*/
}

@end

在 AppDelegate 类中,我使用 CustomWindow 而不是 UIWindow。

现在,当我触摸导航栏下方的区域时,没有任何反应。

我的按钮仍然没有收到触摸事件,因为我不知道如何使用按钮将此事件(并更改坐标)发送到我的视图。

I found out the answer here(Apple Developer Forum).

Keith at Apple Developer Technical Support, on 18th May 2010 (iPhone OS 3):

I recommend that you avoid having touch-sensitive UI in such close proximity to the nav bar or toolbar. These areas are typically known as "slop factors" making it easier for users to perform touch events on buttons without the difficulty of performing precision touches. This is also the case for UIButtons for example.

But if you want to capture the touch event before the navigation bar or toolbar receives it, you can subclass UIWindow and override:
-(void)sendEvent:(UIEvent *)event;

Also I found out,that when I touch the area under the UINavigationBar, the location.y defined as 64,though it was not.
So I made this:

CustomWindow.h

@interface CustomWindow: UIWindow 
@end

CustomWindow.m

@implementation CustomWindow
- (void) sendEvent:(UIEvent *)event
{       
  BOOL flag = YES;
  switch ([event type])
  {
   case UIEventTypeTouches:
        //[self catchUIEventTypeTouches: event]; perform if you need to do something with event         
        for (UITouch *touch in [event allTouches]) {
          if ([touch phase] == UITouchPhaseBegan) {
            for (int i=0; i<[self.subviews count]; i++) {
                //GET THE FINGER LOCATION ON THE SCREEN
                CGPoint location = [touch locationInView:[self.subviews objectAtIndex:i]];

                //REPORT THE TOUCH
                NSLog(@"[%@] touchesBegan (%i,%i)",  [[self.subviews objectAtIndex:i] class],(NSInteger) location.x, (NSInteger) location.y);
                if (((NSInteger)location.y) == 64) {
                    flag = NO;
                }
             }
           }  
        }

        break;      

   default:
        break;
  }
  if(!flag) return; //to do nothing

    /*IMPORTANT*/[super sendEvent:(UIEvent *)event];/*IMPORTANT*/
}

@end

In AppDelegate class I use CustomWindow instead of UIWindow.

Now when I touch area under navigation bar, nothing happens.

My buttons still don't get touch events,because I don't know how to send this event (and change coordinates) to my view with buttons.

糖果控 2025-01-08 17:56:29

子类 UINavigationBar 并添加此方法。除非点击子视图(例如按钮),否则它将导致点击被传递。

 -(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event
 {
    UIView *v = [super hitTest:point withEvent:event];
    return v == self? nil: v;
 }

Subclass UINavigationBar and add this method. It will cause taps to be passed through unless they are tapping a subview (such as a button).

 -(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event
 {
    UIView *v = [super hitTest:point withEvent:event];
    return v == self? nil: v;
 }
梦途 2025-01-08 17:56:29

我的解决方案如下:

第一:
在您的应用程序中添加 UINavigationBar 的扩展(无论您在何处输入此代码),如下所示:
以下代码仅在点击 navigationBar 时调度带有点和事件的通知。

extension UINavigationBar {
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil, userInfo: ["point": point, "event": event as Any])
    return super.hitTest(point, with: event)
    }
}

然后,在您的特定视图控制器中,您必须通过在 viewDidLoad 中添加以下行来监听此通知:

NotificationCenter.default.addObserver(self, selector: #selector(tapNavigationBar), name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil)

然后您需要在视图控制器中创建方法 tapNavigationBar,如下所示:

func tapNavigationBar(notification: Notification) {
    let pointOpt = notification.userInfo?["point"] as? CGPoint
    let eventOpt = notification.userInfo?["event"] as? UIEvent?
    guard let point = pointOpt, let event = eventOpt else { return }

    let convertedPoint = YOUR_VIEW_BEHIND_THE_NAVBAR.convert(point, from: self.navigationController?.navigationBar)
    if YOUR_VIEW_BEHIND_THE_NAVBAR.point(inside: convertedPoint, with: event) {
        //Dispatch whatever you wanted at the first place.
    }
}

PD :不要忘记删除 deinit 中的观察,如下所示:

deinit {
    NotificationCenter.default.removeObserver(self)
}

就是这样...这有点“棘手”,但这是一个很好的解决方法,可以避免子类化并在 navigationBar 中随时获取通知正在被窃听。

The solution for me was the following one:

First:
Add in your application (It doesn't matter where you enter this code) an extension for UINavigationBar like so:
The following code just dispatch a notification with the point and event when the navigationBar is being tapped.

extension UINavigationBar {
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil, userInfo: ["point": point, "event": event as Any])
    return super.hitTest(point, with: event)
    }
}

Then in your specific view controller you must listen to this notification by adding this line in your viewDidLoad:

NotificationCenter.default.addObserver(self, selector: #selector(tapNavigationBar), name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil)

Then you need to create the method tapNavigationBar in your view controller as so:

func tapNavigationBar(notification: Notification) {
    let pointOpt = notification.userInfo?["point"] as? CGPoint
    let eventOpt = notification.userInfo?["event"] as? UIEvent?
    guard let point = pointOpt, let event = eventOpt else { return }

    let convertedPoint = YOUR_VIEW_BEHIND_THE_NAVBAR.convert(point, from: self.navigationController?.navigationBar)
    if YOUR_VIEW_BEHIND_THE_NAVBAR.point(inside: convertedPoint, with: event) {
        //Dispatch whatever you wanted at the first place.
    }
}

PD: Don't forget to remove the observation in the deinit like so:

deinit {
    NotificationCenter.default.removeObserver(self)
}

That's it... That's a little bit 'tricky', but it's a good workaround for not subclassing and getting a notification anytime the navigationBar is being tapped.

各自安好 2025-01-08 17:56:29

我只是想分享解决这个问题的另一个前景。这不是设计上的问题,而是为了帮助用户返回或导航。但我们需要将内容紧紧地放在导航栏内或下方,而事情看起来很糟糕。

首先我们看一下代码。

class MyNavigationBar: UINavigationBar {
private var secondTap = false
private var firstTapPoint = CGPointZero

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    if !self.secondTap{
        self.firstTapPoint = point
    }

    defer{
        self.secondTap = !self.secondTap
    }

    return  super.pointInside(firstTapPoint, withEvent: event)
}

可能会明白为什么我要进行第二次触摸处理。有解决方案的秘诀。

一次调用会调用两次命中测试。第一次报告窗口上的实际点。一切顺利。在第二遍时,就会发生这种情况。

如果系统看到导航栏并且 Y 侧的点击点大约多出 9 像素,它会尝试将其逐渐减少到导航栏所在的 44 点以下。

看一下屏幕就清楚了。

输入图片这里的描述

因此,有一种机制将使用附近的逻辑来进行命中测试的第二遍。如果我们可以知道它的第二遍,然后用第一个命中测试点调用超级。工作完成了。

上面的代码正是这样做的。

I just wanted to share another prospective to solving this problem. This is not a problem by design, but it was meant to help user get back or navigate. But we need to put things tightly in or below nav bar and things look sad.

First lets look at the code.

class MyNavigationBar: UINavigationBar {
private var secondTap = false
private var firstTapPoint = CGPointZero

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    if !self.secondTap{
        self.firstTapPoint = point
    }

    defer{
        self.secondTap = !self.secondTap
    }

    return  super.pointInside(firstTapPoint, withEvent: event)
}

}

You might be see why am i doing second touch handling. There is the recipe to the solution.

Hit test is called twice for a call. The first time the actual point on the window is reported. Everything goes well. On the second pass, this happens.

If system sees a nav bar and the hit point is around 9 pixels more on Y side, it tries to decrease that gradually to below 44 points which is where the nav bar is.

Take a look at the screen to be clear.

enter image description here

So theres a mechanism that will use nearby logic to the second pass of hittest. If we can know its second pass and then call the super with first hit test point. Job done.

The above code does that exactly.

天生の放荡 2025-01-08 17:56:29

有两件事可能会导致问题。

  1. 您是否尝试过 setUserInteractionEnabled:NO 标签。

  2. 我认为可能有效的第二件事是在按钮顶部添加标签后,您可以将标签发送到后面(它可能有效,但不确定)

    [button sendSubviewToBack:label];

请让我知道代码是否有效:)

There are 2 things that might be causing problems.

  1. Did you try setUserInteractionEnabled:NO for the label.

  2. Second thing i think might work is apart from that after adding label on top of button you can send the label to back (it might work, not sure although)

    [button sendSubviewToBack:label];

Please let me know if the code works :)

踏雪无痕 2025-01-08 17:56:29

你的标签很大。它们从 {0,0}(按钮的左上角)开始,延伸到按钮的整个宽度,并具有整个视图的高度。检查您的数据并重试。

此外,您还可以选择使用 UIButton 属性 titleLabel。也许您稍后设置标题,并将其放入此标签而不是您自己的 UILabel 中。这可以解释为什么文本(属于按钮)会起作用,而标签会覆盖按钮的其余部分(不让点击通过)。

titleLabel 是一个只读属性,但您可以将其自定义为您自己的标签(frame 除外),包括文本颜色、字体、阴影等。

Your labels are huge. They start at {0,0} (the left top corner of the button), extend over the entire width of the button and have a height of the entire view. Check your frame data and try again.

Also, you have the option of using the UIButton property titleLabel. Maybe you are setting the title later and it goes into this label rather than your own UILabel. That would explain why the text (belonging to the button) would work, while the label would be covering the rest of the button (not letting the taps go through).

titleLabel is a read-only property, but you can customize it just as your own label (except perhaps the frame) including text color, font, shadow, etc.

裂开嘴轻声笑有多痛 2025-01-08 17:56:29

这解决了我的问题..

我添加了 hitTest:withEvent :代码到我的导航栏子类..

 -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        int errorMargin = 5;// space left to decrease the click event area
        CGRect smallerFrame = CGRectMake(0 , 0 - errorMargin, self.frame.size.width, self.frame.size.height);
        BOOL isTouchAllowed =  (CGRectContainsPoint(smallerFrame, point) == 1);

        if (isTouchAllowed) {
            self.userInteractionEnabled = YES;
        } else {
            self.userInteractionEnabled = NO;
        }
        return [super hitTest:point withEvent:event];
    }

This solved my problem..

I added hitTest:withEvent: code to my navbar subclass..

 -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        int errorMargin = 5;// space left to decrease the click event area
        CGRect smallerFrame = CGRectMake(0 , 0 - errorMargin, self.frame.size.width, self.frame.size.height);
        BOOL isTouchAllowed =  (CGRectContainsPoint(smallerFrame, point) == 1);

        if (isTouchAllowed) {
            self.userInteractionEnabled = YES;
        } else {
            self.userInteractionEnabled = NO;
        }
        return [super hitTest:point withEvent:event];
    }
愁以何悠 2025-01-08 17:56:29

扩展 Alexander 的解决方案:

步骤 1. 子类 UIWindow

@interface ChunyuWindow : UIWindow {
    NSMutableArray * _views;

@private
    UIView *_touchView;
}

- (void)addViewForTouchPriority:(UIView*)view;
- (void)removeViewForTouchPriority:(UIView*)view;

@end
// .m File
// #import "ChunyuWindow.h"

@implementation ChunyuWindow
- (void) dealloc {
    TT_RELEASE_SAFELY(_views);
    [super dealloc];
}


- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if (UIEventSubtypeMotionShake == motion
        && [TTNavigator navigator].supportsShakeToReload) {
        // If you're going to use a custom navigator implementation, you need to ensure that you
        // implement the reload method. If you're inheriting from TTNavigator, then you're fine.
        TTDASSERT([[TTNavigator navigator] respondsToSelector:@selector(reload)]);
        [(TTNavigator*)[TTNavigator navigator] reload];
    }
}

- (void)addViewForTouchPriority:(UIView*)view {
    if ( !_views ) {
        _views = [[NSMutableArray alloc] init];
    }
    if (![_views containsObject: view]) {
        [_views addObject:view];
    }
}

- (void)removeViewForTouchPriority:(UIView*)view {
    if ( !_views ) {
        return;
    }

    if ([_views containsObject: view]) {
        [_views removeObject:view];
    }
}

- (void)sendEvent:(UIEvent *)event {
    if ( !_views || _views.count == 0 ) {
        [super sendEvent:event];
        return;
    }

    UITouch *touch = [[event allTouches] anyObject];
    switch (touch.phase) {
        case UITouchPhaseBegan: {
            for ( UIView *view in _views ) {
                if ( CGRectContainsPoint(view.frame, [touch locationInView:[view superview]]) ) {
                    _touchView = view;
                    [_touchView touchesBegan:[event allTouches] withEvent:event];
                    return;
                }
            }
            break;
        }
        case UITouchPhaseMoved: {
            if ( _touchView ) {
                [_touchView touchesMoved:[event allTouches] withEvent:event];
                return;
            }
            break;
        }
        case UITouchPhaseCancelled: {
            if ( _touchView ) {
                [_touchView touchesCancelled:[event allTouches] withEvent:event];
                _touchView = nil;
                return;
            }
            break;
        }
        case UITouchPhaseEnded: {
            if ( _touchView ) {
                [_touchView touchesEnded:[event allTouches] withEvent:event];
                _touchView = nil;
                return;
            }
            break;
        }

        default: {
            break;
        }
    }

    [super sendEvent:event];
}

@end

步骤 2:将 ChunyuWindow 实例分配给 AppDelegate 实例

步骤 3:实现 touchesEnded:widthEvent:对于带有按钮的view,例如:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded: touches withEvent: event];

    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView: _buttonsView]; // a subview contains buttons
    for (UIButton* button in _buttons) {
        if (CGRectContainsPoint(button.frame, point)) {
            [self onTabButtonClicked: button];
            break;
        }
    }    
}

第四步:当我们的view我们调用ChunyuWindowaddViewForTouchPriority关心出现,视图消失或dealloc时调用removeViewForTouchPriority,在ViewControllers的viewDidAppear/viewDidDisappear/dealloc中,所以ChunyuWindow中的_touchView为NULL,和UIWindow,没有副作用。

Extending Alexander's solution:

Step 1. Subclass UIWindow

@interface ChunyuWindow : UIWindow {
    NSMutableArray * _views;

@private
    UIView *_touchView;
}

- (void)addViewForTouchPriority:(UIView*)view;
- (void)removeViewForTouchPriority:(UIView*)view;

@end
// .m File
// #import "ChunyuWindow.h"

@implementation ChunyuWindow
- (void) dealloc {
    TT_RELEASE_SAFELY(_views);
    [super dealloc];
}


- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if (UIEventSubtypeMotionShake == motion
        && [TTNavigator navigator].supportsShakeToReload) {
        // If you're going to use a custom navigator implementation, you need to ensure that you
        // implement the reload method. If you're inheriting from TTNavigator, then you're fine.
        TTDASSERT([[TTNavigator navigator] respondsToSelector:@selector(reload)]);
        [(TTNavigator*)[TTNavigator navigator] reload];
    }
}

- (void)addViewForTouchPriority:(UIView*)view {
    if ( !_views ) {
        _views = [[NSMutableArray alloc] init];
    }
    if (![_views containsObject: view]) {
        [_views addObject:view];
    }
}

- (void)removeViewForTouchPriority:(UIView*)view {
    if ( !_views ) {
        return;
    }

    if ([_views containsObject: view]) {
        [_views removeObject:view];
    }
}

- (void)sendEvent:(UIEvent *)event {
    if ( !_views || _views.count == 0 ) {
        [super sendEvent:event];
        return;
    }

    UITouch *touch = [[event allTouches] anyObject];
    switch (touch.phase) {
        case UITouchPhaseBegan: {
            for ( UIView *view in _views ) {
                if ( CGRectContainsPoint(view.frame, [touch locationInView:[view superview]]) ) {
                    _touchView = view;
                    [_touchView touchesBegan:[event allTouches] withEvent:event];
                    return;
                }
            }
            break;
        }
        case UITouchPhaseMoved: {
            if ( _touchView ) {
                [_touchView touchesMoved:[event allTouches] withEvent:event];
                return;
            }
            break;
        }
        case UITouchPhaseCancelled: {
            if ( _touchView ) {
                [_touchView touchesCancelled:[event allTouches] withEvent:event];
                _touchView = nil;
                return;
            }
            break;
        }
        case UITouchPhaseEnded: {
            if ( _touchView ) {
                [_touchView touchesEnded:[event allTouches] withEvent:event];
                _touchView = nil;
                return;
            }
            break;
        }

        default: {
            break;
        }
    }

    [super sendEvent:event];
}

@end

Step 2: Assign ChunyuWindow instance to AppDelegate Instance

Step 3: Implement touchesEnded:widthEvent: for view with buttons, for example:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded: touches withEvent: event];

    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView: _buttonsView]; // a subview contains buttons
    for (UIButton* button in _buttons) {
        if (CGRectContainsPoint(button.frame, point)) {
            [self onTabButtonClicked: button];
            break;
        }
    }    
}

Step 4: call ChunyuWindow's addViewForTouchPriority when the view we care about appears, and call removeViewForTouchPriority when the view disappears or dealloc, in viewDidAppear/viewDidDisappear/dealloc of ViewControllers, so _touchView in ChunyuWindow is NULL, and it is the same as UIWindow, having no side effects.

浅笑轻吟梦一曲 2025-01-08 17:56:29

根据 Alexander 提供的答案,对我有用的替代解决方案:

self.navigationController?.barHideOnTapGestureRecognizer.enabled = false

您可以禁用负责 UINavigationBar< 上“倾斜区域”的手势识别器,而不是覆盖 UIWindow /代码>。

An alternative solution that worked for me, based on the answer provided by Alexandar:

self.navigationController?.barHideOnTapGestureRecognizer.enabled = false

Instead of overriding the UIWindow, you can just disable the gesture recogniser responsible for the "slop area" on the UINavigationBar.

本宫微胖 2025-01-08 17:56:29

根据巴特·怀特利(Bart Whiteley)的说法,给出一个扩展版本。不需要子类化。

@implementation UINavigationBar(Xxxxxx)

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *v = [super hitTest:point withEvent:event];
    return v == self ? nil: v;
}

@end

Give a extension version according to Bart Whiteley. No need to subclass.

@implementation UINavigationBar(Xxxxxx)

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *v = [super hitTest:point withEvent:event];
    return v == self ? nil: v;
}

@end
安静被遗忘 2025-01-08 17:56:29

以下对我有用:

self.navigationController?.isNavigationBarHidden = true

The following worked for me:

self.navigationController?.isNavigationBarHidden = true
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文