ios - 将 IndexPath 行值传递给委托(delegate)函数而不是 Sender.tag 以删除图像项目 CollectionView Swift

标签 ios swift uitableview uicollectionview delegates

我正在使用 collectionView 来显示照片并委托(delegate)函数来查看自定义警报。 在照片上,我有用于删除照片的十字标记。我的委托(delegate)功能和显示项目都工作正常。 但是当我必须从服务器中删除照片时,我遇到了问题。因为我需要将准确的图像 ID 传递给 Web 服务以将其从服务器中删除。如果我使用 cell.tag,它会给我行值为 1,但实际 imgID 为 40992。如何将此值传递给我的删除委托(delegate)函数?

结构:

单元格项目显示 --tap gesture call removeImage func --- 自定义警报 -- 在删除按钮上 -- didDeleteButtonClicked 调用。

我在 cellForItem 中需要的主要值(value):

let imgId = AppData?.imageList?[indexPath.row].projectUnitImageId

照片 View Controller :

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellName, for: indexPath) as! PhotoCollectionViewCell

            if(indexPath.row < (AppData?.imageList?.count ?? 0)){
                cell.imageView.isHidden = false
                cell.closeIcon.isHidden = false
                cell.addIcon.isHidden = true
                let dic = AppData?.imageList?[indexPath.row].url ?? " "
                cell.imageView.image =  UIImage(url: URL(string: dic))


                let imgId = AppData?.imageList?[indexPath.row].projectUnitImageId
                print(imgId)

                cell.closeIcon.isUserInteractionEnabled = true
                cell.closeIcon.tag = imgId ?? 0
                deleteAlertView.delegate = self
                let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(removeImage(_:)))
                cell.closeIcon.addGestureRecognizer(tapGestureRecognizer)

            } else {
                cell.imageView.isHidden = true
                cell.closeIcon.isHidden = true
                cell.addIcon.isHidden = false
            }

            return cell
        }


        @objc func removeImage(_ sender: AnyObject){

            print(imgId)
            let fotoXib = Bundle.main.loadNibNamed("FotoDeleteAlert", owner: self, options: nil)
            let alertView = fotoXib?.first as! FotoDeleteAlert
            alertView.delegate = self
            self.view.addSubview(alertView)

        }


          //MARK: - Delegate Function

extension PhotoCollectionViewController: handleDeleteAction {

        func didDeleteButtonClicked(_ sender: UIButton) {

            print("delegate")
            let row = sender.tag
            print(row)

            // I have to call my delete webServices here and have to pass imgId
            deleteWebservices(imgId)


        }
    }

FotoAlert Xib 自定义提醒:

protocol handleDeleteAction {
    func didDeleteButtonClicked(_: UIButton)
}

@IBDesignable class FotoDeleteAlert: UIView {

    var delegate: handleDeleteAction?

    @IBOutlet weak var deleteBtn: UIButton!

    override func awakeFromNib() {
        super.awakeFromNib()
        layoutIfNeeded()
        deleteBtn.addTarget(self, action: #selector(didDelete(_:)), for: .touchUpInside)
    }

    @IBAction func didCancel(_ sender: Any) {
        removeFromSuperview()
    }

    @IBAction func didDelete(_ sender: UIButton) {

        self.delegate?.didDeleteButtonClicked(sender)
        removeFromSuperview()


    }
}

最佳答案

长话短说;

您设置了 cell.closeIcon 的标签,然后您使用了 FotoDeleteAlert 按钮的标签。

要修复你需要添加的内容


class FotoDeleteAlert: ... {
   ...

   func setButtonTag(imageId: Int) {
       button.tag = imageId
   }
}


