我正在尝试遵循UIScrollView And Autolayout Mixed approach。
我见过其他类似的问题but with no accepted answer。
我不确定这是我所需要的。
[请注意,我既没有使用Storyboard,也没有使用XIB。我的所有视图都是使用Xamarin.iOS中的c#以编程方式创建的。这与目标C代码非常相似。
[和其他许多人一样,我找不到使滚动视图实际滚动的方法。
因此,在我的主View Controller中,ViewDidLoad()中具有以下内容:
public override void ViewDidLoad()
{
base.ViewDidLoad();
_scrollView = new UIScrollView
{
ShowsHorizontalScrollIndicator = false,
TranslatesAutoresizingMaskIntoConstraints = false,
AlwaysBounceVertical = true,
Bounces = true
};
_refreshControl = new UIRefreshControl { TranslatesAutoresizingMaskIntoConstraints = false };
_refreshControl.Enabled = true;
_refreshControl.ValueChanged -= RefreshControl_ValueChanged;
_refreshControl.ValueChanged += RefreshControl_ValueChanged;
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
_scrollView.RefreshControl = _refreshControl;
}
else
{
_scrollView.AddSubview(_refreshControl);
}
this.View.AddSubview(_scrollView);
_scrollViewContainer = new UIView { TranslatesAutoresizingMaskIntoConstraints = true };
_scrollView.AddSubview(_scrollViewContainer);
_scrollView.Anchor(top: this.View.SaferAreaLayoutGuide().TopAnchor, leading: this.View.LeadingAnchor, bottom: this.View.SaferAreaLayoutGuide().BottomAnchor, trailing: this.View.TrailingAnchor);
}
没什么特别的,我创建我的UIScrollView并将其添加为主视图的子视图。创建一个UIRefreshControl并将其添加到滚动视图。创建一个普通的UIView并将其添加到UIScrollView中,以便放置所有子视图。
因为我使用的是AutoLayout,所以ScrollView锚定在主视图的约束内。
现在稍后在ViewWillAppear()中,我正在创建添加到普通UIView的Card View。这些卡片视图使用自动布局将它们堆叠在一起,第一张卡片固定在容器视图的顶部,前导和尾随锚点上。
这些卡中的所有东西都使用自动布局,基本上可以堆叠所有东西。
public UIView BuildQOLCard()
{
CardView qolCard = new CardView();
_scrollViewContainer.AddSubview(qolCard);
qolCard.TranslatesAutoresizingMaskIntoConstraints = false;
qolCard.CornerRadius = 5f;
qolCard.ShadowOffsetHeight = 0;
qolCard.ShadowOffsetWidth = 0;
qolCard.BackgroundColor = UIColor.White;
...
qolCard.Anchor(leading: _scrollViewContainer.LeadingAnchor, trailing: _scrollViewContainer.TrailingAnchor, top: _scrollViewContainer.TopAnchor, padding: new UIEdgeInsets(10f, 10f, 10f, 10f));
return qolCard;
}
当然,容器视图不会神奇地知道如何调整自身大小。因此,我必须给它一个尺寸,否则我什么也看不到。
所以我像这样帮了个忙:
public void SizeScrollViewContentSize()
{
nfloat scrollViewHeight = 0.0f;
foreach (UIView view in this._scrollViewContainer.Subviews)
{
scrollViewHeight += view.Frame.Size.Height;
}
this._scrollViewContainer.Frame = new CGRect(0, 0, this._scrollView.Frame.Width, scrollViewHeight);
}
但是我似乎无法弄清楚何时调用它,因为子视图在这里,但是它们的大小是未知的。我尝试从ViewDidLayoutSubviews()调用它。
感谢任何帮助。
滚动视图需要定义其框架和它需要定义其内容。如果内容受到限制,则滚动是自动的。
我将逐步进行此操作-使用Storyboard,以便我们可以看到发生了什么。通过代码执行此操作绝对没有区别。
[从视图控制器开始,添加滚动视图,并将其约束到所有四个侧面(我给它提供了绿色背景,以便我们可以看到它:]]
现在我们添加一个“容器”视图(青色背景,并将所有4面约束到滚动视图中:
如果运行此命令,我们将看到:
这是因为“容器”没有宽度或高度。它的前导/尾随/顶部/底部约束定义了滚动视图的content。
因此,我们将其等于宽度和高度等于滚动视图:
运行它,我们看到了:
这很好,除了...它将永远不会滚动,因为它与滚动视图的高度相同。
所以,我删除等高-因为我要容器的content确定其高度。
我添加了一个“ CardView”,并将其“顶部” /“前导” /“尾随”约束设置为“容器”的“顶部” /“前导/尾随”约束,并具有10点“填充”和100的高度。我还为其设置了“底部约束” “容器”的底部(+10)-将“拉出容器的底部”至CardView底部下方最多10点:
导致:
现在我添加第二个CardView,将Leading / Trailing约束约束到容器的Leading / trailing,具有10点“填充”和100的高度。然后将其Top约束设置为CardView-1的底部(+10 ),并将其底部限制为“容器”的底部(+10):
[不幸的是,我们现在从CardView-1的底部获得了10点约束。[[和从CardView-2的底部得到了10点约束,这当然是行不通的。] >因此,让我们从CardView-1中删除“从底部到超级视图”约束
我们得到这个:
让我们重复这些步骤以获取更多的卡片视图,每次都限制Leading / Trailing到“容器”,高度100,
通过代码执行此操作只是要记住,每个CardView的顶部都应约束到
previous
CardView的底部-除了[[first卡之外,您必须将其约束到顶部“ container”和last卡,将其约束到“ container”的底部。全部通过自动布局完成。无需执行任何“计算高度并设置框架”代码。作为旁注,您可以使用StackView并摆脱其中的大部分:将堆栈视图添加到滚动视图