2013-06-20 2 views
-1

경로/베 지어 커브를 따라 객체를 만들려면 어떻게해야합니까? 즉, 같은 경로를 따라 주어진 간격으로 주어진 경로를 따라 여러 개의 UIButton을 만드는 방법은 무엇입니까?경로를 따라 여러 UIButton을 만드는 방법/BezierCurve?

나는 움직이는 물체에 관한 수십 가지의 질문을 보았습니다. 그러나 실제로 그것을 생성하는 솔루션이 필요합니다.

나는 경로를 따라 가고 모든 X 점/거리에 대한 객체를 만들고 싶습니다. 이와 같이 :

이 경우 4 포인트마다 위치를 가져 와서 UIButton을 만듭니다.

+0

질문을 명확히하십시오. 패스를 따라 객체를 만들지 만 화면에 그려서는 안됩니다. 응? – iwasrobbed

+0

경로를 따라 여러 UIButton 개체를 만들려고합니다. 이것이 가능한가? 모든 X 점/거리에 대해 X/Y 위치를 반환해야하므로 만들 수 있습니다. – nmdias

+0

그 경로를 따라 애니메이션이있는 X/Y 위치를 반환 할 수 있기를 바랬지 만 애니메이션을 통해 각 X 포인트/거리에 대해 지정된 선택기를 트리거하는 방법을 알 수 없었습니다. 동시. – nmdias

답변

11

을 도울 수 있다면 아니,이 표시되면 아이폰 OS는 직접 당신에게 경로를 따라 간격 포인트를 제공하는 공개 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는 내 문제에 대한 완벽한 해답을 제시했지만 도움을 주셔서 감사합니다! 건배 =) – nmdias

관련 문제