gpt4 book ai didi

ios - UILayoutViewController中的滚动时自动布局约束“消失”

转载 作者:行者123 更新时间:2023-12-01 21:55:24 27 4
gpt4 key购买 nike

我正在尝试使用自动布局使用“浮动”标题构建滚动视图。更确切地说,我正在尝试建立包含几列的日历视图。这些列中的每个列都应具有自己的标题,该标题应浮动在顶部,而该列可以垂直滚动到其下方。

如果一切正常,则如下所示:

如您所见,有几列和一个页面控件,用于指示可用的页面数。

但是,在滑动/平移(或什至只是尝试滑动)以切换到下一页时,保留标题标签在顶部的约束将被删除,并且它们将消失到滚动视图的顶部(在情节提要中)。

由于列标题在屏幕外滚动,因此看不到列标题

列标题位于滚动视图的顶部(高度错误)。

建立

用户可以在日期之间进行切换(顶部带有左右箭头的“今天”按钮),并可以在显示的人员之间进行切换。 (滑动/平移查看)
Boh交互是通过彼此内部的UIPageViewController实现的。外页视图控制器在日期之间切换,内页控制器在列的页面之间(带有人)切换。
时间视图包含在外部页面视图控制器中,而不包含在内部页面视图控制器中。

因此,视图和控制器的层次结构如下所示:

Calendar PageViewController (the one controlled via buttons in the navigation bar)
-- Scroll View of Page View Controller
---- Team View Controller (with view)
------ Header View reference (see screenshot 2)
------ Scroll View for vertical scrolling
-------- Time View (the one on the left)
-------- People PageViewController (the one controlled by swiping left/right)
---------- ScrollView of Page View Controller
------------ ViewController for a Single Page (with view)
--------------(1-n) Container View Controller (several of those, in the example 4 per page)
---------------- Column View Controller
------------------ Header View (A UIVisualEffectsView with a label)
------------------ calendar column view (the one doing the horizontal stripes)

将各个列视图控制器的标题视图两个固定在顶部,我在内部页面视图控制器外部和垂直滚动视图外部使用了一个参考视图。我在上面的概述中将其称为 Header View reference,您可以在残破的示例中很好地看到它:

这是一个简单的UIVisualEffectsView,我将其限制在左上角,并且高度和宽度与时间视图相同。因此,此视图具有正确的位置和高度,我希望所有标题视图都具有正确的位置和高度,并使用它在每个 updateViewConstraintsColumViewController方法的代码中将各个列标题视图约束到代码中(所有其他约束都在情节提要中设置),例如所以:
- (void)updateViewConstraints
{
DDLogDebug(@"updating view constraints in colum view controller for %@", self.employee.displayName);
UIView *baseView = self.headerViewReferenceContainer.viewForHeaderContainerViewConstraints;
UIView *containerReference = self.headerViewReferenceContainer.headerContainerViewReference;
NSParameterAssert([containerReference isDescendantOfView:baseView] && [self.headerContainerView isDescendantOfView:baseView]);
[baseView addConstraint:[NSLayoutConstraint constraintWithItem:self.headerContainerView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:containerReference
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0]];

[baseView addConstraint:[NSLayoutConstraint constraintWithItem:self.headerContainerView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:containerReference
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0]];

[super updateViewConstraints];
}
baseView是应在其中添加约束的视图。它必须是标题视图视图和列视图控制器的标题视图的 super 视图。目前,这将是上面 Team View Controller的视图(包含垂直滚动视图的视图)。
containerReference是“标题视图参考”视图,如上面的屏幕快照所示。

因此,我将列标题视图限制为与参考视图具有相同的顶部位置和高度。 (宽度和x位置取决于列)

正如您在破碎的屏幕截图中所看到的那样,Header View参考始终处于正确位置。另外,在加载视图控制器和那里的视图时,约束已正确设置。

然后,当开始平移手势以切换PeoplePageView Controller的页面并加载下一个 ViewController for a Single Page时,约束将以某种方式消失,并且标题视图由于不再固定在顶部而移至滚动视图的顶部。

下一个 View Controller for a Single Page具有正确设置的约束,但是直到它卡入到位。

因此,在平移时,正确设置了视图控制器要显示的约束。但是,只要它卡入到位(感觉就像在 -viewDidAppear上发生的那样),约束也会被删除。

我不明白为什么以及如何删除约束。

什么没错/我尝试了什么

