从UICollectionViewCell中删除单元格和相应的图像?

时间:2017-09-21 13:00:05

标签: ios swift uiimageview uicollectionview uicollectionviewcell

我的横向UICollectionView带有自定义UICollectionViewCell。每个单元格都有UIImageView,显示用户选择的图像。 现在,我想要做的是在每个单元格的角落添加一个删除按钮(或图像?),当它被点击时,它会从数组和单元格本身中删除相应的图像。我有两个问题:

  1. 如何以编程方式添加该按钮/图像功能(我真的不想弄乱故事板)
  2. 如何从相应的UIViewController
  3. 实现删除功能

    这样的事情:

    enter image description here

    这是我的Custom Cell课程:

    class PhotoCell: UICollectionViewCell, UIGestureRecognizerDelegate
    {
        @IBOutlet weak var cellImage: UIImageView!
    
        override func awakeFromNib()
        {
            super.awakeFromNib()
            setupUI()
        }
    
        func setupUI()
        {
            cellImage.layer.cornerRadius = 5
            cellImage.clipsToBounds = true
            cellImage.contentMode = .scaleAspectFill
        }
    }
    

    这是整个View Controller的代码

       import UIKit
        import SDWebImage
        import Photos
        import AssetsPickerViewController
        import SVProgressHUD
    
        class PhotoVC: UIViewController
        {
            // MARK: IBOutlets
            @IBOutlet weak var collectionView: UICollectionView!
            @IBOutlet weak var postButton: UIButton!
            @IBOutlet weak var userProfileImage: UIImageView!
            @IBOutlet weak var userUsername: UsernameLabel!
            @IBOutlet weak var postTitleTextField: UITextField!
            @IBOutlet weak var postContentTextField: UITextView!
            @IBOutlet weak var postTagsTextField: UITextField!
            @IBOutlet weak var postSourceTextField: UITextField!
    
            // MARK: Class Properties
            var user: UserModel!
            var post: Post!
            var cameraPhotoUIImage: UIImage?
            var assets = [PHAsset]()
            lazy var assetsTurnedIntoImages =
            {
                return  [UIImage]()
            }()
    
            lazy var imageManager = {
                return PHCachingImageManager()
            }()
    
            // MARK: View Did Load
            override func viewDidLoad()
            {
                self.assetsTurnedIntoImages = [UIImage](repeating: UIImage(), count: assets.count) // Important! make sure to have enough pre-created space in the array
                super.viewDidLoad()
                setupCollectionView()
            }
    
            // MARK: View Did Appear
            override func viewDidAppear(_ animated: Bool) {
                super.viewDidAppear(animated)
                fetchUserUsernameAndProfileImage()
                userProfileImageSetup()
                handlePostButtonState()
                collectionView.reloadData()
            }
    
            // MARK: View Will Disappear
            override func viewWillDisappear(_ animated: Bool) {
                super.viewWillDisappear(animated)
                emptyArrays()
             }
    
            // MARK: Fetch User Username And Profile Photo
            func fetchUserUsernameAndProfileImage()
            {
                Api.User.observeCurrentUser
                { (userModel) in
                    self.user = userModel
                    self.userUsername.text = userModel.username_lowercase!
                    if let userProfileImageURL = URL(string: userModel.profileImageUrlString!)
                    {
                        self.userProfileImage.sd_setImage(with: userProfileImageURL, placeholderImage: UIImage(named: "default_profileHeader"))
                    }
                }
            }
    
            // MARK: Cancel Pressed
            @IBAction func cancelPressed(_ sender: UIButton)
            {
                emptyArrays()
                collectionView.reloadData()
                dismiss(animated: true, completion: nil)
            }
    
            // MARK: Post Pressed
            @IBAction func postPressed(_ sender: UIButton)
            {
                guard let title = postTitleTextField.text else { return }
                guard let content = postContentTextField.text else { return }
                guard let tags = postTagsTextField.text else { return }
                guard let source = postSourceTextField.text else { return }
    
                view.endEditing(true)
                SVProgressHUD.setDefaultMaskType(.gradient)
                SVProgressHUD.show(withStatus: "Posting...")
                print("Assets turned into images before posting is:", assetsTurnedIntoImages.count)
                if let takenImage = cameraPhotoUIImage
                {
                    let imageToUpload = takenImage
    
                    if let imageData = UIImageJPEGRepresentation(imageToUpload, 0.1)
                    {
                        let ratio: [CGFloat] = [imageToUpload.size.width / imageToUpload.size.height]
                        DatabaseService.uploadDataToServer(data: imageData, videoUrl: nil, multipleImages: nil, ratio: ratio, title: title, content: content, tags: tags, source: source,
                                                           onSuccess:
                                                           {
                                                                self.clean()
                                                                self.performSegue(withIdentifier: Segue_PhotoPostToTabbar, sender: nil)
                                                           })
                    }
                }
                else if assetsTurnedIntoImages.count > 0
                {
                    DatabaseService.uploadDataToServer(data: nil, videoUrl: nil, multipleImages: assetsTurnedIntoImages, ratio: nil, title: title, content: title, tags: tags, source: source,
                                                       onSuccess:
                                                       {
                                                        self.clean()
                                                        self.performSegue(withIdentifier: Segue_PhotoPostToTabbar, sender: nil)
                                                       })
                }
                else
                {
                    SVProgressHUD.showError(withStatus: "At least 1 photo is required to make this post.")
                }
            }
    
            @IBAction func settingsPressed(_ sender: UIButton)
            {
                //TODO: Work on settings for the post
            }
    
            // MARK: End Editing
            override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
            {
                view.endEditing(true)
            }
    
            // MARK: Clean Text Fields And Arrays
            func clean()
            {
                postTitleTextField.text = ""
                postTagsTextField.text = ""
                postContentTextField.text = ""
                postSourceTextField.text = ""
                emptyArrays()
            }
    
            // MARK: Empty Arrays
            func emptyArrays()
            {
                assets.removeAll()
                assetsTurnedIntoImages.removeAll()
                cameraPhotoUIImage = nil
                collectionView.reloadData()
            }
    
            // MARK: Handle Post Button State
            func handlePostButtonState()
            {
                if cameraPhotoUIImage != nil || assets.count > 0
                {
                    postButton.isEnabled = true
                }
                else
                {
                    postButton.isEnabled = false
                }
            }
    
            // MARK: User Profile UI Update
            func userProfileImageSetup()
            {
                userProfileImage.layer.cornerRadius = userProfileImage.frame.size.width / 2
                userProfileImage.clipsToBounds = true
            }
    
        }
    
        // MARK: Collectionew View Delegate & Datasourse
        extension PhotoVC : UICollectionViewDataSource, UICollectionViewDelegate
        {
            func setupCollectionView()
            {
                collectionView.dataSource = self
                collectionView.delegate = self
            }
    
            func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
            {
                    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoPostCVCell", for: indexPath) as! PhotoPostCVCell
                    if let takenImage = cameraPhotoUIImage
                    {
                        cell.cellImage.image = takenImage
                    }
                    if assets.count > 0
                    {
                        let asset = assets[indexPath.row]
    
                        var imageRequestOptions: PHImageRequestOptions
                        {
                            let options = PHImageRequestOptions()
                            options.version = .current
                            options.resizeMode = .exact
                            options.deliveryMode = .fastFormat
                            options.isSynchronous = true
                            return options
                        }
                        // TODO: Fix the size of the images. Right now it's 500x500
                        let targetSize = CGSize(width: 500, height: 500)
                        imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: imageRequestOptions)
                        { (image, info) in
                            if image != nil
                            {
                                print(image!.size)
                                cell.cellImage.image = image
                                self.assetsTurnedIntoImages[indexPath.row] = image!
                                cell.deleteButton?.tag = indexPath.row
                                cell.deleteButton?.addTarget(self, action: #selector(self.deleteImage(sender:)), for: UIControlEvents.touchUpInside)
                            }
                        }
                    }
                    return cell
            }
    
            @objc func deleteImage(sender:UIButton) {
                let i = sender.tag
                print(i)
                assetsTurnedIntoImages.remove(at: i)
                collectionView.reloadData()
            }
    
            func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
            {
                if assetsTurnedIntoImages.count > 0
                {
                    return assetsTurnedIntoImages.count
                }
                else
                {
                    return 1
                }
            }
    
            // MARK: Preview Selected Image
            func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
            {
                let postStoryboard = UIStoryboard(name: Storyboard_Post, bundle:nil)
    
                if let destinationVC = postStoryboard.instantiateViewController(withIdentifier: "PreviewImageVC") as? PreviewImageVC
                {
                    destinationVC.allowedDismissDirection = .both
                    destinationVC.maskType = .clear
                    if cameraPhotoUIImage != nil
                    {
                        destinationVC.transferedImageToPreview = cameraPhotoUIImage!
                        destinationVC.showInteractive()
                    }
                    if assetsTurnedIntoImages.count > 0
                    {
                        destinationVC.transferedImageToPreview = assetsTurnedIntoImages[indexPath.row]
                        destinationVC.showInteractive()
                    }
    
                }
            }
        }
    

