首先,我想说我已经看了很多其他资源试图实现这一点,但我看到的任何东西似乎都没有帮助.
例如:Automatically grow document view of NSScrollView using auto layout?
我有一个我在Interface Builder中创建的NSScrollView并设置约束以填充它所在的窗口:滚动视图的顶部,左侧,右侧和底部设置为等于超级视图的顶部,左侧,右侧和底部(其中是Xamarin中viewcontroller使用的xib视图.
我想要的文档视图是一个简单的NSView,它在我的viewcontroller的ViewDidLoad中动态填充了NSImageViews:
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;
因为我不一定知道_projects中有多少项目,我不知道将加载到每个imageView中的图像的高度,虽然我知道预期的比例,但我不知道我的文档的高度直到运行时
我希望每次滚动视图所在的封闭窗口(因此也调整滚动视图)时,documentView的宽度都会调整为与NSClipView相同.至于documentView的高度,我希望它由我在documentView中填充的imageViews的大小决定,这就是高度约束相对于宽度的原因.
我已经使用了documentView的AutoresizingMask,NSClipView,scrollview等.我尝试将TranslatesAutoresizingMaskIntoConstraints设置为false,并添加约束以将documentView的Left,Right和Top设置为等于NSClipView的约束.当我这样做时,视图似乎甚至没有出现.我似乎无法想出这个.
我也试过这样做而不使用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;
}
}
最佳答案 我想到了.所以,这样做的诀窍在于,除非你将底部固定在最后一个子视图中,否则documentView不会知道自己有多大.您可以使用可视化格式执行此操作,但如果您在运行时之前实际上并不知道您的视图是什么,那就有点了.这是适合我的代码:
public override void ViewDidLoad()
{
base.ViewDidLoad();
var clipView = EventListScrollView.ContentView;
var documentView = new FlippedView();
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 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.LessThanOrEqual, imageView, NSLayoutAttribute.Width, (nfloat)0.360, 0);
documentView.AddSubview(imageView);
documentView.AddConstraint(xPosConstraint);
documentView.AddConstraint(yPosConstraint);
documentView.AddConstraint(widthConstraint);
documentView.AddConstraint(heightConstraint);
lastHeader = imageView;
ImageService.Instance.LoadUrl($"https:{project.ProjectLogo}").Into(imageView);
}
if(lastHeader!=null)
{
var bottomPinConstraint = NSLayoutConstraint.Create(documentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, lastHeader, NSLayoutAttribute.Bottom, 1, 0);
documentView.AddConstraint(bottomPinConstraint);
}
}
关键是最后一个约束 – bottomPinConstraint.这允许documentView扩展其高度以适应所有子视图.
另外,我仍然需要使用IsFlipped = true的视图;即使我手动设置NSClipView和我的documentView之间的约束,否则它会忽略约束并将我的视图固定到NSClipView的底部.我的EventListScrollView是在Interface Builder中创建的,并且设置了约束以使其填充整个窗口.
最终结果是一个带有DocumentView的NSScrollView,它填充了ScrollView的宽度,但也垂直扩展以适应我以编程方式添加到它的子视图.