Newbie
Newbie

Reputation: 358

Delegate function in not invoke properly on delete CollectionView item Swift

I have created PhotoCollectionViewController which contains all photos fetched from server by using Alamofire. Now I want to implement delete function on photos. I have used tap-gesture for it. Created custom alert Xib and its successfully showing. Custom alert xib have two button cancel and Delete. On delete button I have create delegate but for some reason its not working even its not invoking properly. Actually I have to pass AppData?.imageList?[indexPath.row].projectUnitImageId which is imageID to delete it from server. Manually without delegation and webservice its working. But Once I have used delegate function not calling.

Issues:

Please anyone can guide me.

Xib FotoDeleteAlert & Delegate:

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: Any) {

        self.delegate?.didDeleteButtonClicked(sender as! UIButton)


    }
}

PhotoCollectionViewController:

let deleteAlertView: FotoDeleteAlert? = nil  // defined on the top

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
                cell.closeIcon.isUserInteractionEnabled = true
                cell.closeIcon.tag = indexPath.row
                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){

            deleteAlertView?.delegate = self
            let alert = FotoDeleteAlert.loadViewFromNib()
            alert!.frame = self.view.bounds
            self.view.addSubview(alert!)

        }


//MARK: - Delegate Function

    extension PhotoCollectionViewController: handleDeleteAction {

        func didDeleteButtonClicked(_ sender: UIButton) {
            // below code manual working without delegate and web services work.

            let row = sender.view.tag
            self.data?.remove(at: row.row)
            self.images?.remove(at: row.row)
            self.collectionView.reloadData()

        }
    }


Upvotes: 3

Views: 205

Answers (4)

Rakesh Patel
Rakesh Patel

Reputation: 1701

You are not initialise your AlertView. so first you have to initialise your alert view by frame.

as below:

@objc func removeImage(_ sender: AnyObject) {
        deleteAlertView = FotoDeleteAlert(frame: .zero)
        deleteAlertView?.delegate = self
        let alert = FotoDeleteAlert.loadViewFromNib()
        alert!.frame = self.view.bounds
        self.view.addSubview(alert!)
    }

then you have your target should assign in override func awakeFromNib() see below code:

@IBDesignable class FotoDeleteAlert: UIView {

    var delegate: handleDeleteAction?
    @IBOutlet weak var deleteBtn: UIButton!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

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

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

    @IBAction func didDelete(_ sender: Any) {
        self.delegate?.didDeleteButtonClicked(sender as! UIButton)
    }
}

Upvotes: 0

Newbie
Newbie

Reputation: 358

Thank you everyone. I have rectified the issue and it was xib as it's not loading properly so I changed the code for it.

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

Upvotes: 0

Aqeel Ahmad
Aqeel Ahmad

Reputation: 757

Relace your removeImage function with followng

@objc func removeImage(_ sender: AnyObject){


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

}

Upvotes: 1

giorashc
giorashc

Reputation: 13713

In this method:

@objc func removeImage(_ sender: AnyObject){
            deleteAlertView?.delegate = self
            let alert = FotoDeleteAlert.loadViewFromNib()
            alert!.frame = self.view.bounds
            self.view.addSubview(alert!)
        }

you are setting the delegate on an uninitialized alert view (which will be nil at this point). Set the delegate on the created alert:

 let alert = FotoDeleteAlert.loadViewFromNib()
 alert!.frame = self.view.bounds
 alert!.delegate = self
 self.view.addSubview(alert!)

from your posted code I see no use for storing deleteAlertView

Upvotes: 0

Related Questions