iOS. Приемы программирования - страница 80



>beganContactForItem:(id )paramItem

>withBoundaryIdentifier:(id )paramIdentifier

>atPoint:(CGPoint)paramPoint{


>NSString *identifier = (NSString *)paramIdentifier;


>if ([identifier isEqualToString: kBottomBoundary]){


>[UIView animateWithDuration:1.0f animations: ^{

>UIView *view = (UIView *)paramItem;


>view.backgroundColor = [UIColor redColor];

>view.alpha = 0.0f;

>view.transform = CGAffineTransformMakeScale(2.0f, 2.0f);

>} completion: ^(BOOL finished) {

>UIView *view = (UIView *)paramItem;

>[paramBehavior removeItem: paramItem];

>[view removeFromSuperview];

>}];


>}


>}


>– (void)viewDidAppearBOOL)animated{

>[super viewDidAppear: animated];


>/* Создаем виды */

>NSUInteger const NumberOfViews = 2;


>self.squareViews = [[NSMutableArray alloc] initWithCapacity: NumberOfViews];

>NSArray *colors = @[[UIColor redColor], [UIColor greenColor]];


>CGPoint currentCenterPoint = CGPointMake(self.view.center.x, 0.0f);

>CGSize eachViewSize = CGSizeMake(50.0f, 50.0f);

>for (NSUInteger counter = 0; counter < NumberOfViews; counter++){


>UIView *newView =

>[[UIView alloc] initWithFrame:

>CGRectMake(0.0f, 0.0f, eachViewSize.width, eachViewSize.height)];


>newView.backgroundColor = colors[counter];

>newView.center = currentCenterPoint;


>currentCenterPoint.y += eachViewSize.height + 10.0f;

>[self.view addSubview: newView];


>[self.squareViews addObject: newView];


>}


>self.animator = [[UIDynamicAnimator alloc]

>initWithReferenceView: self.view];


>/* Создаем тяготение */

>UIGravityBehavior *gravity = [[UIGravityBehavior alloc]

>initWithItems: self.squareViews];

>[self.animator addBehavior: gravity];


>/* Создаем обнаружение столкновений */

>UICollisionBehavior *collision = [[UICollisionBehavior alloc]

>initWithItems: self.squareViews];

>[collision

>addBoundaryWithIdentifier: kBottomBoundary

>fromPoint: CGPointMake(0.0f, self.view.bounds.size.height – 100.0f)

>toPoint: CGPointMake(self.view.bounds.size.width,

>self.view.bounds.size.height – 100.0f)];

>collision.collisionDelegate = self;


>[self.animator addBehavior: collision];


>}


Объясню, что происходит в коде. Во-первых, мы создаем два вида и кладем их один на другой. Эти виды представляют собой два обычных разноцветных квадрата: второй находится на первом. Оба они добавлены к контроллеру вида. Как и в предыдущих примерах, мы добавляем к аниматору поведение тяготения. Это означает, что, как только анимация начнет действовать, виды станут как будто сползать по опорному виду сверху вниз. Мы не задаем границы опорного вида в качестве границ столкновения, а самостоятельно проводим границу столкновения, располагая ее в 100 точках над нижней границей экрана. У нас получается невидимая линия, проходящая по экрану слева направо. Она не позволяет видам бесконечно падать вниз и выходить за пределы опорного вида.

Кроме того, как видите, мы задаем вид с контроллером в качестве делегата поведения столкновения. Таким образом, он получает обновления от этого поведения, сообщающие, произошло ли столкновение и если произошло, то когда. Как только вы узнаете о факте столкновения, то, вероятно, захотите определить, было ли это столкновение с границей (например, созданной нами) или с одним из элементов сцены. Например, если вы создали в опорном виде множество виртуальных стен, а маленькие виды-квадраты могут сталкиваться с этими стенами, то можете реализовать иной эффект (скажем, взрыв), зависящий от того, с чем именно произошло столкновение. О том, с каким элементом произошло столкновение, вы сможете узнать из делегатного метода, вызываемого в контроллере вида и дающего идентификатор той границы, с которой столкнулся элемент. Зная, какой это был объект, мы можем решить, что делать дальше.