CocoaDev

Edit AllPages

I’ve recently written a layout managing subclass of NSView to position subviews in an automatic flowing-grid like fashion, in a move to implement the response by RyanBates for OverComplexGuiSimplification.

Now, my layout manager works, but it’s entirely possible that more views will be inserted than there is room to position so I’d like to have the layout view grow vertically to acommodate all the subviews, and let an NSScrollView do the dirty work of managing scrollbar size and whatnot.

So, the question is, can I just make the layout view resize and the scrollview will work automatically? Or am I going to have to deal with some sort of “roving window” situation?

Also, the height of the layout view is dependent on the width, since it’s flowing the subviews according to minimum size constraints. Will this make things harder?

–ShamylZakariya


The NSScrollView/NSClipView will register for ‘framed changed’ notifications. So sending setSize: to self will update the scroll view.

I am not sure what exactly you refer to in ‘make things harder’. If you want your view always to follow the width of the scroll view and calculate height accordingly (so resizing the width of the scroll view will change the virtual height), then it definitely requires more code, but it’s not impossible.

An easy solution might be to set the auto-sizing for only the width and then overload setSize: to call super with a modified rectangle, since when resizing the scroll view, your setSize: will be called.


What I was worried about was that it was something more “magical” than simply resizing the content view. I’ve worked with a lot of different GUI APIs ( Qt, GTK, BeOS, Win32, Swing, etc ) and each has its own way, more or less, for handling scroll views.

What I did was have my view, in its awakeFromNib check for [self enclosingScrollView] and if it’s non-null I set the autoresize mask to height & width resizable and to resize itself to fit the content rect. Subsequent resizes on the scrollview keep my view fitting in it completely.

Everything works fine, after that. The only tricky parts I had were to catch redundant frame resize notifications and to prevent infinite loops when resizing the height from within a frame-resize triggered layout.

The important part is it works – and – if anybody has any need for a flow-layout NSView I’d be happy to submit it to the sample code. It’s really nice – all you do is tell it a minimum size for child views as well as padding and spring rules and it will lay all childviews out from left to right, top to bottom; reflowing when the width changes. it also allows for single-column layout, which is nice for situations where you want to emulate a single-column table but want to be able to insert arbitrary NSViews.

–ShamylZakariya


actually I’d be interested (I think…) I’ve been trying to figure out where to attach code to an NSMatrix in an NSScrollView to make it adjust cell spacing/number of columns to make best use of horizontal space, adding more rows vertically when it needs, and without having a horizontal scroll ever… I can’t figure out if I need a delegate for the matrix/scroll view or if there’s a notification I can respond to or does it need to be in a live resizing session…


Here’s how I do this (above post).

////////////////////// BKMatrix.h:

// Warning: This supports content and selected* bindings, but it has only been tested with // the content and selectedObjects bindings.

#import <Cocoa/Cocoa.h>

@interface BKMatrix : NSMatrix { // Key paths and observed object, indexed by binding name. NSMutableDictionary *keyPaths; NSMutableDictionary *observedObjects;

NSArray *oldContent;

BOOL wrapsCellsToFit;
BOOL expandsCellsToFillWidth;

NSSize minimumCellSize;
NSEvent *downEvent;

SEL deleteAction;
NSObject *delegate; }

/*! This method has no effect if the minimum cell size is not set. */

@end

////////////////////// BKMatrix.m:

#import “BKMatrix.h”

@interface BKMatrix (Private)

@end

@implementation BKMatrix (Private)

/*! Adjusts cell sizes to fill width, rewrapping if needed. Do not call this method from a bindings notification method; it calls -rearrangeObjects, and a call cycle could occur. This method has no effect if the minimum cell size is not set. Reference: http://www.cocoabuilder.com/archive/message/cocoa/2004/1/30/99886 */

// Reference: http://www.cocoadev.com/index.pl?DragMatrix

// Reference: http://www.cocoadev.com/index.pl?DragMatrix

/*! Update selectedIndex, selectedObject, selectedTag, selectedValue bindings. */

@end

@implementation BKMatrix

// Reference: http://www.cocoadev.com/index.pl?DragMatrix

#pragma mark - #pragma mark Accessors

@end


I have a view inside a NSScrollView, implemented in InterfaceBuilder.

When I move the scrollbar, the view gets very messy, things overlapping each other and that kind of stuff.

What do I have to do?


I would recommend reading the documentation on drawing and views. Specifically: http://developer.apple.com/documentation/Cocoa/Conceptual/DrawViews/Tasks/DisplayingViews.html (see Marking a View as Needing Display)


I solved it but it is kinda stupid. see example code


PLEASE read the documentation as prescribed above. What are you trying to accomplish with the code above? —-