2013-06-20 4 views
-1

Как создать объекты по пути/Безье? Другими словами, как я могу создать несколько UIButtons по заданному пути с заданным интервалом вдоль этого же пути?Как создать несколько UIButtons по пути/BezierCurve?

Я видел десятки вопросов о движущихся объектах. Но мне нужно решение для их создания.

Я хотел бы пойти по пути и создать объект для каждого Х точек/расстояний. Примерно так:

[email protected]@[email protected]@.... 

В этом случае, для каждых 4 точек, получить позицию и создать там UIButton.

+0

Просьба уточнить ваш вопрос. Вы хотите создавать объекты по пути, но не рисовать их на экране? А? – iwasrobbed

+0

Я пытаюсь создать несколько объектов UIButton по пути. Это возможно? Для каждого X-точки/расстояния мне нужно вернуть положение X/Y, поэтому я могу их создать. – nmdias

+0

Я надеялся, что смогу вернуть позицию X/Y анимацией по этому пути, но я не знаю, как бы я сказал, чтобы анимация запускала заданный селектор для каждой точки/расстояния X и возвращала позицию в в то же время. – nmdias

ответ

11

IOS не имеет публичного API, который напрямую дает вам очки разнесенных вдоль пути. Но есть обходной способ сделать это. Предположим, вам нужны точки вдоль пути, расположенного на расстоянии от X.

Сначала создайте CGPathRef, содержащий ваш путь. (Вы можете построить UIBezierPath, если вы предпочитаете, а затем получает его свойство CGPath.)

Затем вызовите CGPathCreateCopyByDashingPath, используя образец штриха { X, X }. Например:

static CGFloat const kSpace = 10; 
CGPathRef dashedPath = CGPathCreateCopyByDashingPath(path, NULL, 0, 
    (CGFloat const []){ kSpace, kSpace }, 2); 

Это возвращает новый путь, содержащий несколько подпапок. Каждый подпуть является сегментом длины X исходного пути и отделен от соседних подпутей расстоянием X по исходному пути. Таким образом, конечные точки подпапок расположены на исходном пути с интервалом длины X.

Итак, перечислим пунктирную линию, используя CGPathApply, выбрав там конечные точки и создавая там кнопки. Во-первых, вы хотите, чтобы обернуть его в функцию, которая принимает блок:

static void applyBlockToPathElement(void *info, const CGPathElement *element) { 
    void (^block)(const CGPathElement *) = (__bridge void (^)(const CGPathElement *))(info); 
    block(element); 
} 

void MyCGPathApplyBlock(CGPathRef path, void (^block)(const CGPathElement *element)) { 
    CGPathApply(path, (__bridge void *)(block), applyBlockToPathElement); 
} 

Тогда можно применить блок, который находит каждый подпуть конечной точки и создает кнопку там. Предполагая, что у вас есть метод с именем createButtonAtPoint:, что-то вроде этого должно работать:

__block BOOL isInSubpath = NO; 
__block CGPoint subpathStart = CGPointZero; 
__block CGPoint currentPoint = CGPointZero; 
MyCGPathApplyBlock(dashedPath, ^(const CGPathElement *element) { 
    switch (element->type) { 
     case kCGPathElementMoveToPoint: 
      if (isInSubpath) { 
       [self createButtonAtPoint:currentPoint]; 
       isInSubpath = NO; 
      } 
      currentPoint = element->points[0]; 
      break; 

     case kCGPathElementCloseSubpath: 
      // This should not appear in a dashed path. 
      break; 

     case kCGPathElementAddLineToPoint: 
     case kCGPathElementAddQuadCurveToPoint: 
     case kCGPathElementAddCurveToPoint: 
      if (!isInSubpath) { 
       [self createButtonAtPoint:currentPoint]; 
       isInSubpath = YES; 
      } 
      int pointIndex = 
       element->type == kCGPathElementAddLineToPoint ? 0 
       : element->type == kCGPathElementAddQuadCurveToPoint ? 1 
       : /* element->type == kCGPathElementAddCurveToPoint ? */ 2; 
      currentPoint = element->points[pointIndex]; 
      break; 
    } 
}); 
+0

Вы отлично поняли мою проблему. Я все еще пытаюсь обвести вокруг себя голову, но ваше решение выглядит очень многообещающим! Спасибо за такой отличный ответ, сэр. – nmdias

+0

Только что закончил реализацию этого кода. Боже мой, я поражен тем, как в вашем коде не было ни одной опечатки, и как легко вы это придумали. Он отлично работает! Это все еще немного опережает мои знания API, я не думаю, что подошел бы близко к этому. Еще раз спасибо! – nmdias

+0

Спасибо. Я написал код в Xcode, чтобы избежать ошибок, а затем скопировал его в ответ. И я бы не сказал, что это так просто. Просто [я использовал эту технику раньше] (http://stackoverflow.com/a/13667092/77567). –

-1

Вы еще не решили проблему? если нет, то увидеть, если это может помочь

//if the interval is kown as float, suggesting it named padding 

    //then you can 

    for(i=0;i<numOfPaddings;i++){ 
     //create a button 
     UIButton *aButton = [UIButton buttonWithType:UIButtonRoundRect/*I forgot how to spell,but it does not metter*/]; 
     //Set your button's position base on padding 
     [aButton setFrame:CGRectMake(padding+padding*i,20,50,20)]; 
    } 
+0

@rob mayoff дал прекрасный ответ на мою проблему, но спасибо за помощь! Cheers =) – nmdias