【问题标题】:Change NSView subviews order更改 NSView 子视图顺序
【发布时间】:2012-07-03 13:09:24
【问题描述】:

我正在使用呈现不同句柄的自定义控件。我想确保选定的句柄比其他句柄有一个 Z-index 刨丝器。

有没有办法交换视图顺序? 我找到了这个函数sortSubviewsUsingFunction:context:,但我不明白这是否是正确的解决方案。

【问题讨论】:

  • 您可以遍历所有子视图并获取它们,您可以将每个子视图插入到视图中的索引...

标签: objective-c cocoa nsview subviews


【解决方案1】:

Cocoa 在 macOS 10.0 中引入了新的 API。
和iOS类似,你可以传递另一个视图显示在下方或上方。

[self.view addSubview:myView positioned:NSWindowBelow relativeTo:myViewInBackground];

查看documentation;以我的经验,NSWindowBelowNSWindowAbove 似乎相反。

【讨论】:

  • 你不需要在 parent.addSubview(child,index) 之前使用 child.removeFromSuperview() 来交换吗?那么使用 NSView 类中的 sortSubviewsUsingFunction 不是更合适吗?
  • 经过一些测试。再次添加视图效果很好。无需删除。
  • 文档说它自 10.0 以来一直存在,而不是 10.10。因此也可用于 10.10 以下的目标。
【解决方案2】:

这很简单,您可以使用比较 2 个子视图的函数来重新排序它们。这是一个基于视图标签的简单解决方案:

[mainView sortSubviewsUsingFunction:(NSComparisonResult (*)(id, id, void*))compareViews context:nil];

...

NSComparisonResult compareViews(id firstView, id secondView, void *context) { 
    int firstTag = [firstView tag];
    int secondTag = [secondView tag];

    if (firstTag == secondTag) {
        return NSOrderedSame;
    } else {
        if (firstTag < secondTag) {
            return NSOrderedAscending;
        } else { 
            return NSOrderedDescending;
        }
    }
}

【讨论】:

  • 很抱歉,我看不懂 compareViews 函数的原型。它是否混合使用了 Objective-c 和 C?
  • Objective-C 是 C 的超集,因此这是 Objective-C
【解决方案3】:

是的,sortSubviewsUsingFunction:context: 可以做您想做的事情,但是如果您只想将一个特定视图放在(无序的)其他视图之上,那可能就有点过头了。在这种情况下,您应该查看UIViewbringSubviewToFront: 方法。这样,您可以在 IBAction 中执行类似的操作来调出句柄:

[self.view bringSubviewToFront: handle];

假设句柄是一个/继承自 UIView 的对象。如果这不是您要查找的内容,那么请务必使用sortSubviewsUsingFunction:context:,在这种情况下,您需要更改每个子视图的各个标签属性,并进行相应的排序。

【讨论】:

  • 我正在使用非 iOS 的 OSX...但是 +1 因为我可以搜索类似的功能。
  • 啊,在这种情况下,这看起来有点骇人听闻,但您始终可以添加一个类别来执行以下操作:stackoverflow.com/questions/4236304/…
  • 谢谢,我需要了解这个解决方案在性能方面是否比 sortSubviewsUsingFunction 更好
  • 没问题!我不能权威地说它会更快,但我的想法是肯定的。这取决于 sortSubviewUsingFunction:context: 的内部结构,我无法评论。然而,我想它的工作原理是这样的:1)操纵子视图指针的内部数组,然后 2)重新绘制 UI。当然,我们的步骤 1 会更快,因为它不会像排序那样遍历所有子视图。对于第 2 步,它可能更快或相等,因为实现将全部重绘(我们的更快)或仅重绘更改(相等)。
  • 也就是说,如果性能对您的应用非常重要,您可能需要对不同的方法进行基准测试 - 看看 stackoverflow.com/questions/3017888/…
【解决方案4】:

据我所知,您可以循环查看所有视图并将它们添加到数组中,然后您可以选择使用索引将它们添加到视图中......并且您具有以下功能。

[self.view insertSubview:view1 atIndex:2]
[self.view insertSubview:view1 aboveSubview:0]
[self.view insertSubview:view1 belowSubview:1]

然后你可以根据需要交换它的顺序..

【讨论】:

  • 看起来 OP 在询问 NSViews 这仅适用于 UIViews
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
相关资源
最近更新 更多