如何使用 Swift 将 ActivityIndi​​cator 放入 UITableView 中的 UIImage 中?

How to put ActivityIndicator inside UIImage inside UITableView using Swift?

我有 UITableView,其中每个单元格都有一个 UIImage,图像是使用 JSON 从 API 下载的。

我通过后台线程处理了初始图像和数据。然而,当用户在 table 视图中向下滚动时,其他单元格的图像开始下载,因此这些单元格需要一些刷新。

我考虑过在 UIImageView 中添加一个 ActivityIndi​​cator,这样用户会注意到正在下载图像。

附加信息,UIImageView 在 UIStackView 中。我想了isHidden方法,无法实现。

感谢您的宝贵时间。

通常我建议使用像 Kingfisher 这样的库来为你管理这个(我相信你可以设置一个占位符视图在你加载时显示)但是如果你想手动做这个你可能有类似

的东西
enum LoadingState {
    case notLoading
    case loading
    case loaded(UIImage)
}

class MyTableViewCell: UITableViewCell {
    let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    let imageStackView = UIStackView()
    let myImageView = UIImageView() // can't be named imageView because UITableViewCell already has one with that name

    var loadingState: LoadingState = .notLoading {  // many ways you could do this, you just need one or more "update" mechanisms to start/stop the spinner and set your image
        didSet {
            switch loadingState {
            case .notLoading:
                myImageView.image = nil
                activityIndicator.stopAnimating()
            case .loading:
                myImageView.image = nil
                activityIndicator.startAnimating()
            case let .loaded(img):
                myImageView.image = img
                activityIndicator.stopAnimating()
            }
        }
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        configure()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }

    private func configure() {
        contentView.addSubview(activityIndicator)
        contentView.addSubview(imageStackView)
        imageStackView.addArrangedSubview(myImageView)
        // constrain activity indicator and stack view
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        loadingState = .notLoading
    }
}