문제

나는 사용자 지정 UIView 을 표시하는 타일 이미지입니다.

    - (void)drawRect:(CGRect)rect
    {
        ...
        CGContextRef context = UIGraphicsGetCurrentContext();       
        CGContextClipToRect(context,
             CGRectMake(0.0, 0.0, rect.size.width, rect.size.height));      
        CGContextDrawTiledImage(context, imageRect, imageRef);
        ...
    }

이제 나가려고 애니메이션 크기를 조정하는 뷰입니다.

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];

// change frame of view

[UIView commitAnimations];

내가 무엇을 기대하는 것은 기와 지역에 위치하고,성장을 떠나 타일의 크기는 상수입니다.무슨 일을 대신 하는 동안 지역이 성장의 원본 내용 보기로 확장하는 새로운 크기입니다.에서 적어도 중 애니메이션이다.그래서 처음에 결국 애니메이션의 모든 것이 좋습니다.하는 동안 애니메이션 타일이 왜곡되었습니다.

왜 캘리포니아 노력하고 확인해 주세요.하지 못하도록 하려면 어떻게 해서 이렇게?나는 무엇을 놓쳤는가?

도움이 되었습니까?

해결책

면 핵심 애니메이션을 다시 코드에 대한 모든 애니메이션 프레임지 않을 것입 한 빨리,그리고 애니메이션의 사용자 정의 속성은 오랜 기능을 요청하고 FAQ 을 위한 캘리포니아에서 맥.

UIViewContentModeRedraw 이 올바르게 매치된 상태이며,또한 최신 CA.문제가에서 UIKit 관점의 프레임만 두 값:값에 전환의 시작과 끝 값의 전환,그리고 당신이 무엇을 알렸다.에서 보면 핵심 애니메이션이 건축 문서 당신은 어떻게 볼 캘리포니아는 개인 표현의 모든 계층 속성과 값을 변경하는 시간.는 프레임 보간 일이 일어나고,당신이 할 수 없습의 통지를 변화들이 일어난다.

그래서 유일한 방법은 사용 NSTimer (나 performSelector:withObject:afterDelay:)보기를 변경하려면 프레임을 통해 시간,옛날 방법입니다.

다른 팁

나는 유사한 문제에 직면하고 다른 상황에서 발견했는데,그것이 시작인 것 같이 스레드 발견했 던의 제안의 설정 프레임에서 NSTimer.내가 이 코드를 달성하기 위해 같은:

CGFloat kDurationForFullScreenAnimation = 1.0;
CGFloat kNumberOfSteps = 100.0; // (kDurationForFullScreenAnimation / kNumberOfSteps) will be the interval with which NSTimer will be triggered.
int gCurrentStep = 0;
-(void)animateFrameOfView:(UIView*)inView toNewFrame:(CGRect)inNewFrameRect withAnimationDuration:(NSTimeInterval)inAnimationDuration numberOfSteps:(int)inSteps
{
    CGRect originalFrame = [inView frame];

    CGFloat differenceInXOrigin = originalFrame.origin.x - inNewFrameRect.origin.x;
    CGFloat differenceInYOrigin = originalFrame.origin.y - inNewFrameRect.origin.y;
    CGFloat stepValueForXAxis = differenceInXOrigin / inSteps;
    CGFloat stepValueForYAxis = differenceInYOrigin / inSteps;

    CGFloat differenceInWidth = originalFrame.size.width - inNewFrameRect.size.width;
    CGFloat differenceInHeight = originalFrame.size.height - inNewFrameRect.size.height;
    CGFloat stepValueForWidth = differenceInWidth / inSteps;
    CGFloat stepValueForHeight = differenceInHeight / inSteps;

    gCurrentStep = 0;
    NSArray *info = [NSArray arrayWithObjects: inView, [NSNumber numberWithInt:inSteps], [NSNumber numberWithFloat:stepValueForXAxis], [NSNumber numberWithFloat:stepValueForYAxis], [NSNumber numberWithFloat:stepValueForWidth], [NSNumber numberWithFloat:stepValueForHeight], nil];
    NSTimer *aniTimer = [NSTimer timerWithTimeInterval:(kDurationForFullScreenAnimation / kNumberOfSteps)
                                                target:self
                                              selector:@selector(changeFrameWithAnimation:)
                                              userInfo:info
                                               repeats:YES];
    [self setAnimationTimer:aniTimer];
    [[NSRunLoop currentRunLoop] addTimer:aniTimer
                                 forMode:NSDefaultRunLoopMode];
}

