UIKit框架(二) —— UIKit动力学和移动效果(二)

版本记录

版本号 时间
V1.0 2018.08.05

前言

iOS中有关视图控件用户能看到的都在UIKit框架里面,用户交互也是通过UIKit进行的,这一篇就看一下UIKit动力学和移动效果。感兴趣的参考上面几篇文章。
1. UIKit框架(一) —— UIKit动力学和移动效果(一)

Invisible boundaries and collisions - 不可见的边界和碰撞

将碰撞行为初始化更改回其原始形式,也就是只对那个正放心的有作用:

Swift版本

collision = UICollisionBehavior(items: [square])

在此行之后,立即添加以下内容:

// add a boundary that has the same frame as the barrier
collision.addBoundaryWithIdentifier("barrier", forPath: UIBezierPath(rect: barrier.frame))

OC版本

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.dynamicView]];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.barrierView.frame];
[collision addBoundaryWithIdentifier:@"barrier" forPath:path];

上面的代码添加了一个不可见的边界,它与障碍视图具有相同的frame。 红色屏障对用户仍然可见,但对动态引擎不可见,由于边界对动态引擎可见,但对用户不可见。 随着正方形视图的下降,它就与障碍物相互作用,但它实际上撞击了不可移动的边界。

下面我们重新修改下barrier的约束,如下所示:

运行代码可见如下效果:

方形视图现在从边界反弹,旋转一点,然后继续向屏幕底部运动。

到目前为止,UIKit Dynamics的强大功能正在变得非常明确:只需几行代码就可以完成很多工作。 引擎盖下发生了很多事情;下面部分将向您展示动态引擎如何与应用中的对象进行交互的一些细节。


Behind the scenes of collisions - 在碰撞的幕后

每个动态行为都有一个action属性,您可以在其中提供要在动画的每个步骤中执行的块。 将以下代码添加到viewDidLoad:

Swift版本

collision.action = {
  println("\(NSStringFromCGAffineTransform(square.transform)) \(NSStringFromCGPoint(square.center))")
}

上面的代码记录了下降方块视图的中心和变换属性。 Build并运行您的应用程序,您将在Xcode控制台窗口中看到这些日志消息。

对于前〜400毫秒,您应该看到如下所示的日志消息:

[1, 0, 0, 1, 0, 0], {150, 236}
[1, 0, 0, 1, 0, 0], {150, 243}
[1, 0, 0, 1, 0, 0], {150, 250}

在这里,您可以看到动态引擎正在改变方形的中心 - 即每个动画步骤中的frame。

一旦方块撞到屏障,它就会开始旋转,从而产生如下消息:

[0.99797821, 0.063557133, -0.063557133, 0.99797821, 0, 0] {152, 247}
[0.99192101, 0.12685727, -0.12685727, 0.99192101, 0, 0] {154, 244}
[0.97873402, 0.20513339, -0.20513339, 0.97873402, 0, 0] {157, 241}

在这里,您可以看到动态引擎正在使用变换和帧偏移的组合来根据基础物理模型定位视图。

OC版本

collision.action = ^{
    NSLog(@"%@--%@", NSStringFromCGAffineTransform(self.dynamicView.transform), NSStringFromCGPoint(self.dynamicView.center));
};

下面看一下输出结果

