- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是我根据 Apple WWDC 尝试重复但使用自动布局的代码:
extension AugmentedReallityViewController {
@objc func handlePan(recognizer: UIPanGestureRecognizer) {
// // hide languages and units anyway
// moveUnitView(show: false)
// moveLanguageView(show: false)
//
// let isNowExpanded = settingsPanelState == SettingsPanelState.expanded
// let newState = isNowExpanded ? SettingsPanelState.collapsed : SettingsPanelState.expanded
//
// switch recognizer.state {
// case .began:
// startInteractiveTransition(state: newState, duration: 1)
// isLastPanelUpdateToReachTheNewState = true // just in case, but we should change this property later
// case .changed:
// let translation = recognizer.translation(in: viewSettings)
// let fractionComplete = translation.y / viewSettings.frame.size.height
//
// // we will use this property when interaction ends
// if fractionComplete != 0 { // if it's == 0 , we need to use prev data
// isLastPanelUpdateToReachTheNewState = (newState == SettingsPanelState.expanded && fractionComplete < 0) || (newState == SettingsPanelState.collapsed && fractionComplete > 0)
// }
//
// updateInteractiveTransition(fractionComplete: fractionComplete)
// case .ended:
// continueInteractiveTransition(cancel: !isLastPanelUpdateToReachTheNewState)
// default:
// break
// }
}
@objc func handleSettingsTap() {
// hide languages and units anyway
moveUnitView(show: false)
moveLanguageView(show: false)
let isNowExpanded = settingsPanelState == SettingsPanelState.expanded
let newState = isNowExpanded ? SettingsPanelState.collapsed : SettingsPanelState.expanded
animateOrReverseRunningTransition(state: newState, duration: 10)
}
// perform all animations with animators if not already running
private func animateTransitionIfNeeded(state: SettingsPanelState, duration: TimeInterval) {
if runningAnimators.isEmpty {
// // define constraint for frame animation
// // update constraints
// switch state {
// case .expanded:
// constraint_settingsView_bottom.constant = 0
// case .collapsed:
// constraint_settingsView_bottom.constant = -constraint_height_settingViewWhitePart.constant
// }
// animate that
let frameAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear, animations: { [weak self] in
if let strongSelf = self {
// define constraint for frame animation
// update constraints
switch state {
case .expanded:
strongSelf.constraint_settingsView_bottom.constant = 0
case .collapsed:
strongSelf.constraint_settingsView_bottom.constant = -(strongSelf.constraint_height_settingViewWhitePart.constant)
}
}
self?.view.layoutIfNeeded()
})
frameAnimator.startAnimation()
runningAnimators.append(frameAnimator)
frameAnimator.addCompletion({ [weak self] (position) in
if position == UIViewAnimatingPosition.end { // need to remove this animator from array
if let index = self?.runningAnimators.index(of: frameAnimator) {
print("removed animator because of completion")
self?.runningAnimators.remove(at: index)
// we can change state to a new one
self?.settingsPanelState = state
}
else {
print("animator completion with state = \(position)")
}
}
})
}
}
// starts transition if neccessary or reverses it on tap
private func animateOrReverseRunningTransition(state: SettingsPanelState, duration: TimeInterval) {
if runningAnimators.isEmpty { // start transition from start to end
animateTransitionIfNeeded(state: state, duration: duration)
}
else { // reverse all animators
for animator in runningAnimators {
animator.stopAnimation(true)
animator.isReversed = !animator.isReversed
// test
print("tried to reverse")
}
}
}
// called only on pan .begin
// starts transition if neccessary and pauses (on pan .begin)
private func startInteractiveTransition(state: SettingsPanelState, duration: TimeInterval) {
animateTransitionIfNeeded(state: state, duration: duration)
for animator in runningAnimators {
animator.pauseAnimation()
// save progress of any item
progressWhenInterrupted = animator.fractionComplete
}
}
// scrubs transition on pan .changed
private func updateInteractiveTransition(fractionComplete: CGFloat) {
for animator in runningAnimators {
animator.fractionComplete = fractionComplete + progressWhenInterrupted
}
}
// continue or reverse transition on pan .ended
private func continueInteractiveTransition(cancel: Bool) {
for animator in runningAnimators {
// need to continue or reverse
if !cancel {
let timing = UICubicTimingParameters(animationCurve: .easeOut)
animator.continueAnimation(withTimingParameters: timing, durationFactor: 0)
}
else {
animator.isReversed = true
}
}
}
private func addPanGustureRecognizerToSettings() {
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(AugmentedReallityViewController.handlePan(recognizer:)))
// panGestureRecognizer.cancelsTouchesInView = false
viewSettings.addGestureRecognizer(panGestureRecognizer)
}
private func addTapGestureRecognizerToSettings() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(AugmentedReallityViewController.handleSettingsTap))
tapGestureRecognizer.cancelsTouchesInView = false
viewSettingsTopTriangle.addGestureRecognizer(tapGestureRecognizer)
}
}
现在我只是在测试点击手势。有两个主要问题:
1) 点按识别器在动画期间无法正常工作。但在苹果 WWDC 中,他们改变了框架(不像我的情况那样的约束)并且点击识别器工作得很好
2) 如果我改变反向属性,它会改变约束,这真的很糟糕。我还有多余的纸条等等
3) 我尝试了两种方法来在动画 block 之前和内部放置变化的约束。没关系,都是一样的
对如何使用自动布局做到这一点有什么帮助吗?或者至少如何使用框架来做到这一点,但我的 View Controller 是基于自动布局的,所以无论如何我都会对这个底部 View 有限制。
最佳答案
当您为动画使用自动布局时,您可以按如下方式进行:
确保自动布局已完成:
self.view.layoutIfNeeded()
然后在动画 block 之前更改约束。例如:
someConstraint.constant = 0
然后在更改约束后,您告诉自动布局约束已更改:
self.view.setNeedsLayout()
然后您只需调用 layoutIfNeeded()
即可添加一个动画 block :
UIView.animate(withDuration: 1, animations: {
self.view.layoutIfNeeded()
})
当您使用 UIViewPropertyAnimator
时同样适用 - 更改动画 block 中的约束。例如:
self.view.layoutIfNeeded()
someConstraint.constant = 0
self.view.setNeedsLayout()
let animator = UIViewPropertyAnimator(duration: 1, curve: .easeInOut) {
self.view.layoutIfNeeded()
}
animator.startAnimation()
发生这种情况是因为 layoutIfNeeded()
执行实际布局 - 它计算受影响 View 的帧。因此,如果您直接设置帧,则将它们设置在动画 block 中。但是,Autolayout 会为您设置框架 - 因此您需要告诉 autolayout 在动画 block 中设置它们(如果您直接设置它们,就像您所做的那样)。 layoutIfNeeded()
调用正是这样做的 - 它告诉自动布局引擎计算和设置新框架。
关于反转:
虽然我没有足够的经验来 100% 确定,但我预计仅仅将动画师设置为反转是不够的。由于您在开始动画之前应用约束,然后您只需告诉自动布局根据约束更新帧 - 我假设当您反转动画师时,您还需要反转驱动动画的约束。
Animator 只是将 View 动画化为新的框架。但是,无论是否反转,无论您是否反转动画师,新约束仍然有效。因此,在动画师完成后,如果稍后自动布局再次布置 View ,我希望 View 进入当前事件约束设置的位置。简单地说:动画师动画帧变化,但不是约束本身。这意味着反转动画器会反转帧,但不会反转约束 - 只要自动布局执行另一个布局循环,它们就会再次应用。
关于ios - Autolayout 的 UIViewPropertyAnimator 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46588815/
我在 Factory 类中有此代码以返回 UIViewPropertyAnimators 以在何时何地使用: class AnimatorFactory { @discardableResul
当用户点击 UIView 时,我尝试为 UIView 和 imageView 制作动画。这是我的代码: // When the user taps on the featured story imag
我查看了以下 StackOverflow 问题的答案,但似乎没有一个对我有用:在执行完成 block 时,程序没有再次执行动画,而是无限地喷出“完成”广告动画 View 。 How can I rep
帮我弄清楚在这种情况下发生了什么: 假设您有一个具有以下属性的 View Controller @IBOutlet weak var blurView: UIVisualEffectView! var
我有一个带有摄像头的 ViewController,用于录制视频。顶部有一个旋转的圆圈,表示正在录制视频。这是这样设置的: class CameraViewController: UIViewCont
大家好! 我的应用程序有问题。我正在使用 UIViewPropertyAnimator 为我的模糊设置动画。我让模糊效果从 nil (0) 运行到 .light (1),但是因为光效太多了,我将 UI
我弄乱了 UIViewPropertyAnimator 的文档我希望找到一种方法来组合两个 UIViewPropertyAnimator。 像这样: let firstAnimator = UIVie
我有一个运行完美的简单脉冲动画 UIView.animate(withDuration: 1, animations: { myAnimatableView.transform = CGAff
UIViewPropertyAnimator 对于修改 View 的变换、alpha 等非常方便。但是,有时您希望为 CAShapeLayer 路径或 设置动画UIImageView 图像变化。有什么
当 UIViewPropertyAnimator 执行动画过程时如何增加值?当我将对象设置为运动时,我想在它落在屏幕上时增加它的值,但我不确定如何将其与我的动画器链接。有什么建议么?这是我启动的方式
来自苹果文档 pausesoncompletion Because the completion handler is not called when this property is true, y
我正在寻找一种方法来将一些动画添加到 UIViewPropertyAnimator 中,它比其他动画更早完成。UIViewPropertyAnimator 例如有一个方法,您可以在其中添加延迟动画 a
我正在尝试通过屏幕触摸来控制动画 当我触摸屏幕然后 View 的 alpha 变为 0 但是如果在 alpha 变为 0 时再次触摸 然后 alpha 再次变为 1(中断动画使 alpha 值为 0)
我正在使用 UIViewPropertyAnimator 来运行数组交互式动画,我遇到的一个问题是,每当我反转动画时,我都无法再次向前运行动画。 我使用三个函数与平移手势识别器一起处理动画。 priv
使用 UIView.animate: 方法,我们可以配置选项并使其成为 [.autoreverse,.repeat]。 这是一个简单的动画: @IBOutlet weak var v1: UIView
我正在尝试让我的动画让屏幕从黑变白再变黑,并重复一定次数。目前使用我的代码,动画从黑色缓和到白色,然后跳回黑色。无论如何要反向运行动画或添加在第一个动画完成后运行的动画? override func
我没有经常使用 UIViewPropertyAnimator(仍然是一个老式的 block 家伙),我看到了一些我无法解释的行为,而且文档并没有真正提供任何见解上。 为什么即使动画师在启动后立即暂停,
我有一个 UIImageView,它可以拉伸(stretch)屏幕的宽度,我正在为其尾端和前端设置动画以在屏幕中间相遇。它所花费的时间与计时器有关。 我有一个开始按钮,它也可以用作暂停按钮。我可以让动
问题描述 我有一个 UIViewPropertyAnimator 管理模糊等,我只想将它用于它的 fractionComplete 属性。问题是,如果我将 fractionComplete 设置为 1
问题描述 我有一个 UIViewPropertyAnimator 管理模糊等,我只想将它用于它的 fractionComplete 属性。问题是,如果我将 fractionComplete 设置为 1
我是一名优秀的程序员,十分优秀!