 @objc func removeImage(_ sender: UIView){

    print(imgId)
    let fotoXib = Bundle.main.loadNibNamed("FotoDeleteAlert", owner: self, options: nil)
    let alertView = fotoXib?.first as! FotoDeleteAlert
    alertView.setButtonTag(imageId: sender.tag
    alertView.delegate = self
    self.view.addSubview(alertView)
}


extension PhotoCollectionViewController: handleDeleteAction {

        func didDeleteButtonClicked(_ sender: UIButton) {

            print("delegate")
            let imgId = sender.tag


            // I have to call my delete webServices here and have to pass imgId
            deleteWebservices(imgId)


        }
    }

现在让我们清理你的意大利面条代码

您的大部分 collectionView(_:, cellForItemAt: ) 都可以移动到 PhotoCollectionViewCell 中。 我不会通过 tag 发送 id,相反你可以创建自己的委托(delegate)

最后我会把它重写成这样的:

class Controller {
    func displayAlert(for info: PhotoInfo) {
        // I bet this code is invalid (view isn't correctly aligned

        let fotoXib = Bundle.main.loadNibNamed("FotoDeleteAlert", owner: self, options: nil)
        let alertView = fotoXib?.first as! FotoDeleteAlert
        alertView.delegate = self
        self.view.addSubview(alertView)
    }
}

extension Controller: UICollectionViewDelegate {
    func collectionView(
        _ collectionView: UICollectionView, 
        cellForItemAt indexPath: IndexPath
    ) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: cellName, for: indexPath
        ) as! PhotoCollectionViewCell

        let imgInfo: PhotoInfo? = AppData?.imageList?[indexPath.row]
        cell.display(info: imgInfo)
        cell.delegate = self

        return cell
    }
}

extension Controller: PhotoCollectionViewCellDelegate {
    func photoCollectionViewCell(didPressCloseBtn cell: PhotoCollectionViewCell) {
        guard let indexPath = collectionView.indexPath(for: cell) else { return }
        if let imgInfo: PhotoInfo = AppData?.imageList?[indexPath.row] {
            displayAlert(for: imgInfo)
        }
    }
}

extension Controller: FotoDeleteAlertDelegate {
    func fotoDeleteAlert(
        didPressDelete view: FotoDeleteAlert, for item: PhotoInfo?
    ) {
        guard let item: PhotoInfo = item else { return }
        deleteWebservices(item.projectUnitImageId)
    }

}

protocol PhotoCollectionViewCellDelegate: class {
    func photoCollectionViewCell(didPressCloseBtn: PhotoCollectionViewCell)
}

class PhotoCollectionViewCell: UICollectionViewCell {
    weak var delegate: PhotoCollectionViewCellDelegate?

    var closeIcon: UIButton! {
        didSet {
            button.addTarget(
                self, action: #selector(closeTap), for: .touchUpInside
            )
        }
    }


    func display(info: PhotoInfo?) {
        imageView.isHidden = info == nil
        closeIcon.isHidden = info == nil
        addIcon.isHidden = info != nil

        if let info = info {
            imageView.image =  UIImage(url: URL(string: info.url))
        }
    }

    @objc func closeTap() {
        delegate?.photoCollectionViewCell(didPressCloseBtn: self)
    }

}

protocol FotoDeleteAlertDelegate: class {
    func fotoDeleteAlert(
        didPressDelete view: FotoDeleteAlert, for item: PhotoInfo?
    )

}

class FotoDeleteAlert {
    weak var delegate: FotoDeleteAlertDelegate?

    var deleteButton: UIButton! {
        didSet {
            button.addTarget(
                self, action: #selector(deleteTap), for: .touchUpInside
            )
        }
    }

    private var item: PhotoInfo?

    func display(item: PhotoInfo) {
        self.item = item
    }

    @objc func deleteTap() {
        delegate?.fotoDeleteAlert(didPressDelete: self, for: item)
    }
}

关于ios - 将 IndexPath 行值传递给委托(delegate)函数而不是 Sender.tag 以删除图像项目 CollectionView Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59468208/

相关文章:

ios - 无法识别的选择器作为按钮发送到 Collection View 单元格的实例,该按钮将数据从按钮发送到另一个 View Controller

ios - 如何在 UITableView 中使用多个自定义单元格 (>1)

ios - 使用 CLLocationManager 减少获取位置的频率

ios - 类型 '_' 的值没有成员

ios - 如何为不同的 UITableView 部分使用不同的 TableView 单元格类

ios - 如何在 Swift 中隐藏/删除空 TableView 行?

ios - Swift 3 - .addTarget() 方法不触发选择器

ios - UITableView:reloadRows(at :)每次点击两次才能更新表并滚动

ios - 将数据从 ViewController 传递回根 ViewController?

ios - 在Xcode Simulator中切换“颜色混合层”的快捷方式是什么?