2018-08-05 15:09:45.801516+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 120}
2018-08-05 15:09:45.806114+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 121}
2018-08-05 15:09:45.825243+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 122}
2018-08-05 15:09:45.837939+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 123}
2018-08-05 15:09:45.854657+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 125}
2018-08-05 15:09:45.874589+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 126}
2018-08-05 15:09:45.890322+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 128}
2018-08-05 15:09:45.906109+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 131}
2018-08-05 15:09:45.921364+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 133}
2018-08-05 15:09:45.938558+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 136}
2018-08-05 15:09:46.085647+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 168}
2018-08-05 15:09:46.088024+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 174}
2018-08-05 15:09:46.104674+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 179}
2018-08-05 15:09:46.121365+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 185}
2018-08-05 15:09:46.138057+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 191}
2018-08-05 15:09:46.154729+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 197}
2018-08-05 15:09:46.171396+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 204}
2018-08-05 15:09:46.188074+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 211}
2018-08-05 15:09:46.204805+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 218}
2018-08-05 15:09:46.221432+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 225}
2018-08-05 15:09:46.238041+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 233}
2018-08-05 15:09:46.254805+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 241}
2018-08-05 15:09:46.271686+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 249}
2018-08-05 15:09:46.288085+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 258}
2018-08-05 15:09:46.304718+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 266}
2018-08-05 15:09:46.321378+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 275}
2018-08-05 15:09:46.338054+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 284}
2018-08-05 15:09:46.354709+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 294}
2018-08-05 15:09:46.371506+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 304}
2018-08-05 15:09:46.388231+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 314}
2018-08-05 15:09:46.405078+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 324}
2018-08-05 15:09:46.421429+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 335}
2018-08-05 15:09:46.438066+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 345}
2018-08-05 15:09:46.454790+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 356}
2018-08-05 15:09:46.471348+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 368}
2018-08-05 15:09:46.488277+0800 JJDynamics[13854:6043679] [1, 0, 0, 1, 0, 0]--{187, 379}
2018-08-05 15:09:46.505091+0800 JJDynamics[13854:6043679] [0.99999032001561705, 0.0043999858026804103, -0.0043999858026804103, 0.99999032001561705, 0, 0]--{187, 391}
2018-08-05 15:09:46.521487+0800 JJDynamics[13854:6043679] [0.99670509099572935, 0.081110798191084202, -0.081110798191084202, 0.99670509099572935, 0, 0]--{190, 390}
2018-08-05 15:09:46.538197+0800 JJDynamics[13854:6043679] [0.98757539405837946, 0.15714592279291401, -0.15714592279291401, 0.98757539405837946, 0, 0]--{192, 390}
2018-08-05 15:09:46.554757+0800 JJDynamics[13854:6043679] [0.97270030449661105, 0.23206489961258717, -0.23206489961258717, 0.97270030449661105, 0, 0]--{195, 389}
2018-08-05 15:09:46.571451+0800 JJDynamics[13854:6043679] [0.95215036329479197, 0.30562998164053801, -0.30562998164053801, 0.95215036329479197, 0, 0]--{197, 390}
2018-08-05 15:09:46.588097+0800 JJDynamics[13854:6043679] [0.92604546130418763, 0.37741198125909348, -0.37741198125909348, 0.92604546130418763, 0, 0]--{200, 390}
2018-08-05 15:09:46.604798+0800 JJDynamics[13854:6043679] [0.89471662296917953, 0.44663426266087891, -0.44663426266087891, 0.89471662296917953, 0, 0]--{202, 391}
2018-08-05 15:09:46.621871+0800 JJDynamics[13854:6043679] [0.85822238841548293, 0.51327802604672634, -0.51327802604672634, 0.85822238841548293, 0, 0]--{205, 392}
2018-08-05 15:09:46.638148+0800 JJDynamics[13854:6043679] [0.81677344690082287, 0.57695852228539679, -0.57695852228539679, 0.81677344690082287, 0, 0]--{207, 393}
2018-08-05 15:09:46.654829+0800 JJDynamics[13854:6043679] [0.77073653850693524, 0.63715397527626516, -0.63715397527626516, 0.77073653850693524, 0, 0]--{210, 395}
2018-08-05 15:09:46.671455+0800 JJDynamics[13854:6043679] [0.72041209900074288, 0.69354625484775256, -0.69354625484775256, 0.72041209900074288, 0, 0]--{212, 397}
2018-08-05 15:09:46.688130+0800 JJDynamics[13854:6043679] [0.66612138765966766, 0.74584334608707126, -0.74584334608707126, 0.66612138765966766, 0, 0]--{215, 399}
2018-08-05 15:09:46.704924+0800 JJDynamics[13854:6043679] [0.60804546345526223, 0.79390220705794445, -0.79390220705794445, 0.60804546345526223, 0, 0]--{217, 401}
2018-08-05 15:09:46.721482+0800 JJDynamics[13854:6043679] [0.54668181993310971, 0.83734042524807251, -0.83734042524807251, 0.54668181993310971, 0, 0]--{220, 404}
2018-08-05 15:09:46.738822+0800 JJDynamics[13854:6043679] [0.48222812546060806, 0.87604568089497936, -0.87604568089497936, 0.48222812546060806, 0, 0]--{222, 407}
2018-08-05 15:09:46.754871+0800 JJDynamics[13854:6043679] [0.41523064806151799, 0.90971616942341516, -0.90971616942341516, 0.41523064806151799, 0, 0]--{225, 410}
2018-08-05 15:09:46.771468+0800 JJDynamics[13854:6043679] [0.34608624036957419, 0.93820270423126217, -0.93820270423126217, 0.34608624036957419, 0, 0]--{227, 413}
2018-08-05 15:09:46.788139+0800 JJDynamics[13854:6043679] [0.27500636898821867, 0.96144240441948248, -0.96144240441948248, 0.27500636898821867, 0, 0]--{230, 417}
2018-08-05 15:09:46.804831+0800 JJDynamics[13854:6043679] [0.20258440026074659, 0.97926480625568979, -0.97926480625568979, 0.20258440026074659, 0, 0]--{232, 421}
2018-08-05 15:09:46.821495+0800 JJDynamics[13854:6043679] [0.12903553968889034, 0.99163996969525026, -0.99163996969525026, 0.12903553968889034, 0, 0]--{235, 426}
2018-08-05 15:09:46.838145+0800 JJDynamics[13854:6043679] [0.054968607375915829, 0.99848808315530357, -0.99848808315530357, 0.054968607375915829, 0, 0]--{237, 430}
2018-08-05 15:09:46.854825+0800 JJDynamics[13854:6043679] [-0.019202492901692646, 0.99981561513429085, -0.99981561513429085, -0.019202492901692646, 0, 0]--{240, 435}
2018-08-05 15:09:46.871553+0800 JJDynamics[13854:6043679] [-0.093267919662992665, 0.99564104734675218, -0.99564104734675218, -0.093267919662992665, 0, 0]--{242, 440}
2018-08-05 15:09:46.888131+0800 JJDynamics[13854:6043679] [-0.16662288158149985, 0.98602069721354102, -0.98602069721354102, -0.16662288158149985, 0, 0]--{245, 446}
2018-08-05 15:09:46.904801+0800 JJDynamics[13854:6043679] [-0.23887162744301088, 0.97105115498758732, -0.97105115498758732, -0.23887162744301088, 0, 0]--{247, 451}
2018-08-05 15:09:46.921494+0800 JJDynamics[13854:6043679] [-0.30981996369562398, 0.95079524088819578, -0.95079524088819578, -0.30981996369562398, 0, 0]--{250, 457}
2018-08-05 15:09:46.938459+0800 JJDynamics[13854:6043679] [-0.37889656960767365, 0.92543902529531208, -0.92543902529531208, -0.37889656960767365, 0, 0]--{252, 463}
2018-08-05 15:09:46.954883+0800 JJDynamics[13854:6043679] [-0.44592163430196508, 0.89507200607630699, -0.89507200607630699, -0.44592163430196508, 0, 0]--{254, 470}
2018-08-05 15:09:46.971456+0800 JJDynamics[13854:6043679] [-0.51036026761936359, 0.85996069516896623, -0.85996069516896623, -0.51036026761936359, 0, 0]--{257, 476}
2018-08-05 15:09:46.988148+0800 JJDynamics[13854:6043679] [-0.57188648350497095, 0.82033276783529652, -0.82033276783529652, -0.57188648350497095, 0, 0]--{259, 483}
2018-08-05 15:09:47.004891+0800 JJDynamics[13854:6043679] [-0.63034976238832374, 0.77631126299763542, -0.77631126299763542, -0.63034976238832374, 0, 0]--{262, 491}
2018-08-05 15:09:47.021557+0800 JJDynamics[13854:6043679] [-0.68529134374358092, 0.72826902597193932, -0.72826902597193932, -0.68529134374358092, 0, 0]--{264, 498}
2018-08-05 15:09:47.038110+0800 JJDynamics[13854:6043679] [-0.73644734475166251, 0.6764948694618651, -0.6764948694618651, -0.73644734475166251, 0, 0]--{267, 506}
2018-08-05 15:09:47.054828+0800 JJDynamics[13854:6043679] [-0.78370201615604596, 0.6211369815692418, -0.6211369815692418, -0.78370201615604596, 0, 0]--{269, 514}
2018-08-05 15:09:47.072141+0800 JJDynamics[13854:6043679] [-0.82680502634812847, 0.56248862068976169, -0.56248862068976169, -0.82680502634812847, 0, 0]--{271, 522}
2018-08-05 15:09:47.088440+0800 JJDynamics[13854:6043679] [-0.86532762371592398, 0.50120664763563583, -0.50120664763563583, -0.86532762371592398, 0, 0]--{274, 531}
2018-08-05 15:09:47.104784+0800 JJDynamics[13854:6043679] [-0.89931636232794632, 0.4372986170218584, -0.4372986170218584, -0.89931636232794632, 0, 0]--{276, 540}
2018-08-05 15:09:47.121526+0800 JJDynamics[13854:6043679] [-0.92859315918310981, 0.37109937310420188, -0.37109937310420188, -0.92859315918310981, 0, 0]--{279, 549}
2018-08-05 15:09:47.138148+0800 JJDynamics[13854:6043679] [-0.95294400914857713, 0.30314635974696541, -0.30314635974696541, -0.95294400914857713, 0, 0]--{281, 558}
2018-08-05 15:09:47.154826+0800 JJDynamics[13854:6043679] [-0.97228272980628894, 0.2338082404887197, -0.2338082404887197, -0.97228272980628894, 0, 0]--{283, 568}
2018-08-05 15:09:47.171480+0800 JJDynamics[13854:6043679] [-0.98658331383196829, 0.16325858283205821, -0.16325858283205821, -0.98658331383196829, 0, 0]--{286, 578}
2018-08-05 15:09:47.188214+0800 JJDynamics[13854:6043679] [-0.99575326651152141, 0.092062110727676366, -0.092062110727676366, -0.99575326651152141, 0, 0]--{288, 588}
2018-08-05 15:09:47.205096+0800 JJDynamics[13854:6043679] [-0.99978797880165382, 0.020591198209523983, -0.020591198209523983, -0.99978797880165382, 0, 0]--{291, 598}
2018-08-05 15:09:47.221709+0800 JJDynamics[13854:6043679] [-0.99870015633651066, -0.050970557515386081, 0.050970557515386081, -0.99870015633651066, 0, 0]--{293, 609}
2018-08-05 15:09:47.238137+0800 JJDynamics[13854:6043679] [-0.99249492716280507, -0.122285810935277, 0.122285810935277, -0.99249492716280507, 0, 0]--{295, 620}
2018-08-05 15:09:47.254808+0800 JJDynamics[13854:6043679] [-0.98128089779382333, -0.19258192964280935, 0.19258192964280935, -0.98128089779382333, 0, 0]--{298, 631}
2018-08-05 15:09:47.271730+0800 JJDynamics[13854:6043679] [-0.96509442494820807, -0.26190217817705813, 0.26190217817705813, -0.96509442494820807, 0, 0]--{300, 643}
2018-08-05 15:09:47.288230+0800 JJDynamics[13854:6043679] [-0.94401753031973923, -0.32989529012858027, 0.32989529012858027, -0.94401753031973923, 0, 0]--{302, 654}
2018-08-05 15:09:47.304833+0800 JJDynamics[13854:6043679] [-0.91823624181158126, -0.39603308475901755, 0.39603308475901755, -0.91823624181158126, 0, 0]--{305, 666}
2018-08-05 15:09:47.321616+0800 JJDynamics[13854:6043679] [-0.91608428569548672, -0.40098576221829862, 0.40098576221829862, -0.91608428569548672, 0, 0]--{305, 669}
2018-08-05 15:09:47.338960+0800 JJDynamics[13854:6043679] [-0.92642517599358942, -0.37647894135694598, 0.37647894135694598, -0.92642517599358942, 0, 0]--{305, 667}
2018-08-05 15:09:47.354852+0800 JJDynamics[13854:6043679] [-0.93604024367110672, -0.35189296984755919, 0.35189296984755919, -0.93604024367110672, 0, 0]--{304, 666}
2018-08-05 15:09:47.375910+0800 JJDynamics[13854:6043679] [-0.94500296662989636, -0.32706175725800612, 0.32706175725800612, -0.94500296662989636, 0, 0]--{304, 664}
2018-08-05 15:09:47.388297+0800 JJDynamics[13854:6043679] [-0.95324667898583482, -0.30219326432347371, 0.30219326432347371, -0.95324667898583482, 0, 0]--{303, 663}
2018-08-05 15:09:47.404836+0800 JJDynamics[13854:6043679] [-0.96089148637345423, -0.2769251729529365, 0.2769251729529365, -0.96089148637345423, 0, 0]--{303, 663}
2018-08-05 15:09:47.421459+0800 JJDynamics[13854:6043679] [-0.96781631755177133, -0.25165765531874607, 0.25165765531874607, -0.96781631755177133, 0, 0]--{302, 662}
2018-08-05 15:09:47.439010+0800 JJDynamics[13854:6043679] [-0.97407683889910945, -0.22621739968516674, 0.22621739968516674, -0.97407683889910945, 0, 0]--{302, 662}
2018-08-05 15:09:47.457963+0800 JJDynamics[13854:6043679] [-0.97966875318901847, -0.20062186826234552, 0.20062186826234552, -0.97966875318901847, 0, 0]--{301, 662}
2018-08-05 15:09:47.471699+0800 JJDynamics[13854:6043679] [-0.9845532247099249, -0.17508554398718407, 0.17508554398718407, -0.9845532247099249, 0, 0]--{301, 663}
2018-08-05 15:09:47.488229+0800 JJDynamics[13854:6043679] [-0.98880204214124978, -0.14923311112917995, 0.14923311112917995, -0.98880204214124978, 0, 0]--{300, 664}
2018-08-05 15:09:47.504880+0800 JJDynamics[13854:6043679] [-0.99234746962863918, -0.12347671651626085, 0.12347671651626085, -0.99234746962863918, 0, 0]--{300, 665}
2018-08-05 15:09:47.521559+0800 JJDynamics[13854:6043679] [-0.99522210801562294, -0.097636856345028361, 0.097636856345028361, -0.99522210801562294, 0, 0]--{299, 666}
2018-08-05 15:09:47.538173+0800 JJDynamics[13854:6043679] [-0.99740964800825904, -0.071930480743846309, 0.071930480743846309, -0.99740964800825904, 0, 0]--{299, 668}
2018-08-05 15:09:47.554884+0800 JJDynamics[13854:6043679] [-0.99894252433625585, -0.045976440409288853, 0.045976440409288853, -0.99894252433625585, 0, 0]--{298, 669}
2018-08-05 15:09:47.571560+0800 JJDynamics[13854:6043679] [-0.99979613529768074, -0.020191281381371936, 0.020191281381371936, -0.99979613529768074, 0, 0]--{298, 671}
2018-08-05 15:09:47.588330+0800 JJDynamics[13854:6043679] [-0.99998436115367473, 0.0055926244355460411, -0.0055926244355460411, -0.99998436115367473, 0, 0]--{297, 674}
2018-08-05 15:09:47.604888+0800 JJDynamics[13854:6043679] [-0.99950729111595327, 0.03138749760731336, -0.03138749760731336, -0.99950729111595327, 0, 0]--{297, 676}
2018-08-05 15:09:47.621514+0800 JJDynamics[13854:6043679] [-0.99836494594901304, 0.05716147916406935, -0.05716147916406935, -0.99836494594901304, 0, 0]--{296, 679}
2018-08-05 15:09:47.638316+0800 JJDynamics[13854:6043679] [-0.99657464555281372, 0.08269810059054418, -0.08269810059054418, -0.99657464555281372, 0, 0]--{296, 683}
2018-08-05 15:09:47.655573+0800 JJDynamics[13854:6043679] [-0.99879028539667847, 0.049172815632435626, -0.049172815632435626, -0.99879028539667847, 0, 0]--{296, 683}
2018-08-05 15:09:47.671630+0800 JJDynamics[13854:6043679] [-0.99986890184941479, 0.016191945974629109, -0.016191945974629109, -0.99986890184941479, 0, 0]--{296, 684}
2018-08-05 15:09:47.688278+0800 JJDynamics[13854:6043679] [-0.99985900670601602, -0.016791864365193226, 0.016791864365193226, -0.99985900670601602, 0, 0]--{296, 685}
2018-08-05 15:09:47.704881+0800 JJDynamics[13854:6043679] [-0.99995007385255941, -0.0099924872910074139, 0.0099924872910074139, -0.99995007385255941, 0, 0]--{296, 685}
2018-08-05 15:09:47.721717+0800 JJDynamics[13854:6043679] [-0.99999490348585685, -0.0031926481659901476, 0.0031926481659901476, -0.99999490348585685, 0, 0]--{295, 685}
2018-08-05 15:09:47.738278+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.754951+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.771863+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.788082+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.804749+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.821476+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.838159+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.854808+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.871393+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.888066+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.904744+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.921494+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.938082+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.954743+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.971479+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:47.988089+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.004811+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.021453+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.038136+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.054788+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.071459+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.088120+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.104763+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.121434+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.138105+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.154762+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.171488+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.188160+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.204820+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.221486+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.238122+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.254783+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.271448+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}
2018-08-05 15:09:48.288107+0800 JJDynamics[13854:6043679] [-0.99999998144229718, 0.00019265358860153227, -0.00019265358860153227, -0.99999998144229718, 0, 0]--{295, 685}

