2013-10-29 1 views
2

응용 프로그램이 실행될 때 이미지에 점을 만들고 그 점을 천천히 다른 위치로 이동하려고합니다. 여기 내 코드입니다.이 코드는 작동하지만 두 가지 문제가 있습니다.nsbezierpath (objective -c)를 사용하여 코코아에서 공/원을 움직이게할까요?

먼저, 처리 아직 난 단지 완성 된 결과를 확인 윈도우가로드되기 전에 발생했습니다.

둘째 (내가 한 지점 이미지에서 다른 지점으로 이동 보여주고 싶은), 이전 지점은 제거되지 않습니다 새로운 포인트를 만들면 포인트가 움직이는 것처럼 보이지 않습니다. 중복되는 것처럼 보입니다. 포인트를 제거하려면 어떻게해야합니까?

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    // Insert code here to initialize your application 
    NSGraphicsContext* gc = [NSGraphicsContext currentContext]; 

    // Save the current graphics context settings 
    [gc saveGraphicsState]; 

    // Set the color in the current graphics context for future draw operations 
    [[NSColor blackColor] setStroke]; 
    [[NSColor redColor] setFill]; 


    for(int i=1;i<100;i++){ 

     NSRect rect = NSMakeRect(130+i, 130, 10, 10); 
     NSBezierPath* circlePath = [NSBezierPath bezierPath]; 
     [circlePath appendBezierPathWithOvalInRect: rect]; 

     // Outline and fill the path 
     [circlePath stroke]; 
     [circlePath fill]; 


     // // Restore the context to what it was before we messed with it 
     // [gc restoreGraphicsState]; 
    } 
} 

답변

2

편집 : 여기

가 작동 구현의 :

@interface AppDelegate() 
@property (nonatomic, readonly) CALayer * ballLayer ; 
@end 

@implementation AppDelegate 
@synthesize ballLayer = _ballLayer ; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    [ ((NSView*)self.window.contentView) setWantsLayer:YES ] ; 
    [ self performSelectorOnMainThread:@selector(doAnimation) withObject:nil waitUntilDone:NO ] ; 
} 

-(void)doAnimation 
{ 
    [ self.ballLayer addAnimation:[ self createBallLayerAnimation ] forKey:nil ] ; 
} 

-(CALayer*)ballLayer 
{ 
    if (!_ballLayer) 
    { 
     CALayer * layer = [ CALayer layer ] ; 
     NSImage * image = [[ NSImage alloc ] initWithContentsOfURL:[ NSURL URLWithString:@"http://etc-mysitemyway.s3.amazonaws.com/icons/legacy-previews/icons/glossy-black-icons-sports-hobbies/044450-glossy-black-icon-sports-hobbies-ball-beach.png" ] ] ; 
     layer.contents = image ; 
     layer.bounds = (CGRect){ .size = { 100, 100 } } ; 

     [((NSView*)self.window.contentView).layer addSublayer:layer ] ; 

     _ballLayer = layer ; 
    } 

    return _ballLayer ; 
} 

-(CAAnimation*)createBallLayerAnimation 
{ 
    CAKeyframeAnimation * anim = [ CAKeyframeAnimation animationWithKeyPath:@"position" ] ; 
    { 
     CGPathRef p = [ self createBallAnimationPath ] ; 
     anim.path = p ; 
     CGPathRelease(p) ; 
    } 
    anim.duration = 3.0 ; 
    anim.repeatCount = FLT_MAX ; 

    return anim ; 
} 

-(CGPathRef)createBallAnimationPath 
{ 
    CGRect bounds = ((NSView*)self.window.contentView).bounds ; 
    CGPathRef p = CGPathCreateWithEllipseInRect(CGRectInset(bounds, bounds.size.width * 0.25, bounds.size.width * 0.25), NULL) ; 
    return p ; 
} 
@end 

당신은 CGPathCALayer에 위로 읽고 싶은거야 ...

다른 사람들이 말했듯이를 applicationDidFinishLaunching 메소드에서이 작업을 수행하지 마십시오. 수행해야합니다. 당신의 창 /보기가 나타난 후에. 당신이 당신의 자신의 NSView의 서브 클래스는 펜촉에서로드가있는 경우, 하나의 옵션은 -awakeFromNib을 재정의 할 수 있습니다 :

보기 서브 클래스의 다음
-(void)awakeFromNib 
{ 
    [ super awakeFromNib ] ; 
    [ self performSelectorOnMainThread:@selector(doAnimation) withObject:nil waitUntilDone:NO ] ; // when the main thread runs again, call `-doAnimation` 
} 

-(void)doAnimation: 
{ 
    CAAnimation * animation = [ CAKeyframeAnimation animationForKeyPath:@"position" ] ; 
    CGPathRef path = [ self createBallAnimationPath ] ; // method -createBallAnimationPath is defined below... 
    animation.path = path ; 
    CGPathRelease(path) ; 
    [ self.ballLayer addAnimation:animation forKey:nil ] ; // ballLayer is the property that contains a reference to layer that contains the image you want to animate along the path 
} 
(위, -awakeFromNib에서 호출)를 -doAnimation 방법을

경로를 만드는 방법이 있습니다.

-(CGPathRef)createBallAnimationPath 
{ 
    CGMutablePathRef result = CGPathCreateMutable() ; 
    CGPathMoveToPoint(result, 100, 100) ; 
    CGPathAddLineToPoint(result, 1000, 1000) ; 
    return result ; 
} 
+0

네,하지만 다른 부분은 어떻습니까? 원이 움직이는 것처럼 보이게하기 위해 새 점을 만들기 전에 이전 점을 제거 하시겠습니까? – zzzzz

+1

화면에서 무엇인가를 움직이고 싶습니까? 매번 다시 그리는 대신 이동하려는 항목을 레이어 (또는 뷰)에 넣고 이동하십시오. 나는 내 대답을 수정하고있다. – nielsbot

+0

awakefromnib 부분을 이해하지만 대답의 두 번째 부분을 이해하지 못합니다. 견해를 옮기는 것이 무엇을 의미합니까? 나는 코코아를 처음 사용하므로이 주제를 이해할 수 없다. 현재 코드를 수정하여 실행할 수 있습니까? – zzzzz