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?
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:
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.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).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).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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With