• collisionBehavior: beganContactForItem: withBoundaryIdentifier: atPoint: — вызывается в делегате, когда один из элементов, обладающих поведением столкновения, ударяется об одну из границ, добавленных к этому поведению;
• collisionBehavior: endedContactForItem: withBoundaryIdentifier: atPoint: — вызывается, когда элемент, столкнувшийся с границей, отскочил от нее и, таким образом, контакт элемента с границей прекратился.
Чтобы продемонстрировать вам делегат в действии и показать, как его можно использовать, расширим приведенный пример. Как только квадратики достигают нижней границы опорного вида, мы делаем их красными, увеличиваем на 200 %, а потом заставляем рассыпаться, как при взрыве, и исчезать из виду:
NSString *const kBottomBoundary = @"bottomBoundary";
@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *squareViews;
@property (nonatomic, strong) UIDynamicAnimator *animator;
@end
@implementation ViewController
— (void)collisionBehavior:(UICollisionBehavior*)paramBehavior
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 точках над нижней границей экрана. У нас получается невидимая линия, проходящая по экрану слева направо. Она не позволяет видам бесконечно падать вниз и выходить за пределы опорного вида.
Кроме того, как видите, мы задаем вид с контроллером в качестве делегата поведения столкновения. Таким образом, он получает обновления от этого поведения, сообщающие, произошло ли столкновение и если произошло, то когда. Как только вы узнаете о факте столкновения, то, вероятно, захотите определить, было ли это столкновение с границей (например, созданной нами) или с одним из элементов сцены. Например, если вы создали в опорном виде множество виртуальных стен, а маленькие виды-квадраты могут сталкиваться с этими стенами, то можете реализовать иной эффект (скажем, взрыв), зависящий от того, с чем именно произошло столкновение. О том, с каким элементом произошло столкновение, вы сможете узнать из делегатного метода, вызываемого в контроллере вида и дающего идентификатор той границы, с которой столкнулся элемент. Зная, какой это был объект, мы можем решить, что делать дальше.
В примере мы сравниваем идентификатор, получаемый от поведения столкновения, с константой kBottomBoundary, которую присвоили барьеру при создании этого барьера. Создаем для объекта такую анимацию: квадрат под действием тяготения движется по экрану вниз, вплоть до установленной нами границы. Граница гарантирует, что квадрат остановится на расстоянии 100 точек от нижнего края экрана, на проведенной линии.
Читать дальше
Конец ознакомительного отрывка
Купить книгу