First of all, I want to say that I've looked at a good number of other resources trying to accomplish this, but nothing I've looked at seems to help.
For instance: Automatically grow document view of NSScrollView using auto layout?
I have an NSScrollView that I created in Interface Builder and set constraints on to fill the window it's in: Top, Left, Right, and Bottom of the scrollview are set equal to the Top, Left, Right, and Bottom of the superview (which is the xib view used by the viewcontroller in Xamarin).
My intended document view is a simple NSView that is being dynamically filled with NSImageViews within my viewcontroller's ViewDidLoad:
EventListScrollView.TranslatesAutoresizingMaskIntoConstraints = false;
var documentView = new NSView(EventListScrollView.Bounds);
//documentView.AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.HeightSizable;
//documentView.TranslatesAutoresizingMaskIntoConstraints = false;
NSView lastHeader = null;
foreach(var project in _projects)
{
var imageView = new NSImageView();
imageView.TranslatesAutoresizingMaskIntoConstraints = false;
imageView.SetContentCompressionResistancePriority(1, NSLayoutConstraintOrientation.Horizontal);
imageView.SetContentCompressionResistancePriority(1, NSLayoutConstraintOrientation.Vertical);
imageView.ImageScaling = NSImageScale.ProportionallyUpOrDown;
var xPosConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, documentView, NSLayoutAttribute.Left, 1, 0);
NSLayoutConstraint yPosConstraint = null;
if(lastHeader!=null)
{
yPosConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, lastHeader, NSLayoutAttribute.Bottom, 1, 0);
}
else
{
yPosConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, documentView, NSLayoutAttribute.Top, 1, 0);
}
var widthConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, documentView, NSLayoutAttribute.Width, 1, 0);
var heightConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, imageView, NSLayoutAttribute.Width, (nfloat)0.325, 0);
documentView.AddSubview(imageView);
documentView.AddConstraints(new[] { xPosConstraint, yPosConstraint, widthConstraint, heightConstraint });
lastHeader = imageView;
ImageService.Instance.LoadUrl($"https:{project.ProjectLogo}").Into(imageView);
}
EventListScrollView.DocumentView = documentView;
Since I don't necessarily know how many projects are in _projects
and I don't know the height of the image that will be loading into each imageView
, though I do know the intended ratio, I don't know the height of my documentView until runtime.
I want the documentView
's width to be resized to be the same as the NSClipView
every time the enclosing window the scrollview is in (and therefore also the scrollview) is resized. As for the height of the documentView
, I want it to be determined by the size of the imageView
s I'm populating in the documentView
, which is why the height constraint is relative to the width.
I've played around with the AutoresizingMask
of the documentView
, the NSClipView
, the scrollview, etc. I tried setting TranslatesAutoresizingMaskIntoConstraints
to false
for everything and adding constraints to set the Left, Right, and Top of the documentView
equal to that of the NSClipView
. When I did that, the view doesn't even seem to show up. I can't seem to figure this one out.
I've also tried doing this without using NSImageViews:
public override void ViewDidLoad()
{
base.ViewDidLoad();
EventListScrollView.TranslatesAutoresizingMaskIntoConstraints = false;
var clipView = new NSClipView
{
TranslatesAutoresizingMaskIntoConstraints = false
};
EventListScrollView.ContentView = clipView;
EventListScrollView.AddConstraint(NSLayoutConstraint.Create(clipView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, EventListScrollView, NSLayoutAttribute.Left, 1, 0));
EventListScrollView.AddConstraint(NSLayoutConstraint.Create(clipView, NSLayoutAttribute.Right, NSLayoutRelation.Equal, EventListScrollView, NSLayoutAttribute.Right, 1, 0));
EventListScrollView.AddConstraint(NSLayoutConstraint.Create(clipView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, EventListScrollView, NSLayoutAttribute.Top, 1, 0));
EventListScrollView.AddConstraint(NSLayoutConstraint.Create(clipView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, EventListScrollView, NSLayoutAttribute.Bottom, 1, 0));
var documentView = new NSView();
documentView.WantsLayer = true;
documentView.Layer.BackgroundColor = NSColor.Black.CGColor;
documentView.TranslatesAutoresizingMaskIntoConstraints = false;
EventListScrollView.DocumentView = documentView;
clipView.AddConstraint(NSLayoutConstraint.Create(documentView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, clipView, NSLayoutAttribute.Left, 1, 0));
clipView.AddConstraint(NSLayoutConstraint.Create(documentView, NSLayoutAttribute.Right, NSLayoutRelation.Equal, clipView, NSLayoutAttribute.Right, 1, 0));
clipView.AddConstraint(NSLayoutConstraint.Create(documentView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, clipView, NSLayoutAttribute.Top, 1, 0));
NSView lastHeader = null;
foreach(var project in _projects)
{
var random = new Random();
var imageView = new NSView();
imageView.TranslatesAutoresizingMaskIntoConstraints = false;
imageView.WantsLayer = true;
imageView.Layer.BackgroundColor = NSColor.FromRgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)).CGColor;
var xPosConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, documentView, NSLayoutAttribute.Left, 1, 0);
NSLayoutConstraint yPosConstraint = null;
if(lastHeader!=null)
{
yPosConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, lastHeader, NSLayoutAttribute.Bottom, 1, 0);
}
else
{
yPosConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, documentView, NSLayoutAttribute.Top, 1, 0);
}
var widthConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, documentView, NSLayoutAttribute.Width, 1, 0);
var heightConstraint = NSLayoutConstraint.Create(imageView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, imageView, NSLayoutAttribute.Width, (nfloat)0.325, 0);
documentView.AddSubview(imageView);
documentView.AddConstraints(new[] { xPosConstraint, yPosConstraint, widthConstraint, heightConstraint });
lastHeader = imageView;
}
}