iOS. Приемы программирования - страница 78
Обсуждение
Поведение столкновения, относящееся к типу UICollisionBehavior, затрагивает объекты, соответствующие протоколу UIDynamicItem. Все виды типа UIView уже ему соответствуют, поэтому вам придется лишь инстанцировать ваши виды и добавить их к поведению столкновения. Поведение столкновения требует определить на экране границы, которые будут непреодолимы для элементов, находящихся в аниматоре. Например, если вы зададите линию, которая будет идти из нижнего левого угла вашего опорного вида в нижний правый угол (соответственно, это будет линия, вплотную прилегающая к его нижнему краю), а также добавите к этому виду поведение тяготения, то виды, расположенные на экране, будут двигаться под действием тяготения вниз, но не смогут «провалиться» с экрана, так как столкнутся с его нижним краем, который задается поведением столкновения.
Если вы хотите, чтобы границы области, в которой действует поведение столкновения, совпадали с границами опорного вида, то присвойте свойству translatesReferenceBoundsIntoBoundary экземпляра поведения столкновения значение YES. Если хотите самостоятельно провести линии, соответствующие границам такой области, просто воспользуйтесь методом экземпляра addBoundaryWithIdentifier: fromPoint: toPoint:, относящимся к классу UICollisionBehavior.
В этом примере мы собираемся создать два цветных вида, один из которых расположен на другом. После этого добавим к аниматору поведение тяготения, чтобы эти виды не перекрывали друг друга. Кроме того, они не будут выходить за границы опорного вида (то есть вида контроллера).
Итак, для начала определим массив видов и аниматор:
>#import "ViewController.h"
>@interface ViewController ()
>@property (nonatomic, strong) NSMutableArray *squareViews;
>@property (nonatomic, strong) UIDynamicAnimator *animator;
>@end
>@implementation ViewController
><# Остаток вашего кода находится здесь #>
>Потом, когда вид появится на экране, зададим поведения столкновения и тяготения и добавим их к аниматору:
>– (void)viewDidAppear:(BOOL)animated{
>[super viewDidAppear: animated];
>/* Создаем виды */
>NSUInteger const NumberOfViews = 2;
>self.squareViews = [[NSMutableArray alloc] initWithCapacity: NumberOfViews];
>NSArray *colors = @[[UIColor redColor], [UIColor greenColor]];
>CGPoint currentCenterPoint = self.view.center;
>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.translatesReferenceBoundsIntoBoundary = YES;
>[self.animator addBehavior: collision];
>}
Получим примерно такой же результат, как на рис. 2.1.
Рис. 2.1. Взаимодействующие поведения тяготения и столкновения
В этом примере показано, что поведение обнаружения столкновений работает отлично, если свойство translatesReferenceBoundsIntoBoundary имеет значение YES. Но что, если мы захотим очертить собственные границы столкновений? Здесь и пригодится метод экземпляра addBoundaryWithIdentifier: fromPoint: toPoint:, относящийся к поведению столкновения. Вот параметры, которые следует передать этому методу: