Swift4中UITableView.reloadData不更新及ActivityIndicator未移除问题求助
Hey there, let's work through these two frustrating problems you're facing. I've run into similar UI update and indicator cleanup issues before, so here's what's likely going wrong and how to fix it:
1. Activity Indicator & Background View Won't Disappear
The root cause here is almost certainly in your UIView extension's activityStopAnimating() method. If the method only calls stopAnimating() on the indicator but doesn't remove the indicator and its background view from the view hierarchy, they'll stay visible even after the animation stops.
Fix: Update Your Extension to Clean Up Views
Make sure your stop method actively removes the views you added when starting the indicator. Using tags is a simple way to track these views:
extension UIView { func activityStartAnimating() { // Create and configure background view let backgroundView = UIView(frame: bounds) backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0.5) backgroundView.tag = 999 // Unique tag to identify it later // Create and configure activity indicator let indicator = UIActivityIndicatorView(style: .whiteLarge) indicator.center = backgroundView.center indicator.tag = 1000 // Unique tag for the indicator backgroundView.addSubview(indicator) addSubview(backgroundView) indicator.startAnimating() } func activityStopAnimating() { // Find and remove the background view if let backgroundView = viewWithTag(999) { backgroundView.removeFromSuperview() } // Find and clean up the indicator (extra safety) if let indicator = viewWithTag(1000) { indicator.stopAnimating() indicator.removeFromSuperview() } } }
This ensures both the indicator and its background are fully removed from your view when you call activityStopAnimating().
2. Collection View Isn't Updating
There are a few possible culprits here, but the most common one is using DispatchQueue.main.sync instead of async, plus a few quick checks to validate your setup:
Fix 1: Replace sync with async for UI Updates
Using DispatchQueue.main.sync can cause deadlocks (especially if your API callback is accidentally running on the main thread already) and block UI updates. Always use async for UI-related work:
// Inside your API completion handler yourAPIFetchCall { [weak self] fetchedData in guard let self = self else { return } // Populate your data array (make sure it's a var, not let!) self.yourDataArray = fetchedData // Switch to main thread safely with async DispatchQueue.main.async { self.CapsulleCollectionView.reloadData() self.view.activityStopAnimating() } }
Fix 2: Validate Your Collection View Setup
Double-check these critical points:
- Ensure
yourDataArrayis declared as a variable (var yourDataArray: [YourDataType] = []) — if it's a constant (let), it can't be updated. - Confirm your collection view's data source methods use this array:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return yourDataArray.count // Not a hardcoded number! } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCellID", for: indexPath) as! YourCellType let item = yourDataArray[indexPath.row] // Configure cell with item data return cell } - Verify your collection view's
IBOutletis properly connected in Interface Builder (check thatCapsulleCollectionViewisn'tnilby printing it before callingreloadData()). - Make sure you've set the collection view's
dataSourceanddelegatetoself(either in IB or inviewDidLoad()).
内容的提问来源于stack exchange,提问作者abdul sathar

