如何使UIAnimation一次执行一个(迭代for循环),而不是一次全部执行?



我目前正在为一个应用程序创建一个视图控制器,以帮助可视化气泡排序算法。但是,当用户按下排序按钮时,不是逐个发生交换(让用户有时间了解算法的工作原理(,而是一次排序,并且它们一次全部转到各自的位置。我希望让 UIAnimation 遍历 for 循环,并让元素一个接一个地交换,而不是一次全部交换。

我已经尝试将延迟作为参数传递给UIView.animate方法。它所做的只是暂停指定的时间量,然后再一次将它们全部排序(我不想要(。

//IBOutlets for the images (containing numbers) and the sort button
@IBOutlet weak var sortButton: UIButton!
@IBOutlet weak var firstImage: UIImageView!
@IBOutlet weak var secondImage: UIImageView!
@IBOutlet weak var thirdImage: UIImageView!
@IBOutlet weak var fourthImage: UIImageView!
@IBOutlet weak var fifthImage: UIImageView!
@IBOutlet weak var sixthImage: UIImageView!
@IBOutlet weak var seventhImage: UIImageView!
@IBOutlet weak var eighthImage: UIImageView!
@IBOutlet weak var ninthImage: UIImageView!
@IBOutlet weak var tenthImage: UIImageView!

//Create an array of UIImageViews
var elements : [UIImageView] = [UIImageView]()
var numberArray : [Int] = [Int]()
//Function when the view loads
override func viewDidLoad() {
super.viewDidLoad()
//Add the UIImageViews to the array
elements += [firstImage, secondImage, thirdImage, fourthImage, fifthImage, sixthImage, seventhImage, eighthImage, ninthImage, tenthImage]
//Create a variable that will indicate whether there is a duplicate number in the array
var duplicate = true;
//Assign each element in the array a random number between 1 and 10
for index in elements {
//Repeat-while loop to avoid duplicate numbers in the array
repeat {
//Create a random number
let randNumber = Int.random(in: 1 ... 10)
//Display the appropriate numbered image
index.image = UIImage(named: "(randNumber)")
//Check to see if the number is already a duplicate
if numberArray.contains(randNumber) {
duplicate = true
} else {
duplicate = false
//Add the number to the list of used numbers in the array
numberArray.append(randNumber)
}
} while duplicate == true
}
} //End of viewDidLoad


@IBAction func sortButtonPressed(_ sender: Any) {
//Bubble Sort algorithm
for i in (0..<elements.count) {
for j in (1..<elements.count) {
if numberArray[j]<numberArray[j-1] {
let temp = numberArray[j-1]
numberArray[j-1] = numberArray[j]
numberArray[j] = temp
let tempElement = elements[j-1]
elements[j-1] = elements[j]
elements[j] = tempElement
//Swap the corresponding UIImageViews on screen
let tempView : CGRect = elements[j-1].frame
UIView.animate(withDuration: 0.75, delay: 0, animations: {
self.elements[j-1].frame = CGRect(x: self.elements[j].frame.minX, y: self.elements[j].frame.minY, width: tempView.width, height: tempView.height)
self.elements[j].frame = CGRect(x: tempView.minX, y: tempView.minY, width: self.elements[j].frame.width, height: self.elements[j].frame.width)
self.view.layoutIfNeeded()
})
}
}
}
}

有谁知道如何使图像交换(动画(一个接一个(对于每次迭代(而不是一次全部发生?(焦点区域朝向排序按钮按下功能的底部...任何帮助将不胜感激。提前感谢您的帮助!

要手动执行此类操作,您需要在当前动画完成后启动新动画。有几种方法可以做到这一点,但其中之一是将动画所需的所有数据打包到一个类中,然后创建此类类的数组。然后,您可以创建一个递归调用的方法。像这样:

- (void)performAllAnimations:(NSArray *)allAnimations
{
NSMutableArray *duplicate = [allAnimations mutableCopy];
AnimationDescription *currentAnimation = duplicate.firstObject;
[duplicate removeObjectAtIndex:0];
[UIView animateWithDuration:currentAnimation.duration animations:^{
// Use currentAnimation to do the animation
} completion:^(BOOL finished) {
if(duplicate.count > 0) [self performAllAnimations:duplicate];
}];
}

您并不总是需要AnimationDescription作为自定义类。在您的情况下,只需使用索引数组就足够了。例如,您将执行以下操作:

- (void)performAllAnimations:(NSArray *)allAnimations
{
NSMutableArray *duplicate = [allAnimations mutableCopy];
int currentAnimationIndex = [duplicate.firstObject integerValue];
[duplicate removeObjectAtIndex:0];
[UIView animateWithDuration:0.3 animations:^{
// Use currentAnimation to do the animation
} completion:^(BOOL finished) {
if(duplicate.count > 0) [self performAllAnimations:duplicate];
}];
}

然后,您可以执行以下操作:

NSMutableArray *indexArray = [[NSMutableArray alloc] init];
for(int i=0; i<10; i++) {
[indexArray addObject:@(i)];
}
[self performAllAnimations: indexArray];

自然地使用您自己的数据。

另一种方法是使用延迟。在某些情况下,它可能会更好,因为您可以更好地控制下一个动画的启动时间。请参阅以下示例:

- (void)performAllAnimations:(NSArray *)allAnimations withAnimationExecution:(void (^)(id animationObject, int index))execution
{
NSTimeInterval duration = 0.3;
for(int i=0; i<allAnimations.count; i++) {
[UIView animateWithDuration:duration delay:(duration*0.5)*i options:UIViewAnimationOptionCurveEaseInOut animations:^{
execution(allAnimations[i], i);
} completion:^(BOOL finished) {
}];
}
}
- (void)testAnimation
{
NSMutableArray *views = [[NSMutableArray alloc] init];
for(int i=0; i<10; i++) {
UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 50.0, 100.0, 100.0)];
[self.view addSubview:aView];
aView.backgroundColor = [UIColor blackColor];
aView.layer.borderWidth = 2.0;
aView.layer.borderColor = [UIColor yellowColor].CGColor;
[views addObject:aView];
}
[self performAllAnimations:views withAnimationExecution:^(id animationObject, int index) {
UIView *view = animationObject;
view.frame = CGRectMake(75.0*index, 100.0, 100.0, 100.0);
}];
}

相关内容

  • 没有找到相关文章

最新更新