iOS. Приемы программирования - страница 80
>beganContactForItem:(id
>withBoundaryIdentifier:(id
>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 точках над нижней границей экрана. У нас получается невидимая линия, проходящая по экрану слева направо. Она не позволяет видам бесконечно падать вниз и выходить за пределы опорного вида.
Кроме того, как видите, мы задаем вид с контроллером в качестве делегата поведения столкновения. Таким образом, он получает обновления от этого поведения, сообщающие, произошло ли столкновение и если произошло, то когда. Как только вы узнаете о факте столкновения, то, вероятно, захотите определить, было ли это столкновение с границей (например, созданной нами) или с одним из элементов сцены. Например, если вы создали в опорном виде множество виртуальных стен, а маленькие виды-квадраты могут сталкиваться с этими стенами, то можете реализовать иной эффект (скажем, взрыв), зависящий от того, с чем именно произошло столкновение. О том, с каким элементом произошло столкновение, вы сможете узнать из делегатного метода, вызываемого в контроллере вида и дающего идентификатор той границы, с которой столкнулся элемент. Зная, какой это был объект, мы можем решить, что делать дальше.