I can't seem to figure out how to get the content inside a NSScrollView to scale properly. I have come across a few references which describe general approaches, but nothing concrete.
Ambiguous Layout
This seems to indicate that NSScrollView and Auto Layout don't play nicely together. It is somewhat telling that both the iOS & OSX Auto Layout guide examples are UIScrollView instead of NSScrollView:
Auto Layout Examples
I threw together an example. The main window contains a split view with some fixed content on the right and a view that will be filled in programmatically on the left. (I would post a picture, but I don't have the required reputation yet). Running the code below, any attempt to move the splitter will result in it snapping back to the original position.
AppDelegate.h
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (weak) IBOutlet NSScrollView *scrollView;
@property (strong, nonatomic) NSView *containerView;
@property (strong, nonatomic) NSMutableDictionary *views;
@property (assign) IBOutlet NSWindow *window;
@end
AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize scrollView;
@synthesize containerView;
@synthesize views;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
-(void)awakeFromNib {
// Create a container to hold all the subviews
containerView = [[NSView alloc] initWithFrame:NSZeroRect];
[containerView setTranslatesAutoresizingMaskIntoConstraints:NO];
[scrollView setDocumentView:containerView];
views = [[NSMutableDictionary alloc] init];
for (int i=0; i<8; i++) {
NSBox *box = [[NSBox alloc] init];
NSString *title = [NSString stringWithFormat:@"Box%@", [[NSNumber numberWithInt:i] stringValue]];
box.title = title;
[views setObject:box forKey:title];
[box setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:box];
}
long height = 160;
NSArray *sortedKeys = [[views allKeys] sortedArrayUsingSelector: @selector(compare:)];
for(NSString *viewName in sortedKeys) {
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[[NSString alloc] initWithFormat:@"|-20-[%@]-20-|", viewName] options:0 metrics:nil views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[[NSString alloc] initWithFormat:@"V:[%@(==%ld)]",viewName, height] options:0 metrics:nil views:views]];
}
// Build the subview-to-subview constraint string
NSString *constraintString = @"V:|";
for(NSString *viewName in sortedKeys) {
constraintString = [constraintString stringByAppendingString:[NSString stringWithFormat:@"-20-[%@]",viewName]];
}
// Subview-to-subview constraints
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraintString options:0 metrics:nil views:views]];
// Container view constraints
NSDictionary *topLevelDictionary = NSDictionaryOfVariableBindings(containerView);
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[containerView]-0-|" options:0 metrics:nil views:topLevelDictionary]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[containerView]" options:0 metrics:nil views:topLevelDictionary]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[[NSString alloc] initWithFormat:@"V:|[containerView(==%ld)]", (long)(20 + height) * sortedKeys.count + 20] options:0 metrics:nil views:topLevelDictionary]];
}
@end
Any direction would be greatly appreciated.
I had this same issue. Autolayout and NSSplitView
play very nicely together, you just need to sacrifice the right kind of chicken.
Try setting holding priority slightly higher on the relevant split portion. The image shows that my rightmost split will take priority.
Also another consideration. Is the content of the relevant split width constrained? You may need to set a greater-than-or-equal constraint on its width e.g |-0-[mysplitcontent(>=minwidth)]-0-|
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