objective-c - cocoa 移动重叠的 NSView

标签 objective-c cocoa resize nsview

我在一个主视图中有多个 View 。这些 View 都一个接一个地排列,因此当前只能看到最上面的一个。我想做的是,根据某些特定的用户输入,将后面的 View 之一在屏幕上移至较低位置,以便可以在顶 View 下方看到它。我一直试图通过确定两个 View 当前是否重叠来实现这一点,如果它们仍然重叠,则降低后面的 View ,如果它们仍然重叠,则进一步降低,依此类推,直到它们不再重叠并且都完全可见。然后我希望调整主视图的大小,以便可以看到两个 View ,但我认为这只是使用 setBounds 或 setFrame,还没有实现。

对于第一个问题,我还没有找到一种方法来从字面上查看两个 View 是否重叠,如果不能做到这一点,我想也许可以通过在 View 边界上绘制矩形并检查它们是否重叠,但我不这样做了解我该如何做其中任何一个。我认为需要边界或框架,但我不太确定它们有何不同。

基本上,我想检查两个 NSView 是否重叠,如果重叠,我想降低其中一个。

编辑:这部分问题已经基本解决了,但现在出现了一个新问题。我有三个 View ,一个主视图和两个 subview 。主视图没有任何东西,它只包含几个 subview ,主视图里面有什么就是应该看到的。两个 subview 堆叠在主视图之上,因此最前面的 subview 是可见的,后面的 subview 设置为隐藏。当用户点击开始时,后面的 View 变得可见,我使用选择器设置一个重复计时器,该选择器将检查 View 是否重叠,就像@Vince所说,如果重叠,它会稍微偏移后面的 View ,再次检查,直到它们不再重叠。使用这个:

- (void)updateViews {
CGRect viewFrame = [view frame]; //view is the frontmost view that will not move
CGRect backroundViewFrame = [backgroundView frame]; //the view in the back

CGRect rectIntersection = CGRectIntersection (viewFrame,
                                              backgroundFrame);

//if the intersect is NOT null, it'll offset down by 2
if (!CGRectIsNull(rectIntersection)) {
    CGRect newFrame = CGRectOffset (
                                    rectIntersection,
                                    0,     //doesn't move in x
                                    -2     //lowers by 2 in y
                                    );
    [backgroundView setFrame:newFrame]; //lowers the view to the new offset rect

} else{
    [viewsUpdater invalidate]; //stops the timer when rects no longer intersect
    viewsUpdater = nil;
}

问题是,当我降低backgroundView时,它仅在与前 View 相交的空间中可见。即使我将主视图展开得更低(这就是想法,它们都会以相同的尺寸开始一个在另一个之上,并且当backgroundView降低时,主视图将调整并显示两者)。但现在无论主视图有多大,backgroundView仅在与前 View 相交的区域中可见。我认为它正在移动到它必须去的地方,但当它停止时,它已经完全看不见了,所以我无法判断。

感谢您的帮助。

最佳答案

基本上,您将能够通过获取两个 frame 属性的交集(CGRectIntersection())来了解两个 NSView 对象是否重叠),然后使用 CGRectIsNull() 测试结果是否为 null。
这是doc为了它。

现在,关于将一个 View 放在另一个 View 上,听起来您需要使用 NSView 中的此方法:-(void)setSubviews:(NSArray *)newSubviews; ,根据documentation ,让您可以对 subview 重新排序。

或者简单地使用-(void)replaceSubview:(NSView *)oldView with:(NSView *)newView;,也就是说,因为oldView将被释放,请小心保留之前对它的引用。

如果您只是尝试将 View 移低,则只需更改接收器框架的原点,例如:

CGRect actualFrame = [aView frame];
CGPoint framesOrigin = actualFrame.origin;
CGRect newFrame = CGRectMake(framesOrigin.x,
                             (framesOrigin.y)+50,
                             actualFrame.width,
                             actualFrame.height);
[aView setFrame:newFrame];

通过更改框架原点的 y 坐标,这会将 aView 移动得更低。

最后,关于 boundsframe 属性之间的区别,这篇关于 SO Difference between view's frame and view's bound + iPhone 的文章,应该回答你的问题;)

关于objective-c - cocoa 移动重叠的 NSView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6716062/

相关文章:

ios - 这是什么ViewController

objective-c - Cocoa 应用程序 - 安全问题

objective-c - 在 Cocoa 应用程序中使用 XML-RPC 的最佳方式?

objective-c - 如何更改 NSOutlineView 的每个单元格的颜色或 NSTableCellView

java - 调整大小后 JLabel 文本在 JPanel 中消失

objective-c - 如何获得协议(protocol)定义的函数列表?

iphone - 处理在应用程序未运行时触发但在应用程序运行时仍显示的通知警报

objective-c - NSUserDefaults 在哪里存储信息?

c - 带控件的 DialogEx : Resizing?

java - Swing 图形用户界面;能够在运行长进程时调整窗口大小,但主框架内的面板在进程完成之前不会更新