UIScrollView混合布局方法遇到的问题

问题描述 投票:0回答:1

我正在尝试遵循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()调用它。

感谢任何帮助。

c# ios xamarin.ios ios-autolayout
1个回答
0
投票

滚动视图需要定义其框架它需要定义其内容。如果内容受到限制,则滚动是自动的。

我将逐步进行此操作-使用Storyboard,以便我们可以看到发生了什么。通过代码执行此操作绝对没有区别。

[从视图控制器开始,添加滚动视图,并将其约束到所有四个侧面(我给它提供了绿色背景,以便我们可以看到它:]]

enter image description here

现在我们添加一个“容器”视图(青色背景,并将所有4面约束到滚动视图中:

enter image description here

如果运行此命令,我们将看到:

enter image description here

这是因为“容器”没有宽度或高度。它的前导/尾随/顶部/底部约束定义了滚动视图的content

因此,我们将其等于宽度和高度等于滚动视图:

enter image description here

运行它,我们看到了:

enter image description here

这很好,除了...它将永远不会滚动,因为它与滚动视图的高度相同。

所以,我删除等高-因为我要容器的content确定其高度。

我添加了一个“ CardView”,并将其“顶部” /“前导” /“尾随”约束设置为“容器”的“顶部” /“前导/尾随”约束,并具有10点“填充”和100的高度。我还为其设置了“底部约束” “容器”的底部(+10)-将“拉出容器的底部”至CardView底部下方最多10点:

enter image description here

导致:

enter image description here

现在我添加第二个CardView,将Leading / Trailing约束约束到容器的Leading / trailing,具有10点“填充”和100的高度。然后将其Top约束设置为CardView-1的底部(+10 ),并将其底部限制为“容器”的底部(+10):

enter image description here

[不幸的是,我们现在从CardView-1的底部获得了10点约束。[[从CardView-2的底部得到了10点约束,这当然是行不通的。] >因此,让我们从CardView-1中删除“从底部到超级视图”约束

enter image description here

我们得到这个:

enter image description here

让我们重复这些步骤以获取更多的卡片视图,每次都限制Leading / Trailing到“容器”,高度100,previous

,然后仅限制< [last CardView到“容器”的底部:enter image description here还有耶!我们可以滚动:

enter image description here

通过代码执行此操作只是要记住,每个CardView的顶部都应约束到

previous

CardView的底部-除了[[first卡之外,您必须将其约束到顶部“ container”和last卡,将其约束到“ container”的底部。全部通过自动布局完成。无需执行任何“计算高度并设置框架”代码。作为旁注,您可以使用StackView并摆脱其中的大部分:


忘记“容器”

将堆栈视图添加到滚动视图

  • 轴:垂直,间距:10
  • 使用10点填充将堆栈视图的所有4面约束为滚动视图
    • 给堆栈视图一个宽度约束,该约束等于滚动视图宽度-20(对于每侧10磅填充)
    • 然后,只需将您的CardViews添加为堆栈视图的splittedSubviews。
  • 还有...。完成!
  • © www.soinside.com 2019 - 2024. All rights reserved.