Swift中UIButton点击切换勾选图标并动画还原原图标异常问题
Hey there! I totally get why this is confusing when you're new to animations—let's break down what's happening and fix it.
The Root Problem
The issue here is that UI updates happen in batches on the main thread's run loop. If you set the checkmark icon and immediately trigger an animation to switch back in the same chunk of code, the system might merge those two changes before ever rendering the checkmark to the screen. That's why you see the debug prints 1 and 2, but the checkmark never appears (or flashes so fast you miss it).
The Solution
We need to give the system time to actually display the checkmark before starting the animation back to the original icon. Here's a step-by-step implementation:
- First, save the original button image when the button is tapped.
- Immediately set the checkmark icon.
- Use a small delay to let the checkmark render, then animate the switch back to the original icon.
Here's the code example (using Swift, the logic translates cleanly to Objective-C too):
@IBAction func toggleCheckmarkButtonTapped(_ sender: UIButton) { // Make sure we have the original image to switch back to guard let originalButtonImage = sender.imageView?.image else { print("No original image found!") return } // Step 1: Immediately set the checkmark icon let checkmarkImage = UIImage(named: "circle_150px_green filled copy") sender.setImage(checkmarkImage, for: .normal) print("1") // Step 2: Wait a short time (adjust this value to control how long the checkmark shows) let checkmarkDisplayDuration = 0.5 // 0.5 seconds DispatchQueue.main.asyncAfter(deadline: .now() + checkmarkDisplayDuration) { print("2") // Step 3: Animate the transition back to the original icon UIView.transition(with: sender, duration: 0.3, options: .transitionCrossDissolve, animations: { sender.setImage(originalButtonImage, for: .normal) }, completion: nil) } }
Key Notes
- Adjust the delay time: Change
checkmarkDisplayDurationto make the checkmark show longer or shorter (e.g., 1.0 for a full second). - Animation options: The
.transitionCrossDissolvegives a smooth fade effect—you can try other options like.transitionFlipFromRightif you want a different animation style. - Double-check your image name: Make sure the checkmark image's name matches exactly what you have in your asset catalog (capitalization matters!).
This approach ensures the system has time to render the checkmark before starting the animation, so you'll see it clearly.
内容的提问来源于stack exchange,提问作者Paul S.