-(void)changeFrameWithAnimation:(NSTimer*)inTimer
{
    NSArray *userInfo = (NSArray*)[inTimer userInfo];
    UIView *inView = [userInfo objectAtIndex:0];
    int totalNumberOfSteps = [(NSNumber*)[userInfo objectAtIndex:1] intValue];
    if (gCurrentStep<totalNumberOfSteps)
    {
        CGFloat stepValueOfXAxis = [(NSNumber*)[userInfo objectAtIndex:2] floatValue];
        CGFloat stepValueOfYAxis = [(NSNumber*)[userInfo objectAtIndex:3] floatValue];
        CGFloat stepValueForWidth = [(NSNumber*)[userInfo objectAtIndex:4] floatValue];
        CGFloat stepValueForHeight = [(NSNumber*)[userInfo objectAtIndex:5] floatValue];

        CGRect currentFrame = [inView frame];
        CGRect newFrame;
        newFrame.origin.x = currentFrame.origin.x - stepValueOfXAxis;
        newFrame.origin.y = currentFrame.origin.y - stepValueOfYAxis;
        newFrame.size.width = currentFrame.size.width - stepValueForWidth;
        newFrame.size.height = currentFrame.size.height - stepValueForHeight;

        [inView setFrame:newFrame];

        gCurrentStep++;
    }
    else 
    {
        [[self animationTimer] invalidate];
    }
}

내가 찾는 것이 오래 걸리는 시간을 설정하는 프레임 타이머를 완료하는 작업입니다.그것은 아마존에 얼마나 깊은 계층 보기에는 전화 setFrame 이 방법을 사용하여.그리고 아마 그 이유는 뷰가 첫째로 다시 크기와 다음 애니메이션을 원산지에서 sdk.또는 아마가 어떤 문제에서 타이머 메커니즘에 내 코드로 인하여 성능을 방해?

그것은 작동하지만,그것은 매우 느리기 때문에 어쩌면 내 계층 보기가 너무 깊다.

로 던음을 나타냅,핵심 애니메이션이지 않을 것이 다시 그리기의 UIView 의 계층의 내용 각 프레임으로 크기가 조정됩니다.당신이해야 할 것을 자신을 사용하여 타이머입니다.

남자 옴니 게시는 좋은 예를 수행하는 방법의 애니메이션을 기반으로 귀하의 사용자 정의될 수 있는 속성을 적용할 경우입니다.는 예제에 대한 설명과 함께 대한 작동 방법,발견될 수 있는 .

지 않는 경우에 큰 애니메이션이나 성능이 문제가 되지 않는 애니메이션을 위한 기간 사용할 수 있습니다 CADisplayLink.그것은 부드럽게 애니메이션의 확장 사용자 정의 UIView 리 UIBezierPaths 에 대한 인스턴스입니다.아래의 예제 코드에 적응할 수 있습니다 당신의 이미지입니다.

이 ivars 의 내용보기 포함 displayLink 로 CADisplayLink,두 CGRects:toFrame 및 fromFrame 뿐만 아니라 시간과 startTime.

- (void)yourAnimationMethodCall
{
    toFrame = <get the destination frame>
    fromFrame = self.frame; // current frame.

    [displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; // just in case    
    displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateFrame:)];
    startTime = CACurrentMediaTime();
    duration = 0.25;
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)animateFrame:(CADisplayLink *)link
{
    CGFloat dt = ([link timestamp] - startTime) / duration;

    if (dt >= 1.0) {
        self.frame = toFrame;
        [displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
        displayLink = nil;
        return;
    }

    CGRect f = toFrame;
    f.size.height = (toFrame.size.height - fromFrame.size.height) * dt + fromFrame.size.height;
    self.frame = f;
}

참고 하지는 않았을 테스트는 그것의 성능을,그러나 그것은 원활하게 작동합니다.

나는 우연히 이 질문을하려고 할 때에 애니메이션 크기 변경에 UIView 니다.나는 다른 사람을 마찬가지로 여기에 도착에서 혜택을 수도 있습 이 대답이다.원래 나는 사용자 정의 UIView 서브 클래스고 재정의 케이크 방법은 다음과 같다:

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(ctx, 2.0f);
    CGContextSetStrokeColorWithColor(ctx, [UIColor orangeColor].CGColor);
    CGContextStrokeRect(ctx, rect);

    [super drawRect:rect];
}

이끌 확장 문제와 결합할 때 애니메이션으로 다른 사람이 언급했다.상단과 하단의 테두리 성장할 것 이라고 너무 두꺼운 또는 두 개의 얇은 나타납하게 됩니다.이 효과는 쉽게 눈에 띄게 전환 가능한 경우에는 느린이 애니메이션이 있습니다.

이 솔루션을 포기하는 사용자 정의 서브 클래스고 대신 이 방법을 사용:

[_borderView.layer setBorderWidth:2.0f];
[_borderView.layer setBorderColor:[UIColor orangeColor].CGColor];

이 문제를 해결으로 확장하는 테두리에 UIView 동안 애니메이션이 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top