【问题标题】:How to make a UIView always appear at the front?如何让 UIView 总是出现在最前面?
【发布时间】:2011-09-24 13:59:27
【问题描述】:

目前我有一个包含一些控件的 UIView。然后,我以编程方式将一些图像添加到视图中以显示为动画。目前在我的游戏循环的每个间隔结束时,我必须告诉控制器将 UIView 控件移到前面,否则图像将出现在它的顶部。有没有一种成本更低的方法让它始终保持在顶部。

目前我的游戏循环结束时有以下内容:

[self.view bringSubviewToFront:myControlView];

我可以在游戏开始时做这样的事情吗:

myControlView.alwaysOnTop = true;

【问题讨论】:

  • 我刚刚遇到了同样的问题。我想在我的所有视图(导航/页面视图等的复杂添加)前面有一个 UIImageView 来显示教程。我不得不混合一些东西才能让它工作。事实上,我同时使用了:bringSubviewToFront:view.layer.zPosition=MAXFLOAT 这可能对某人有帮助!

标签: iphone uiview


【解决方案1】:

不要使用-addSubview: 插入图片,而是使用-insertSubview:belowSubview: 并将UIView 作为第二个参数传递:

[self.view insertSubview:myImage belowSubview:myControlView];

请注意,出于类似目的,您还可以访问方法 -insertSubview:aboveSubview:-insertSubview:atIndex:

【讨论】:

    【解决方案2】:

    Objective-C

    #import <QuartzCore/QuartzCore.h>
    myAlwaysOnTopView.layer.zPosition = MAXFLOAT;
    

    斯威夫特 2

    myAlwaysOnTopView.layer.zPosition = .max
    

    斯威夫特 3

    myAlwaysOnTopView.layer.zPosition = .greatestFiniteMagnitude
    

    Swift 5.3

    view.layer.zPosition = CGFloat(Float.greatestFiniteMagnitude)
    

    此解决方案更好,特别是如果您希望您的视图始终位于顶部,而不管其后添加的其他视图如何。只需使用 addSubview: 添加任何其他视图,它将始终保持在顶部。

    重要提示:此解决方案将使 UIView显示在顶部,但它仍将低于 UI 系统的其他视图。也就是说,任何用户与视图的交互通常都不起作用,因为它首先由其他重叠视图处理。

    【讨论】:

    • 它适用于 iOS 7.1。但是当添加 VC 时我失去了联系(如图所示)。将 userInteractionEnabled 设置为 YES 没有帮助。
    • CGFloat.max 已在 swift 3 中重命名为 CGFloat.greatestFiniteMagnitude
    • 在出现弹出对话框或警告时不工作
    • 虽然此解决方案适用于纯粹的可见性,但它不保证它会覆盖它“下方”的任何元素的触摸(至少对于任何手势识别器都是如此)。
    • 它适用于唯一的显示视图。对于动作或手势需要在窗口上添加视图。
    【解决方案3】:

    另一种选择是将您的视图放在另一个具有更高 windowLevel 的 UIWindow 上。向Flipboard FLEX或我的简化版Paramount学习

    Manager.action = {
      print("action touched")
    }
    
    Manager.show()
    

    看看FLEXWindow如何选择合适的windowLevel和处理触摸

    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor = [UIColor clearColor];
            // Some apps have windows at UIWindowLevelStatusBar + n.
            // If we make the window level too high, we block out UIAlertViews.
            // There's a balance between staying above the app's windows and staying below alerts.
            // UIWindowLevelStatusBar + 100 seems to hit that balance.
            self.windowLevel = UIWindowLevelStatusBar + 100.0;
        }
        return self;
    }
    
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
    {
        BOOL pointInside = NO;
        if ([self.eventDelegate shouldHandleTouchAtPoint:point]) {
            pointInside = [super pointInside:point withEvent:event];
        }
        return pointInside;
    }
    

    【讨论】:

      【解决方案4】:

      要将子视图移到所有其他当前子视图的后面,请使用view.sendSubviewToBack(yourSubview)

      【讨论】:

        【解决方案5】:

        记住也有这个方法,

        - (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview
        

        【讨论】:

          【解决方案6】:

          另一种解决方案是为所有其他视图创建一个不可见的容器视图。首先将该容器视图添加到您的主视图中,然后将您想要的 UIView 添加到顶部。然后将所有其他视图添加到容器视图,而不是主视图。

          【讨论】:

          • 我认为这是最干净、最安全的解决方案。干杯。
          猜你喜欢
          • 2015-07-06
          • 2012-12-17
          • 2014-05-08
          • 1970-01-01
          • 2014-03-19
          • 1970-01-01
          • 2016-03-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多