虽然动力学适用于这些属性的确切值可能没什么意义,但重要的是要知道它们正在被应用。 因此,如果以编程方式更改对象的frame或变换属性,则可能会覆盖这些值。 这意味着在动态控制下,您无法使用变换来缩放对象。

动态行为的方法签名使用term item而不是视图。 将动态行为应用于对象的唯一要求是它采用UIDynamicItem协议,如下所示:

protocol UIDynamicItem : NSObjectProtocol {
  var center: CGPoint { get set }
  var bounds: CGRect { get }
  var transform: CGAffineTransform { get set }
}

UIDynamicItem协议动态的读写centertransform属性,允许它根据内部计算移动item。 它还具有对边界的读访问权限,用于确定item的size。 这允许它围绕物品的周边创建碰撞边界,并在施加力时计算物品的质量。

该协议意味着dynamics与UIView没有紧密耦合,确实有另一个UIKit类不是视图但仍采用此协议:UICollectionViewLayoutAttributes。 这允许dynamics动画collection views的item。


Collision notifications - Collision通知

到目前为止,您已添加了一些视图和行为,然后让dynamics接管。 在下一步中,您将了解如何在items碰撞时接收通知。

Swift版本

仍然在ViewController.swift中,通过更新类声明采用UICollisionBehaviorDelegate协议:

class ViewController: UIViewController, UICollisionBehaviorDelegate {

viewDidLoad中,在初始化碰撞对象之后将视图控制器设置为代理,如下所示:

collision.collisionDelegate = self

接下来,将一个碰撞行为代理方法的实现添加到类中:

func collisionBehavior(behavior: UICollisionBehavior!, beganContactForItem item: UIDynamicItem!, withBoundaryIdentifier identifier: NSCopying!, atPoint p: CGPoint) {
  println("Boundary contact occurred - \(identifier)")
}

发生碰撞时会调用此代理方法。 它会将一条日志消息打印到控制台。 为了避免使用大量消息混乱控制台日志,请删除您在上面添加的collision.action日志记录。

建立并运行,您的对象将进行交互,您将在控制台中看到以下条目:

Boundary contact occurred - barrier
Boundary contact occurred - barrier
Boundary contact occurred - nil
Boundary contact occurred - nil
Boundary contact occurred - nil
Boundary contact occurred - nil

从上面的日志消息中你可以看到方块视图与边界标识符屏障碰撞两次,这是您之前添加的无形边界。 (null)标识符引用外部参考视图边界。

这些日志消息读起来很有意思,但是当item反弹时提供视觉指示会更有趣。

在将消息发送到日志的行下方,添加以下内容:

let collidingView = item as UIView
collidingView.backgroundColor = UIColor.yellowColor()
UIView.animateWithDuration(0.3) {
  collidingView.backgroundColor = UIColor.grayColor()
}

上面的代码将碰撞item的背景颜色更改为黄色,然后再将其淡化为灰色。

Build并run以查看此效果:

每次碰到边界时,方块视图都会闪烁黄色。

到目前为止,UIKit Dynamics已根据item的界限自动设定item的物理属性(如质量和弹性)。 接下来,您将看到如何使用UIDynamicItemBehavior类自己控制这些物理属性。

OC版本

@interface ViewController () <UICollisionBehaviorDelegate>

collision.collisionDelegate = self;

#pragma mark -  UICollisionBehaviorDelegate

- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p
{
    NSLog(@"Boundary contact occurred - %@", identifier);
}

下面看一下输出结果

2018-08-05 15:56:25.638287+0800 JJDynamics[13861:6057467] Boundary contact occurred - barrier
2018-08-05 15:56:25.638399+0800 JJDynamics[13861:6057467] Boundary contact occurred - barrier

下面我们也看一下那个碰撞就变色的效果

- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p
{
    if ([item isKindOfClass:[UIView class]]) {
        UIView *colorItem = (UIView *)item;
        colorItem.backgroundColor = [UIColor blueColor];
        [UIView animateWithDuration:0.3 animations:^{
            colorItem.backgroundColor = [UIColor redColor];
        }];
    }
}

看一下效果输出,可以看见碰撞的时候变成了蓝色,碰撞结束后就变成了红色。


Configuring item properties - 配置item属性

Swift版本

viewDidLoad中,将以下内容添加到方法的末尾:

let itemBehaviour = UIDynamicItemBehavior(items: [square])
itemBehaviour.elasticity = 0.6
animator.addBehavior(itemBehaviour)

上面的代码创建了一个项目行为,将其与方块视图相关联,然后将行为对象添加到animatorelasticity属性控制item的弹性; 值1.0表示完全弹性碰撞;也就是说,碰撞中没有能量或速度损失。 您已将方块视图的弹性设置为0.6,这意味着每次反弹时方块都会失去速度。

Build并运行您的应用程序,您会注意到该方块视图现在表现得更为方式,如下所示:

注意:如果您想知道我是如何使用显示方形视图先前位置的轨迹生成上述图像的,那实际上非常简单! 只是将一个block添加到其中一个行为的action属性中,并且每三次执行block代码,使用方形视图的当前center和transform向视图添加一个新的方形视图。 代码大致如下。

var updateCount = 0
collision.action = {
  if (updateCount % 3 == 0) {
    let outline = UIView(frame: square.bounds)
    outline.transform = square.transform
    outline.center = square.center

    outline.alpha = 0.5
    outline.backgroundColor = UIColor.clearColor()
    outline.layer.borderColor = square.layer.presentationLayer().backgroundColor
    outline.layer.borderWidth = 1.0
    self.view.addSubview(outline)
  }

    ++updateCount
}

在上面的代码中你只改变了item的弹性;但是,该item的行为类具有许多可以在代码中操作的其他属性。它们如下:

  • elasticity - 弹性 —— 确定“弹性”碰撞的方式,即物品在碰撞中的弹性或“橡皮”状态。
  • friction - 摩擦力 —— 确定沿表面滑动时的运动阻力。
  • density - 密度 —— 当与尺寸size结合时,这将给出item的总质量。质量越大,加速或减速物体越难。
  • resistance - 阻力 —— 确定任何线性运动的阻力。这与摩擦力形成对比,摩擦力仅适用于滑动运动。
  • 角度阻力 - angularResistance —— 确定任何旋转运动的阻力。
  • 允许旋转 - allowsRotation —— 这是一个有趣的,不会模拟任何真实世界的物理属性。将此属性设置为NO时,无论发生任何旋转力,对象都不会旋转。

OC版本

首先,我们也添加下elasticity这个属性,在viewDidLoad最后添加如下代码。

UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.dynamicView]];
itemBehavior.elasticity = 0.6;
[animator addBehavior:itemBehavior];

下面运行看一下效果图

接下来,我们也绘制出方形视图的运动轨迹。

@property (nonatomic, assign) NSInteger number;

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.dynamicView]];
collision.action = ^{
    if (self.number % 3 == 0) {
        UIView *view = [[UIView alloc] initWithFrame:self.dynamicView.bounds];
        view.transform = self.dynamicView.transform;
        view.center = self.dynamicView.center;
        view.alpha = 0.5;
        view.backgroundColor = [UIColor clearColor];
        view.layer.borderColor = self.dynamicView.layer.presentationLayer.backgroundColor;
        view.layer.borderWidth = 1.0;
        [self.view addSubview:view];
    }
    
    self.number ++;
};

