Jic*_*ery 7 uiview cabasicanimation uigesturerecognizer swift
我一直在使用UIPanGestureRecognizer来识别触摸,但我想用动画的固定开始到结束位置替换它.请参阅以下代码:
panGestureDidMove:
func panGestureDidMove(gesture: UIPanGestureRecognizer) {
if gesture.state == .Ended || gesture.state == .Failed || gesture.state == .Cancelled {
} else {
let additionalHeight = max(gesture.translationInView(view).y, 0)
let waveHeight = min(additionalHeight * 0.6, maxWaveHeight)
let baseHeight = minimalHeight + additionalHeight - waveHeight
let locationX = gesture.locationInView(gesture.view).x
layoutControlPoints(baseHeight: baseHeight, waveHeight: waveHeight, locationX: locationX)
updateShapeLayer()
}
}
Run Code Online (Sandbox Code Playgroud)
layoutControlPoints:
private func layoutControlPoints(baseHeight baseHeight: CGFloat, waveHeight: CGFloat, locationX: CGFloat) {
let width = view.bounds.width
let minLeftX = min((locationX - width / 2.0) * 0.28, 0.0)
let maxRightX = max(width + (locationX - width / 2.0) * 0.28, width)
let leftPartWidth = locationX - minLeftX
let rightPartWidth = maxRightX - locationX
l3ControlPointView.center = CGPoint(x: minLeftX, y: baseHeight)
l2ControlPointView.center = CGPoint(x: minLeftX + leftPartWidth * 0.44, y: baseHeight)
l1ControlPointView.center = CGPoint(x: minLeftX + leftPartWidth * 0.71, y: baseHeight + waveHeight * 0.64)
cControlPointView.center = CGPoint(x: locationX , y: baseHeight + waveHeight * 1.36)
r1ControlPointView.center = CGPoint(x: maxRightX - rightPartWidth * 0.71, y: baseHeight + waveHeight * 0.64)
r2ControlPointView.center = CGPoint(x: maxRightX - (rightPartWidth * 0.44), y: baseHeight)
r3ControlPointView.center = CGPoint(x: maxRightX, y: baseHeight)
}
Run Code Online (Sandbox Code Playgroud)
我试图替换 panGestureDidMove CABasicAnimation来设置起始位置的动画,如下面的代码:
let startValue = CGPointMake(70.0, 50.0)
let endValue = CGPointMake(90.0, 150.0)
CATransaction.setDisableActions(true) //Not necessary
view.layer.bounds.size.height = endValue
let positionAnimation = CABasicAnimation(keyPath:"bounds.size.height")
positionAnimation.fromValue = startValue
positionAnimation.toValue = endValue
positionAnimation.duration = 2.0
view.layer.addAnimation(positionAnimation, forKey: "bounds")
Run Code Online (Sandbox Code Playgroud)
随着职位的变化,很多事情都会受到影响,我该怎样才能做到这一点?
如果您想要精细控制动画,您可以CADisplayLink在屏幕像素刷新之前进行任何自定义布局或绘图。运行循环尝试每秒绘制 60 帧,因此考虑到这一点,您可以修改代码来模拟触摸事件。
您需要添加一些属性:
var displayLink:CADisplayLink? // let's us tap into the drawing run loop
var startTime:NSDate? // while let us keep track of how long we've been animating
var deltaX:CGFloat = 0.0 // how much we should update in the x direction between frames
var deltaY:CGFloat = 0.0 // same but in the y direction
var startValue = CGPointMake(70.0, 50.0) // where we want our touch simulation to start
var currentPoint = CGPoint(x:0.0, y:0.0)
let endValue = CGPointMake(90.0, 150.0) // where we want our touch simulation to end
Run Code Online (Sandbox Code Playgroud)
然后每当我们想要动画运行时我们可以调用:
func animate()
{
let duration:CGFloat = 2.0
self.currentPoint = self.startValue
self.deltaX = (endValue.x - startValue.x) / (duration * 60.0) // 60 frames per second so getting the difference then dividing by the duration in seconds times 60
self.deltaY = (endValue.y - startValue.y) / (duration * 60.0)
self.startTime = NSDate()
self.displayLink = CADisplayLink(target: self, selector: #selector(self.performAnimation))
self.displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
}
Run Code Online (Sandbox Code Playgroud)
这将设置显示链接并确定触摸模拟应在帧之间移动多少,并开始调用在每次绘制屏幕之前调用的函数performAnimation:
func performAnimation(){
if self.startTime?.timeIntervalSinceNow > -2 {
self.updateViewsFor(self.currentPoint, translation: CGPoint(x:self.currentPoint.x - self.startValue.x, y: self.currentPoint.y - self.startValue.y))
self.currentPoint.x += self.deltaX
self.currentPoint.y += self.deltaY
}
else
{
self.displayLink?.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
self.currentPoint = self.startValue
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我们检查是否在动画的持续时间内。然后调用updateViewsFor(point:CGPoint,translation:CGPoint)您的手势目标中的内容,然后更新我们的触摸模拟(如果我们在其中),否则我们只需重置我们的属性。
最后,
func updateViewsFor(point:CGPoint,translation:CGPoint)
{
let additionalHeight = max(translation.y, 0)
let waveHeight = min(additionalHeight * 0.6, maxWaveHeight)
let baseHeight = minimalHeight + additionalHeight - waveHeight
let locationX = point.x
layoutControlPoints(baseHeight: baseHeight, waveHeight: waveHeight, locationX: locationX)
updateShapeLayer()
}
Run Code Online (Sandbox Code Playgroud)
您还可以将您的更改panGestureDidMove为:
@objc func panGestureDidMove(gesture: UIPanGestureRecognizer) {
if gesture.state == .Ended || gesture.state == .Failed || gesture.state == .Cancelled {
} else {
self.updateViewsFor(gesture.locationInView(gesture.view), translation: gesture.translationInView(view))
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
有一种更简单的方法可以使用关键帧动画来完成此操作。但我不确定它会让你的updateShapeLayer(). 但对于动画视图,我们可以编写如下函数:
func animate(fromPoint:CGPoint, toPoint:CGPoint, duration:NSTimeInterval)
{
// Essentually simulates the beginning of a touch event at our start point and the touch hasn't moved so tranlation is zero
self.updateViewsFor(fromPoint, translation: CGPointZero)
// Create our keyframe animation using UIView animation blocks
UIView.animateKeyframesWithDuration(duration, delay: 0.0, options: .CalculationModeLinear, animations: {
// We really only have one keyframe which is the end. We want everything in between animated.
// So start time zero and relativeDuration 1.0 because we want it to be 100% of the animation
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 1.0, animations: {
// we want our "touch" to move to the endValue and the translation will just be the difference between end point and start point in the x and y direction.
self.updateViewsFor(toPoint, translation: CGPoint(x: toPoint.x - fromPoint.x, y: toPoint.y - fromPoint.y))
})
}, completion: { _ in
// do anything you need done after the animation
})
}
Run Code Online (Sandbox Code Playgroud)
这会将视图移动到位,然后为视图结束的位置创建一个关键帧,并对中间的所有内容进行动画处理。我们可以这样称呼它:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.animate(CGPointMake(70.0, 50.0), toPoint: CGPointMake(90.0, 150.0), duration: 2.0)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
164 次 |
| 最近记录: |