UIScrollView 中的自动布局使用 Cirrious.FluentLayouts.Touch
Posted
技术标签:
【中文标题】UIScrollView 中的自动布局使用 Cirrious.FluentLayouts.Touch【英文标题】:Autolayouts in UIScrollView using Cirrious.FluentLayouts.Touch 【发布时间】:2015-05-21 14:57:02 【问题描述】:我要在scrollView中做一个带有自动布局的ViewController,但这里有几个问题:
public SomeVC() : UIViewController
_mainScrollView = new UIScrollView
ShowsHorizontalScrollIndicator = false,
ShowsVerticalScrollIndicator = true,
BackgroundColor = UIColor.Clear,
ScrollEnabled = true,
AutoresizingMask = UIViewAutoresizing.FlexibleHeight,
TranslatesAutoresizingMaskIntoConstraints = true
;
_userDataTableView = new UITableView(CGRect.Empty, UITableViewStyle.Grouped);
_userDataTableView.LayoutIfNeeded();
_saveButton = new UIButton();
_menuTableView = new UITableView(CGRect.Empty, UITableViewStyle.Grouped);
_menuTableView.LayoutIfNeeded();
_logoutButton = new UIButton();
public override void LoadView()
base.LoadView();
View = _mainScrollView;
public override void ViewDidLoad()
base.ViewDidLoad();
Add(_userDataTableView);
Add(_saveButton);
Add(_menuTableView);
Add(_logoutButton);
_mainScrollView.AddConstraints(
_userDataTableView.AtTopOf(View),
_userDataTableView.AtLeftOf(View),
_userDataTableView.AtRightOf(View),
_userDataTableView.Height().EqualTo(_userDataTableView.ContentSize.Height),
_saveButton.Below(_userDataTableView, 20),
_saveButton.AtLeftOf(_mainScrollView, 10),
_saveButton.AtRightOf(_mainScrollView, 10),
_saveButton.Height().EqualTo(44),
_menuTableView.Below(_saveButton, 20),
_menuTableView.AtLeftOf(_mainScrollView),
_menuTableView.AtRightOf(_mainScrollView),
_menuTableView.Height().EqualTo(_menuTableView.ContentSize.Height),
_logoutButton.Below(_menuTableView, 20),
_logoutButton.AtLeftOf(_mainScrollView, 10),
_logoutButton.AtRightOf(_mainScrollView, 10),
_logoutButton.Height().EqualTo(44)
);
_mainScrollView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
事实上,它可以工作,但是内容宽度大约是屏幕宽度的一半,并且滚动不起作用。如何让它工作?
据我了解,问题是 - _mainScrollView.ContentSize,但是在使用自动布局时我应该如何以及在哪里设置它?
【问题讨论】:
【参考方案1】:如果您的视图没有超出屏幕,您将无法进行滚动。如果你只有这样的东西:
// Create containers
contentView = new UIView();
scrollView = new UIScrollView contentView ;
Add(scrollView);
contentView.AddSubviews(logo, user, password, loginButton);
// Auto layout
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
View.AddConstraints(scrollView.FullWidthOf(View));
View.AddConstraints(scrollView.FullHeightOf(View));
View.AddConstraints(
contentView.WithSameWidth(View),
contentView.WithSameHeight(View).SetPriority(UILayoutPriority.DefaultLow)
);
scrollView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
scrollView.AddConstraints(contentView.FullWidthOf(scrollView));
scrollView.AddConstraints(contentView.FullHeightOf(scrollView));
// very important to make scrolling work
var bottomViewConstraint = contentView.Subviews.Last()
.AtBottomOf(contentView).Minus(20);
contentView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
contentView.AddConstraints(
logo.AtTopOf(contentView),
logo.WithRelativeWidth(contentView, 0.8f),
logo.WithSameCenterX(contentView),
logo.WithRelativeHeight(contentView, 0.3f),
user.Below(logo, 50),
user.WithRelativeWidth(logo, 0.8f),
user.WithSameCenterX(logo),
password.Below(user),
password.WithSameWidth(user),
password.WithSameCenterX(user),
loginButton.Below(password, 50),
loginButton.WithRelativeWidth(password, 0.9f),
loginButton.Height().EqualTo(50),
loginButton.WithSameCenterX(password)
);
contentView.AddConstraints(bottomViewConstraint);
我正在使用这个包,它的工作原理就像我在 xamarin.forms 的滚动视图中使用 stackLayout 一样,我认为这是完美的行为。
Xamarin.IQKeyboardManager from Nuget
另外,如果你想在滚动视图中居中你的内容视图,你需要添加这个:
public override void ViewWillLayoutSubviews()
base.ViewWillLayoutSubviews();
var scrollViewBounds = scrollView.Bounds;
var containerViewBounds = contentView.Bounds;
var scrollViewInsets = UIEdgeInsets.Zero;
scrollViewInsets.Top = scrollViewBounds.Size.Height / 2.0f;
scrollViewInsets.Top -= contentView.Bounds.Size.Height / 2.0f;
scrollViewInsets.Bottom = scrollViewBounds.Size.Height / 2.0f;
scrollViewInsets.Bottom -= contentView.Bounds.Size.Height / 2.0f;
scrollViewInsets.Bottom += 1;
scrollView.ContentInset = scrollViewInsets;
仅此而已,无论您的 contentView 是怎样的。您将在滚动视图中拥有一个居中的 contetnview 和一个管理器来捕获键盘事件并使您的视图适应此事件。
【讨论】:
只有在 scrollView.Bounds.Size.Height 小于 contentView.Bounds.Size.Height 时,您的 ViewWillLayoutSubviews 代码才应该执行【参考方案2】:找到的解决方案: 首先:
_userDataTableView.AtLeftOf(View),
_userDataTableView.AtRightOf(View),
无效,我们应该使用:
_userDataTableView.AtLeftOf(View),
_userDataTableView.WithSameWidth(View),
如果我们想要边距,我们只需添加
_userDataTableView.WithSameWidth(View).Minus(MARGIN)
我们要做的最后一件事是:
_logoutButton.Height().EqualTo(44),
_logoutButton.Bottom().EqualTo().BottomOf(_mainScrollView).Plus(10)
最后一行非常重要。它说要滚动查看正确的内容大小。
【讨论】:
那么如果一个 Scrollview 有 10 个子视图,我如何让它滚动呢?我只是将 10 个子视图从顶部放在另一个子视图的下方,而不设置相对于底部的约束?以上是关于UIScrollView 中的自动布局使用 Cirrious.FluentLayouts.Touch的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollView 中的自动布局使用 Cirrious.FluentLayouts.Touch
UIScrollView 中的 UITextView 使用自动布局