下面看一下轨迹示意图


Adding behaviors dynamically - 动态添加行为

在当前状态下,您的应用程序会设置系统的所有行为,然后让动态处理系统的物理特性,直到所有项目都停止。 在下一步中,您将看到如何动态添加和删除行为。

Swift版本

下面在viewDidLoad上面添加以下属性:

var firstContact = false

将以下代码添加到碰撞代理方法collisionBehavior(behavior:beganContactForItem:withBoundaryIdentifier:atPoint:)的末尾。

if (!firstContact) {
  firstContact = true

  let square = UIView(frame: CGRect(x: 30, y: 0, width: 100, height: 100))
  square.backgroundColor = UIColor.grayColor()
  view.addSubview(square)

  collision.addItem(square)
  gravity.addItem(square)

  let attach = UIAttachmentBehavior(item: collidingView, attachedToItem:square)
  animator.addBehavior(attach)
}

上面的代码检测障碍物和方形视图之间的初始接触,创建第二个方形视图并将其添加到碰撞和重力行为中。 此外,您还可以设置attachment行为以创建使用虚拟弹簧附加到对象的效果。

构建并运行您的应用程序; 当原始方块视图撞到障碍物时,您应该会看到一个新的方块,如下所示:

虽然两个正方形视图之间似乎存在连接,但实际上您无法将连接视为线或弹簧,因为屏幕上没有绘制任何内容来表示它。

