当前位置: 首页 > 科技观察

玩玩iOS9的UIDynamics

时间:2023-03-23 01:41:58 科技观察

UIDynamics是iOS7SDK中一个受欢迎的新特性,它基本上是一个支持UIView的物理引擎,允许我们自定义UI控件的物理特性。API简单明了,您可以轻松创建出色的动画或过渡效果。我之前在这篇文章中介绍了基础知识,这一次,我们将了解iOS9中UIDynamics的新功能。碰撞边界UIDynamics的第一个版本具有碰撞系统(在UICollisionBehavior中)仅支持矩形。这是可以理解的,因为UIView都是矩形架构,但圆形的并不常见,更不用说针对自定义贝塞尔曲线进行优化了。在iOS9中,UIDynamicItem协议增加了一个新的属性:UIDynamicItemCollisionBoundsType,它支持以下枚举类型:RectangleEllipsePath该属性是只读的。如果我们想修改它,我们需要提供我们的子类:classEllipse:UIView{overridevarcollisionBoundsType:UIDynamicItemCollisionBoundsType{return.Ellipse}}这是UIView的默认碰撞边界。这是具有.Ellipse属性的相同UIView。这涵盖了圆形视图。如果我们心血来潮,画了一个更复杂的连续刚体,我们可以使用.path枚举类型,同时重写这个属性:varcollisionBoundingPath:UIBezierPath{get}这个路由可以是你能想到的任何东西,只要它看起来是凸的(即多边形中的任意两点,两点之间的线段完全包含在多边形中),并且是逆时针方向。凸面的条件可能限制太多,所以引入UIDynamicItemGroup,可以详细描述一组不同图形的组合图形。这样,即使生成的多边形是凹的也可以,只要组合中的每个形状都是凸的。FieldBehaviorFieldBehavior是一种在整个场景中使用的新行为。最常见的例子之一是我们一直在默默使用的UIGravityBehavior,即场景中的每个对象都会受到向下的重力。现在我们可以使用一组新的场力,如Radial(离场景中心越近,力越强)、Noise(场景中随机产生的不同力)等。DynamicItemBehavior(动态元素behavior)UIDynamicItemBehavior包含几个有趣的新特性:varcharge:CGFloatvaranchored:Boolcharge表示一个电荷,它可以影响一个元素在电磁场上的移动方式(是的,听起来很疯狂),并且anchored本质上是将形状变成一个静态物体在碰撞,但不响应事件(如果有东西撞到它,它根本不会移动),所以它非常适合代表地板或墙壁。AttachmentBehavior(吸附行为)UIAttachmentBehavior得到改进,现在像侦探一样具有新的方法和属性,例如frictionTorque和attachmentRange。现在捕捉行为更加灵活,我们可以指定相对滑动动作、固定捕捉、绳索链接和我最喜欢的:引脚捕捉。想象一下两个物体被钉在一起,您就会明白这一点。这几乎涵盖了UIDynamics中的新功能,现在,是时候放弃这个变更日志并开始构建一些愚蠢的东西了。Let'sPlayBall上周我在BallKing上花了很多时间。一个伟大的时间杀手,游戏的概念很简单,但执行得很好。而且,它采用了与获得Apple设计奖的《天天过马路》相同的理念:它不会以任何方式影响玩家,例如游戏中的荣誉。我真正喜欢它的一件事是球的物理模型,以及球击中篮板时篮板的反应。测试上面提到的新UIDynamics功能似乎很棒。让我们来看看如何一步一步创建我们自己的简单版本:BallSwift篮球架可以使用一个UIView作为篮板,几个UIView作为篮筐的左右两侧,以及前视图作为篮筐本身(没有with物理刚体)。使用我们之前定义的Ellipse类,我们可以创建游戏场景的视觉表示:宽度:100,高度:100))board.backgroundColor=.whiteColor()board.layer.borderColor=UIColor(red:0.98,green:0.98,blue:0.98,alpha:1).CGColorboard.layer.borderWidth=2board。addSubview({letv=UIView(frame:CGRect(x:30,y:43,width:40,height:40)))v.backgroundColor=.clearColor()v.layer.borderColor=UIColor(red:0.4,green:0.4,blue:0.4,alpha:1).CGColorv.layer.borderWidth=5returnv}())leftHoop=Ellipse(frame:CGRect(x:hoopPosition.x+20,y:hoopPosition.y+80,width:10,height:6))leftHoop.backgroundColor=.clearColor()leftHoop.layer.cornerRadius=3rightHoop=Ellipse(frame:CGRect(x:hoopPosition.x+70,y:hoopPosition.y+80,width:10,height:6))rightHoop.backgroundColor=.clearColor()rightHoop.layer.cornerRadius=3hoop=UIView(frame:CGRect(x:hoopPosition.x+20,y:hoopPosition.y+80,width:60,height:6))箍.backgroundColor=UIColor(红色:177.0/255.0,green:25.0/255.0,blue:25.0/255.0,alpha:1)hoop.layer.cornerRadius=3[board,leftHoop,rightHoop,floor,ball,hoop].map({self.view.addSubview($0)})}这里真的没有什么新东西,篮筐是在常量CGPointhoopPosition以编程方式创建的,但是视图的顺序很重要,因为我们希望篮筐高于篮球。#p#螺母和螺栓篮筐最重要的部分是左右臂,它们需要身体呈圆形(以使与球的碰撞看起来自然),需要用螺栓固定在板和前框架上。这两个将是基本的UIDynamicItems,不会直接碰撞来参与碰撞。新推出的pin型吸附就是为此而生,它可以将一切完美地结合在一起,正如我们在这张粗略图上看到的:在给定的某个空间点内,pin一次只能连接几个视图:letbolts=[CGPoint(x:hoopPosition.x+25,y:hoopPosition.y+85),//leftHoop->BoardCGPoint(x:hoopPosition.x+75,y:hoopPosition.y+85),//rightHoop->BoardCGPoint(x:hoopPosition).x+25,y:hoopPosition.y+85),//hoop->Board(L)CGPoint(x:hoopPosition.x+75,y:hoopPosition.y+85)]//hoop->Board(R)//Buildtheboardzip([leftHoop,rightHoop,hoop,hoop],offsets).map({(item,offset)inanimator?.addBehavior(UIAttachmentBehavior.pinAttachmentWithItem(item,attachedToItem:board,attachmentAnchor:bolts))})如果你不打算继续看swfit版本中的惊人功能,那么你可能对zip和map不熟悉。乍一看,这似乎是故意的,但实际上非常简单:每个视图都被固定到一个偏移点,我们得到了一系列我们稍后将在映射函数中使用的元组。顾名思义,它在给定对象数组中的每个元素之间创建映射。这允许轮辋的左侧和右侧用螺栓固定到板和前框架上,如下所示:左臂用螺栓固定到篮板的左侧右臂用螺栓固定到篮板右手轮辋用螺栓固定到篮板的左侧步骤要求我们把篮板挂起来,不要固定死,这样球可以通过碰撞让它旋转,就像球王游戏中://Setthedensityofthehoop,andfixititsangle//Hangthehoopanimator?.addBehavior({letattachment=UIAttachmentBehavior(item:board,attachedToAnchor:CGPoint(x:hoopPosition.x,y:hoopPosition.y))attachment.length=2attachment.damping=5returnattachment}())animator?.addBehavior({letbehavior=UIDynamicItemBehavior(项目:[leftHoop,rightHoop])behavior.density=10behavior.allowsRotation=falsereturnbehavior}())//Blocktheboardrotationanimator?.addBehavior({letbehavior=UIDynamicItemBehavior(items:[board])behavior.allowsRotation=falsereturnbehavior}())篮子准备好了,现在是打篮球的时候了ular自定义UIImageView子类视图,如Ellipse类:然后,我们可以将球实例化为普通UIImageView:letball:Ball={letball=Ball(frame:CGRect(x:0,y:0,width:28,height:28))ball.image=UIImage(named:"ball")returnball}()***我们设置他的物理属性://Settheelasticityanddensityoftheballanimator?.addBehavior({letbehavior=UIDdynamicItemBehavior(items:[ball])behavior.elasticity=1behavior.density=3behavior.action={if!CGRectIntersectsRect(self.ball.frame,self.view.frame){self.setupBehaviors()self.ball.center=CGPoint(x:40,y:self.view.frame.size.height-100)}}returnbehavior}())在这段代码中,我设置了elasticsize(碰撞后回弹的大小),density(随便对待asweight),还有一个当球超出弹跳范围时立即结束游戏的事件,也就是重置游戏状态(在主视图中)Collisionsandgravity(碰撞和重力)我提到了UIDynamicItemBehavior的新属性anchored,禁用对象的动态行为,同时将其保持在碰撞循环中。听起来将它用于实心地板会很好://Anchortheflooranimator?.addBehavior({letbehavior=UIDynamicItemBehavior(items:[floor])behavior.anchored=truereturnbehavior}())如果您忘记设置此属性,您会挠我的头。反正我就是这样。好的,一切都设置好了,现在我们只需要一些重力和一组碰撞事件:[ball]))Gravity是默认每秒施加一点向下力的场景行为。碰撞行为用作相互碰撞的视图的参数。游戏设置完毕,现在我们可以在球上施加一个瞬间力并在屏幕上滑动手指:letpush=UIPushBehavior(items:[ball],mode:.Instantaneous)push.angle=-1.35push.magnitude=1.56animator?.addBehavior(push)现在你应该明白了,虽然场景的边缘真的画得很低,但是构建它真的很有趣(是的,云彩和灌木丛是同一个草图,就像超级马里奥里一样)。与往常一样,您可以在我们的GitHub页面上找到源代码。下次见

最新推荐
猜你喜欢