这可能是由于其中一种相关的观点消失了,但是
  • ,它是分页滚动视图
  • 的 super 视图,所以 baseView在向左向右滑动时完全没有改变
  • 标题引用视图未更改,因为它不包含在分页页面视图控制器中。
  • 在视图控制器完全脱离屏幕之前,标题列视图不会消失,因此在分页
  • 期间布局不应中断

    我曾经遇到过这样的问题,即布局仅在分页完成之后才落入适当位置。这是由于我的约束与 iOS 8 UIPageViewController Applying Constraints After Transitions中描述的顶部布局约束有关。
    结果,我使用了到 super 视图顶部的固定距离来固定 Header View Reference,而不是将其固定到顶部布局约束。

    因此,UIPageViewController的错误在分页上没有正确的顶部布局约束也不应该成为问题。

    我没有以编程方式添加任何视图。我所有使用自动布局的情节提要板和视图控制器都是通过情节提要中的Container View Controllers相互添加的,或者实现 UIPageViewControllerDatasource并从xib实例化视图控制器。因此,应该没有与 translatesAutoResizingMasks相关的任何问题。另外,它在加载时有效,仅在分页时中断,这不适合通常的 translatesAutoResizingMasks = YES问题。

    我也没有收到关于冲突约束的任何错误,或者没有为约束准备视图层次,只是删除了工作约束。

    我有一个我认为不相关的问题,但是出于完整性考虑,我将在这里列出:由于内的标签的布局约束,早期出现了列标题视图,因此出现错误:
    The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7af4df20 UILabel:0x7af4e0d0'Susanne'.width == UIVisualEffectView:0x7af4de70.width>
    When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.

    但是,该消息抱怨标签及其包含的视图(列的标题视图)之间的关系,而不是标题视图的“外部”约束。此外,它警告说,如果过早解决约束,应用程序将崩溃。该应用程序不会崩溃,因此时机似乎正确。另外,应用程序抱怨的约束条件是在情节提要中设置的,因此我看不到如何弄错时间。

    tl; dr:从UIPageViewController内部到视图外部的视图层次结构的多个层次的约束都将被删除(没有警告,注释,原因或其他任何东西)。
    我不明白为什么以及如何防止这种情况发生,或者在什么时候再次添加它们。

    更新:

    我在 viewWillAppear:中添加了以下调用:
    [self.view setNeedsUpdateConstraints]

    这具有以下效果:
  • 将页面稍微拖到一边(不切换分页)并再次释放它(以使其回弹)时,再次修复了损坏的约束(并且布局是固定的)。这是由于页面视图控制器“回跳”(以抵消先前发出的viewWillAppear:调用)在原始视图控制器上调用viewWillDisappear所致。
  • 但在滚动过程中,布局仍然损坏。
  • 同样,当滑动到新页面时,新页面的约束也会被破坏。
  • 但是,每当调用viewWillAppear时,约束都会在短时间内固定,直到再次将其删除(通常在滚动结束时)。

  • 如果我将相同的调用添加到 viewDidAppear 而不是 viewWillAppear,则会发生以下情况:
  • 这导致布局在大多数情况下都是正确的(滚动结束后它们是固定的)。
  • 但是在滚动过程中它仍然损坏。

  • 现在,如果我将 [self.view setNeedsUpdateConstraints]添加到这两种方法中,则会发生以下情况:
  • 布局几乎所有时间都正常运行,视图中没有奇怪的跳转
  • 除了以外,首页均未更改。在此期间,原始页面的约束似乎已被删除,并且布局以上面显示的方式破坏了。在那之后,约束似乎被永久性地固定了,来回滑动作品没有问题。
  • 当我确定页面视图控制器不会将所有三个页面都保留在内存中时,这甚至适用于三页(我也尝试了四页)并分页到最后一页(并试图超越它) 。
  • 最佳答案

    是否有可能不止一次调用updateViewConstraints导致多次添加相同约束的问题,这又导致了问题。我相信这很容易发生。

    我在许多讨论中注意到,许多人似乎建议不要在此函数中创建和添加(viewDidLoad似乎是首选),并且仅在此函数中进行约束值设置以最大程度地减少多次调用的问题,但要确保大小正确。另一个选择似乎是在约束添加周围放置控制器的布尔值保护,以确保它在控制器的生存期内仅发生一次。

    可能不是您的问题,但值得一提。

    关于ios - UILayoutViewController中的滚动时自动布局约束“消失”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28698769/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com