2013-03-06 9 views
0

현재 UI 플러그인을 만들고 있습니다. 이 플러그인에는 2 개의 이미지 뷰가 있고 다른 이미지 뷰에는 하나의 이미지 뷰가 있습니다.회 전자가 추가되면 UIView 애니메이션이 실패합니까?

사용자가 화면에서 스 와이프 한 경우 : 스 와이프가 임계 값보다 큰 경우 전면 이미지 뷰는 화면을 스 와이프와 같은 방향으로두고 후면 imageView 뒤에 나타납니다.

그래서 우리는 이것을 이미지 대기열에 사용할 계획입니다. 성공적으로 스 와이프 한 후에는 front imageView가 화면을 떠난 다음 backImageView (앞쪽에 있음)의 뒤에 중심을두고 이미지를 바꿉니다.

더 이상 이미지가 없으면 서버에서 더 많은 이미지를 다운로드 중임을 나타내는 회 전자를 넣습니다.

설명 할 수없는 버그가 하나 있습니다. 스피너를 우리의보기에 추가하면 애니메이션이으로 잘못 처리됩니다.

스 와이프 된 이미지보기는 더 이상 화면을 벗어나지 않지만 원래 위치로 돌아갑니다.

우리는 매우이 당황하고

    [self.view addSubview:spinner]; 

우리의 애니메이션 예기치 않은 동작이 발생합니다 확인합니다.

첨부 이동 방법 미세하십시오

- (void)move:(UIPanGestureRecognizer *)sender { 
    CGPoint translatedPoint = [sender translationInView:self.frontView]; 

    if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) { 
     _firstX = self.frontView.center.x; 
     _firstY = self.frontView.center.y; 
    } 

    translatedPoint = CGPointMake(_firstX+translatedPoint.x, _firstY+translatedPoint.y); 
    [self.frontView setCenter:translatedPoint]; 

    if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) { 
     // Calculate the if the x-movement is greater than a threshold 
     float xTravelled = 0; 
     if (self.frontView.center.x > _firstX) 
      xTravelled = self.frontView.center.x - _firstX; 
     else 
      xTravelled = _firstX - self.frontView.center.x; 

     // Only move if xTravelled is greater than threshold 
     if (xTravelled > self.frontView.window.frame.size.width/3) { 
      NSLog(@"Swipe detected, currentIndex:%d", currentIndex); 

      // Lock view from panning until animation is finished. 
      self.view.userInteractionEnabled = NO; 

      float newXPosition; 
      if (self.frontView.center.x > _firstX) { 
       newXPosition = (float) self.view.frame.size.width * 2; 
      } else { 
       newXPosition = (float) -2 * self.view.frame.size.width; 
      } 

      // We should trigger a fetch as soon as the back image is empty. 
      if (![self getBackView].image) { 
       double delayInSeconds = 2.0; 
       dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
       dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
        //[self fetchComplete]; 
        [spinner stopAnimating]; 
        [spinner removeFromSuperview]; 
        self.view.userInteractionEnabled = YES; 
       }); 

       // Pop up spinner if necessary 
       if (![spinner isAnimating]) { 
        self.view.userInteractionEnabled = NO; 
        [spinner setCenter:CGPointMake(_firstX, _firstY)]; 
        [spinner startAnimating]; 
        /* THIS BREAKS OUR ANIMATION - Enable it to see 
        [self.view addSubview:spinner]; 
        */ 
       } 
      } 

      // Animate the rest of the swipe 
      [UIView \ 
      animateWithDuration:0.5f delay:0.0f options:UIViewAnimationOptionTransitionNone 
      animations:^{ 
       // Use smooth animation to move the top image out of the way 
       [self.frontView setCenter:CGPointMake(newXPosition, self.frontView.center.y)]; 
      } 
      completion:^(BOOL finished){ 
       // Set it to be physically behind the back image 
       [self.view sendSubviewToBack:self.frontView]; 
       //[self.frontView setCenter:CGPointMake(_firstX, _firstY)]; // why not necessary?? 

       // Now change the picture 
       UIImage *next = [self nextImage]; 
       self.frontView.image = next; 

       // update self.top to reference the new back image 
       self.frontView = [self getBackView]; 

       // Do not override spinner's block 
       if (![spinner isAnimating]) 
        self.view.userInteractionEnabled = YES; 
      }]; 
     } else { 
      NSLog(@"Swipe NOT detected"); 
      [UIView \ 
      animateWithDuration:0.5f delay:0.0f options:UIViewAnimationOptionAllowUserInteraction 
      animations:^{ 
       [self.frontView setCenter:CGPointMake(_firstX, _firstY)]; 
      } completion:^(BOOL finished) { 
       self.view.userInteractionEnabled = YES; 
      }]; 
     } 
    } 

나는이 오히려 lenghty 것을 이해하지만, 난 당신이 다운로드하여 컴퓨터에서 실행할 수있는 샘플 프로젝트로이 버그를 격리 한을. 이 샘플 프로젝트는 다음과 같습니다 : http://bit.ly/WO4cEI

self.view에 하위 뷰를 추가하면 [self.view sendSubviewToBack : self.frontView]가 실패한 것 같습니다. 하지만 이것이 왜 우리 애니메이션이 실패하게되는지 확실하지 않습니다.

도움을 주셔서 감사합니다. 이 문제를 해결 user2113425의 추천 @

편집

!

답변

1

우선, 그 시점에 회 전자를 추가 할 필요가 없습니다.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)]; 
    [panRecognizer setMinimumNumberOfTouches:1]; 
    [panRecognizer setMaximumNumberOfTouches:1]; 

    [panRecognizer setDelegate:self]; 
    [self.view addGestureRecognizer:panRecognizer]; 
    self.view.userInteractionEnabled = YES; 

    // Index starts at zero so we pick even. 
    self.frontView = self.evenImage; 

    // Setting the images 
    images = [[NSArray alloc] initWithObjects:@"a.jpeg", @"b.jpeg", nil]; // @"c.jpeg", @"d.jpeg", @"e.jpeg", nil]; 

    currentIndex = 0; 
    self.evenImage.image = [self nextImage]; 
    self.oddImage.image = [self nextImage]; 

    // Spinner 
    spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    **spinner.hidesWhenStopped = YES; 
    [self.view addSubview:spinner];** 
} 

당신이있는 viewDidLoad에 스피너를 추가 할 수 있습니다 그것을 숨길 hidesWhenStopped 세트 및 이동 기능에서 [회 removeFromSuperview]를 제거; 이 줄. addSubView와

문제

+0

그래, 고정! 하지만 왜 그래 ?? – disappearedng

0

이유가 될 수 있습니다 .. 그것은 그와 관련된하지만 확실히 ..

이 문제를 해결하기 위해 많은 방법이있다 수 있습니다, 파단의 zOrder를 변경한다는 것입니다 스피너의 애니메이션. viewController가 high-frequency를 리프레시하는 tableView를 포함하고있을 때와 같은 현상이 나타납니다. 레이어의 다시 그리기로 애니메이션이 깨집니다. 스피너가 뷰의 서브 뷰가 될 경우 이러한 종류의 현상이 발생합니다.

관련 문제