Вандад Нахавандипур

iOS. Приемы программирования


Скачать книгу

также

      Раздел 2.0.

      2.2. Обнаружение столкновений между компонентами пользовательского интерфейса и реагирование на них

      Постановка задачи

      Требуется задать на экране границы столкновений между компонентами вашего пользовательского интерфейса так, чтобы эти компоненты не перекрывали друг друга.

      Решение

      Инстанцируйте объект типа UICollisionBehavior и прикрепите его к объекту аниматора. Присвойте свойству translatesReferenceBoundsIntoBoundary поведения столкновений значение YES и убедитесь в том, что аниматор инициализирован с вышестоящим видом в качестве опорной сущности. Так вы гарантируете, что дочерние виды, на которые распространяется поведение столкновения (о чем мы вскоре поговорим), не будут выпадать за пределы вышестоящего вида.

      Обсуждение

      Поведение столкновения, относящееся к типу 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