Cocoa:是否存在具有用户调整大小功能的 NSView?

发布于 2024-09-27 11:06:20 字数 102 浏览 1 评论 0原文

我想要一个可以通过拖动右下角来调整大小的 NSView,就像 NSWindow 一样。我希望能够将此 NSView 嵌入到父 NSView 中。 Cocoa 或其任何扩展中是否有类似的组件?

I want an NSView that can be resized by dragging its the bottom right corner around, just like an NSWindow. I want to be able to embed this NSView into a parent NSView. Is there a component like this in Cocoa or any of its extensions?

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

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

发布评论

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

评论(2

乄_柒ぐ汐 2024-10-04 11:06:20

如果您的问题更具体,我可以更具体地回答。 :-)

据我所知,还没有类似的东西,但创建它并不是很难。要做的决定是“谁负责绘制调​​整大小夹点和调整大小/拖动逻辑?”

视图自行处理

如果您的用户可调整大小的视图负责绘制夹点并响应调整大小/拖动操作本身,那么您必须选择是否希望将夹点绘制在顶部视图的内容或“外部”。如果您希望手柄位于“外部”,“可用区域”就会减少,因为您的内容必须插入足够的位置,以便为您绘制调整大小控件留出空间,这可能会使绘制和大小调整指标变得复杂。如果将夹点绘制在内容的“顶部”,则可以避免此问题。

容器视图处理所有子视图

另一种方法是创建一个“可调整大小的视图容器视图”,它在任何子视图的周边绘制调整大小夹点,并通过“当它(容器)在其抓握区域之一接收到拖动事件时,“控制子视图”。将逻辑放置在此处允许任何类型的子视图可拖动/调整大小,并为您带来额外的好处,即仅拥有一个稍重的视图实例(相对于许多具有更复杂逻辑的子视图实例)。

基本机制

一旦您决定了这一点,实际上只需创建子视图即可,该子视图执行绘图、管理 NSTrackingArea 实例(用于抓地力区域)以及响应适当的鼠标方法(向下、移动等)。在每个子视图处理自己的情况下,它们将管理自己的跟踪区域、夹点绘图和鼠标移动,并设置自己的框架作为响应。在容器视图为其子视图处理所有这些的情况下,它将管理所有子视图的跟踪区域并在其自身上绘制它们的手柄,并设置目标子视图的框架(并且子视图对整个事情一无所知)。

我希望这至少能让您对可能的机制有一个大概的了解。如果我没有起床并开始喝早间咖啡,我可能可以写得更简洁,但现在就这样了。 :-)


7年后编辑

因为关于OP想要什么的细节不多,我给出了一个非常笼统的答案,但我应该指出几点:

  • 总是如果可以使 NSSplitView 适合您(即,如果视图彼此对齐并划分公共容器视图的空间),则更喜欢 NSSplitView。分割视图可让您自定义抓握区域等,并免费对您的子视图执行所有这些操作。
  • 当我写这个答案时,AutoLayout 还不存在,它使您自己的视图处理多个大小子视图场景的解决方案变得非常复杂。
  • 如果您确实需要一个可以在某个容器中拖动/调整大小的 UI 元素,请尽量避免在主视图中使用 CALayers(如果可以的话)来处理所有布局/大小调整逻辑。
  • 如果您不能执行上述操作(即,可调整大小的视图包含复杂的控件和布局,有自己的 NSViewController 等),请尝试混合方法(使用图层来显示非 。
  • 由于自动布局的复杂性,我真的不建议使用真正的可拖动子视图方法,除非它是不可避免的 设计一个包含可移动的、相当大的东西的视图,最好(也是最有效的)让视图负责其中的所有内容示例:具有大量形状的图形应用程序应该有一个代表形状的 Canvas 视图(以及任何 GUI 装饰,例如。大小/拖动夹点等)使用CALayers,这利用了图形加速,并且比一堆(非常占用资源)NSView 效率 子视图。所有移动/大小/选择逻辑均由“Canvas View”处理,唯一的子视图可能是覆盖控件(尽管如果您的 Canvas 本身需要包含在滚动视图中,则最好使用 < code>NSScrollView 机制允许固定覆盖视图用于此目的)。
  • 如果设计一个绘制很多东西的视图(为此你绝对应该使用图层来表示这些东西)但只允许选择一个东西,那么即使使用自动布局,添加子视图的方法也是足够易于管理的。如果“选择进行编辑”的东西有很多复杂的控件,在编辑时变得可见,那么带有视图控制器的“编辑器子视图”是有意义的,并且是可维护性方面的一个很好的权衡(因为视图控制器划分了所有编辑功能/UI 处理)与容器视图复杂性(因为一个子视图不会破坏资源库,并且在容器视图调整大小和编辑器交互期间维护临时自动布局约束以保持其位置也不会过于复杂)。
  • 所有这些都假设 macOS;如果为 iOS 进行设计,绝对会竭尽全力使用图层和新的(截至撰写本文时)拖放机制,而我目前对此知之甚少。

总之,答案不完整,而且有些过时,所以我觉得我原来的建议并不像现在那么好。

If you get more specific with your question, I can get a little more specific with the answer. :-)

There is nothing like this available that I know of, but it's not terribly difficult to create. The decision to make is "who handles drawing the resize grips and resizing / dragging logic?"

Views Handle Their Own

If your user-resizable view handles drawing the grips and responding to the resizing/dragging actions itself, then you have to choose whether you want the grips drawn atop the view's contents or "around the outside." If you want the grips "outside," the "usable area" decreases because your content has to be inset enough to leave room for you to draw the resizing controls, which can complicate drawing and sizing metrics. If you draw the grips "atop" the content, you can avoid this problem.

Container View Handles All Subviews

The alternative is to create a "resizable view container view" that draws the resize grips around any subviews' perimeters and handles the dragging/resizing logic by "bossing the subviews around" when it (the container) receives dragging events on one of its grip areas. Placing the logic here allows any type of subview to be draggable / resizable and gives you the added benefit of only having one instance of the slightly-heavier-weight view (versus many instances of subviews that have the more complicated logic in them).

The Basic Mechanism

Once you've decided that, it's really just a matter of creating your subview, which does the drawing, manages NSTrackingArea instances (for the grip areas), and responds to the appropriate mouse methods (down, moved, etc.). In the case of each subview handling its own, they'll manage their own tracking areas, grip drawing, and mouse moved, setting their own frame in response. In the case of a container view handling all this for its subviews, it will manage all subviews' tracking areas and draw their grips on itself, and set the targeted subview's frame (and the subview is blissfully ignorant of the whole thing).

I hope this helps give you at least a general idea of possible mechanisms. Had I not just gotten up and started my morning coffee, I'd probably be able to write this more succinctly, but there you have it. :-)


EDIT 7 YEARS LATER

Because there wasn't much detail about what the OP wanted, I gave a very generic answer, but I should make a few points:

  • Always prefer an NSSplitView if it can be made to work for you (ie, if the views align with each other and divide the common container view's space). A split view lets you customize grip areas, etc. and does all of this to your subview for free.
  • AutoLayout didn't exist when I wrote this answer and it greatly complicates rolling your own solution for the view-handling-multiple-sizable-subviews scenario.
  • If you really do need a UI element that can be dragged/resized within some container, try your best to get away with using CALayers inside a master view that handles all the layout/sizing logic if you can.
  • If you can't do the above (ie, the resizable view contains complex controls and layout, has its own NSViewController, etc.), try a hybrid approach (use layers to display cached images of non-selected views and only add a full, interactive sizable subview for the selected item (or subviews for items).
  • Because of the complexities of AutoLayout, I really can't recommend the real draggable subview approach at all unless it's unavoidable. If you're designing a view that contains movable, sizable things, it's best (and most efficient) to make everything inside it that view's responsibility. Example: a graphics app with lots of shapes should have a Canvas view that represents the shapes (and any GUI decorations like size/drag grips, etc.) using CALayers. This takes advantage of graphics acceleration and is far more efficient than a bunch of (very resource-heavy) NSView subviews. All the move/size/select logic is handled by the "Canvas View" and the only subviews might be overlaid controls (though if your Canvas itself needs to be enclosed in a scroll view, it's best to use NSScrollView machinery to allow stationary overlay views for this purpose).
  • If designing a view that draws lots of things (for which you should definitely use layers to represent those things) but allows selecting only one thing, the approach of adding a subview is manageable enough even with AutoLayout. If the "selected for editing" thing has lots of complex controls that become visible when editing, an "editor subview" with accompanying view controller makes sense and is a good tradeoff in maintainability (because view controller compartmentalizes all editing functionality/UI handling) vs. container view complexity (because one subview isn't going to break the resource bank and maintaining temporary AutoLayout constraints for keeping its position during container view resizes & editor interactions isn't overly complex).
  • All of this assumes macOS; if designing for iOS, definitely bend over backwards to use layers and the new (as of this writing) drag and drop machinery, of which I know precious little at present.

In summary, the answer was incomplete as well as somewhat outdated, so I feel my original advice isn't as good as it could be these days.

千寻… 2024-10-04 11:06:20

您可以使用窗口而不是使用视图,并将窗口的样式掩码设置为 NSResizableWindowMask。

如果您有两个可调整大小的连续子视图,另一种选择是使用 NSSplitView。

Instead of using views, you can use windows and set the style mask of the window to NSResizableWindowMask.

Another option is using an NSSplitView, if you have two resizable, contiguous subviews.

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