OC版本

首先在sb中拖进去一个新的view,并设置约束

首先我们也添加下代码

@property (nonatomic, assign) BOOL isFirstContact;
@property (weak, nonatomic) IBOutlet UIView *anotherView;

#pragma mark -  UICollisionBehaviorDelegate

- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p
{
    UIView *colorItem;
    if ([item isKindOfClass:[UIView class]]) {
        colorItem = (UIView *)item;
        colorItem.backgroundColor = [UIColor blueColor];
        [UIView animateWithDuration:0.3 animations:^{
            colorItem.backgroundColor = [UIColor redColor];
        }];
    }
    
    if (self.isFirstContact == NO) {
        self.isFirstContact = YES;
        
        [self.collision addItem:self.anotherView];
        [self.gravity addItem:self.anotherView];
        
        UIAttachmentBehavior *attachBehavior = [[UIAttachmentBehavior alloc] initWithItem:colorItem attachedToItem:self.anotherView];
        [self.animator addBehavior:attachBehavior];
    }
}

下面看一下效果


User Interaction - 用户交互

Swift版本

如您所见,您可以在物理系统运动时动态添加和删除行为。 在最后一节中,只要用户点击屏幕,您就会添加另一种动态行为UISnapBehaviorUISnapBehavior使一个对象跳转到指定的位置,具有类似弹簧的动画。