2 个答案:

答案 0 :(得分:0)

你好这里有两个类作为演示(借用懒惰代码)

    import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var myCollectionView: UICollectionView!
    var dataForDemo = [0,1,2,3,4,5,6,7,8,9,10]

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

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

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataForDemo.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionCell", for: indexPath) as! MyCollectionCell
        cell.myTitlteLabel.text = String(dataForDemo[indexPath.item])

        cell.callback = callbackForCell() // option callback
//        cell.buttonX.tag = indexPath.item  // option button tag
        return cell
    }

    func callbackForCell() -> ((MyCollectionCell)->Void){ // option callback
        return { [weak self] cell in
            guard let `self` = self else { return }
            guard let index = self.myCollectionView.indexPath(for: cell) else { return }

            self.dataForDemo.remove(at: index.item)
            self.myCollectionView.reloadData()
        }
    }

    @IBAction func buttonAction(_ sender: UIButton) { // option button tag
//        self.dataForDemo.remove(at: sender.tag)
//        self.myCollectionView.reloadData()
    }

}

和细胞类:

class MyCollectionCell: UICollectionViewCell {

    var callback : ((MyCollectionCell)->Void)?  // option callback
    @IBOutlet weak var buttonX: UIButton!   // option button tag
    @IBOutlet weak var myTitlteLabel: UILabel!
    @IBAction func removeButtonAction(_ sender: Any) {
        callback?(self)
    }
}

故事板看起来像这样:

enter image description here

所以这里有两个关于你如何做到这一点的选择。一个是回调,另一个是按钮上的标签。

我个人更喜欢带有回调块的那个。

答案 1 :(得分:0)

这很容易实现。将UIButton添加到左上角的单元格xib中,该xib仅与图像视图部分重叠。添加约束。然后将此按钮的插座连接到您的手机类:称之为deleteButton

您可以将故事板中按钮的图像设置为此图像:https://i.stack.imgur.com/lGpjY.png

代码可以如下:

class CustomCell: UICollectionViewCell {

    @IBOutlet weak var deleteButton: UIButton!

}

在集合视图控制器中:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CustomCell
    cell.deleteButton?.tag = indexPath.row
    cell.deleteButton?.addTarget(self, action: #selector(deleteUser(sender:)), for: UIControlEvents.touchUpInside)
    // Do other cell setup here with data source
    return cell
}

@objc func deleteUser(sender:UIButton) {
    let i = sender.tag
    dataSource.remove(at: i)
    collectionView.reloadData()
}

此处,dataSource是用于填充每个单元格的模型数组。

我希望这会有所帮助。