現在、UIプラグインを作成しています。このプラグインには2つのimageViewがあり、1つは別のものの上にあります。
ユーザーが画面をスワイプした場合:スワイプがしきい値よりも大きい場合、前面のimageViewは画面をスワイプと同じ方向に残し、背面のimageViewの後ろに表示されます。
したがって、これを画像のキューに使用する予定です。スワイプが成功すると、前面のimageViewが画面を離れ、backImageView(現在は前面)の後ろの中央に配置され、内部の画像が変更されます。
画像がなくなったら、サーバーからさらに画像をダウンロードしていることを示すスピナーを表示します。
説明できないバグが1つ発生しています。ビューにスピナーを追加すると、アニメーションが誤動作します。
スワイプされたimageViewは画面を離れなくなり、元の位置に戻ります。
私たちはこれに非常に戸惑い、次のことを確認しました
[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;
}];
}
}
これはかなり長いことは理解していますが、このバグをサンプルプロジェクトに分離し、ダウンロードしてコンピューターに実行できるようにしました。このサンプルプロジェクトはここにあります:http://bit.ly/WO4cEI
self.viewにサブビューを追加すると、[self.view sendSubviewToBack:self.frontView]が失敗する原因になっていると思われます。しかし、これがアニメーションの失敗の原因である理由もわかりません。
助けてくれてありがとう!!
編集
@user2113425の推奨によりこの問題が修正されました!!