删除您在上一节中添加的代码:collisionBehavior()中的firstContact属性和if语句。 在屏幕上只有一个方形视图,更容易看到UISnapBehavior的效果。

在viewDidLoad上方添加两个属性:

var square: UIView!
var snap: UISnapBehavior!

这将跟踪您的方形视图,以便您可以从视图控制器中的其他位置访问它。 接下来你将使用snap对象。

在viewDidLoad中,从square的声明中删除let关键字,以便它使用new属性而不是局部变量:

square = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))

最后,为touchesEnded添加一个实现,以便在用户触摸屏幕时创建并添加新的snap行为:

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
  if (snap != nil) {
    animator.removeBehavior(snap)
  }

  let touch = touches.anyObject() as UITouch 
  snap = UISnapBehavior(item: square, snapToPoint: touch.locationInView(view))
  animator.addBehavior(snap)
}

这段代码非常简单。 首先,它检查是否存在现有的snap行为并将其删除。 然后创建一个新的snap行为,将方形视图捕捉到用户触摸的位置,并将其添加到animator

构建并运行您的应用程序。 尝试点击方形视图应该放大到任何你触摸的地方!

OC版本

直接看代码吧

@property (weak, nonatomic) IBOutlet UIView *dynamicView;

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    if (self.snapBehavior != nil) {
        [self.animator removeBehavior:self.snapBehavior];
    }
    
    UITouch *viewTouch = (UITouch *)touches.anyObject;
    self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.dynamicView snapToPoint:[viewTouch locationInView:self.view]];
    [self.animator addBehavior:self.snapBehavior];
}

下面看一下实际效果

这样它就跟着你点击的位置进行移动了。

后记

本篇主要讲述了UIKit动力学和移动效果,感兴趣的给个赞或者关注~~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容