我在XIB中为我的入职制作了UIScrollView
。 UIScrollView
有3个入职观点。长话短说:
这很完美。但是,当屏幕上显示第三页/最后一页时,我希望左上和右上按钮(Overslaan - Volgende)为屏幕设置动画。当我关闭按钮动画时,我的UIScrollView开始表现得很奇怪:
这是我使用的代码:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let pageIndex = Int(targetContentOffset.pointee.x / self.frame.width)
pageControl.currentPage = pageIndex
if stepViews[pageIndex] is OnboardingLoginView {
moveControlConstraintsOffScreen()
} else {
moveControlConstraintsOnScreen()
}
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
}
我调试了代码,事实证明,无论动画块如何,为约束设置新常量都会导致问题。如何在没有我的scrollView表现奇怪的情况下使按钮向上/向下移动屏幕?
答案 0 :(得分:1)
看起来触发布局传递会干扰滚动视图定位。您可以实现func scrollViewDidScroll(_ scrollView: UIScrollView)
并尝试在每帧的基础上更新按钮视图,而不更改自动布局约束。我通常使用transform
属性进行自动布局之外的帧更改,因为在下一次布局过程中,frame
或bounds
的任何更改都会被覆盖。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard mustBeOnLastPage else {
buttonOne.tranform = .identity
buttonTwo.tranform = .identity
return
}
let offset = scrollView.contentOffset.x
buttonOne.tranform = .init(translationX: 0, y: offset)
buttonTwo.tranform = .init(translationX: 0, y: offset)
}
旧答案
这种解释与你所要求的有些相似。
因为看起来你在分页上下文中使用滚动视图,我会通过使用UIPageViewController来解决这个问题。由于UIPageViewController在内部使用UIScrollView,因此您可以观察滚动视图中最后一个视图的contentOffset,以确定页面滚动的距离。 是的,这涉及到查看视图层次结构,但Apple已经改变了五年,所以你应该保持安全。巧合的是,我上周实际上采用了这种方法,它就像一个魅力。 如果您有兴趣,我可以进一步扩展这个主题。可以找到指向正确方向的帖子here。
答案 1 :(得分:1)
这是我做的事情
我无法发布图片,您可以查看此http://i.imgur.com/U7FHoMu.gif
这是代码
var centerYConstraint: Constraint!
func setupConstraint() {
fadeView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
centerYConstraint = make.centerY.equalToSuperview().constraint
make.size.equalTo(CGSize(width: 50, height: 50))
}
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint,targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let pageIndex = Int(targetContentOffset.pointee.x / self.view.frame.width)
if pageIndex != 1 {
centerYConstraint.update(offset: self.view.frame.height)
} else {
centerYConstraint.update(offset: 0)
}
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
答案 2 :(得分:0)
根据@ CloakedEddy的回答,我做了两处修改:
1:似乎layoutSubviews负责奇怪的行为。为了解决这个问题,我阻止scrollView始终调用layoutSubviews:
override func layoutSubviews() {
super.layoutSubviews()
if !didLayoutSubviews {
for index in 0..<stepViews.count {
let page: UIView = stepViews[index]
let xPosition = scrollView.frame.width * CGFloat(index)
page.frame = CGRect(x: xPosition, y: 0, width: scrollView.bounds.width, height: scrollView.frame.height)
scrollView.contentSize.width = scrollView.frame.width * CGFloat(index + 1)
}
didLayoutSubviews = true
}
}
2:如果您要更新设备方向的视图:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
onboardingView.didLayoutSubviews = false
onboardingView.setNeedsLayout()
}