Ios 在collectionView中的特定位置移除特定单元格
我有一个应用程序,当用户提交某个“挑战”的图片时,它会将该挑战从包含许多挑战列表的collectionView中删除。目前,为了确定完成了哪个质询,我手动为7个单元格中的每一个分配了一个ID,这些单元格直接对应于它们的索引(第一个单元格的ID为0,索引为0)。有了这些信息,一旦我回到带有collectionView的视图,它就会通过从数据数组中删除该项并重新加载collectionView来删除该索引处的对象。问题是,一旦我删除了一个单元格,索引就会与原始索引/ID不同,这意味着它随后删除了错误的单元格 如何通过查找CustomCell类中实现的单元格的唯一id来确定实际删除哪个单元格 在代码中,WeeklyViewController是持有挑战集合视图的VCIos 在collectionView中的特定位置移除特定单元格,ios,swift,uicollectionview,uicollectionviewcell,Ios,Swift,Uicollectionview,Uicollectionviewcell,我有一个应用程序,当用户提交某个“挑战”的图片时,它会将该挑战从包含许多挑战列表的collectionView中删除。目前,为了确定完成了哪个质询,我手动为7个单元格中的每一个分配了一个ID,这些单元格直接对应于它们的索引(第一个单元格的ID为0,索引为0)。有了这些信息,一旦我回到带有collectionView的视图,它就会通过从数据数组中删除该项并重新加载collectionView来删除该索引处的对象。问题是,一旦我删除了一个单元格,索引就会与原始索引/ID不同,这意味着它随后删除了错误
import UIKit
struct CustomData {
var img: UIImage
var points: String
var mainLabel: String
var timeText: String
var score: String
var region: String
var lineStaticImage: UIImage
var subtitle: String
var challengeID: Int
}
class WeeklyViewController: UIViewController {
var n = Int()
var selImage = UIImage()
var recievedCompleteChallengeID = Int()
var recivedCompleteChallengeBool = Bool()
@IBOutlet weak var descLabel: UILabel!
var data = [CustomData]()
func completer() {
var masterchallengeList = ["Turn the lights of when you leave the room", "Turn the A/C off when you leave the house/room", "Compost your food from a couple of meals", "Don't let the run the water when brushing", "Walk, Bike, or Run to work, school, or your house", "Tell a friend to practice composting", "Take a walk around your neighborhood"]
var masterSubtitles = ["This week, whenever you leave the room, remember to take a look at the lights and determine whether they can be turned off...and then do it!", "When you leave your house or a section of your household, make it a point to turn off the fan/air-conditioning if it doesn't need to stay running", "Try looking up fun and interesting composting techniques and practice them with a few meal scraps", "Make sure to only use the water when you actually need it while brushing, and not when you are blankly staring into the mirror", "Try to avoid using your car or any mode of transport that uses gasoline; rather, hop on your bike, skateboard, or your own feet", "Once you figured out how you want to compost meal scraps, share it with a friend and ask them to send you a picture", "Many times, we forget that there can be an adventure other than our phones and computers, so open the door and go around your neighborhood" ]
data = [
CustomData(img: #imageLiteral(resourceName: "green"), points: "5", mainLabel: masterchallengeList[0], timeText: "⏰ Ends at midnight", score: "+\(Int.random(in: 1 ..< 50))", region: "Community", lineStaticImage: #imageLiteral(resourceName: "blueline"), subtitle: masterSubtitles[0], challengeID: 0),
CustomData(img: #imageLiteral(resourceName: "green"), points: "5", mainLabel: masterchallengeList[1], timeText: "⏰ Ends at midnight", score: "+\(Int.random(in: 1 ..< 50))", region: "Carbon Footprint", lineStaticImage: #imageLiteral(resourceName: "blueline"), subtitle: masterSubtitles[1], challengeID: 1),
CustomData(img: #imageLiteral(resourceName: "green"), points: "5", mainLabel: masterchallengeList[2], timeText: "⏰ Ends at midnight", score: "+\(Int.random(in: 1 ..< 50))", region: "Community", lineStaticImage: #imageLiteral(resourceName: "blueline"), subtitle: masterSubtitles[2],challengeID: 2),
CustomData(img: #imageLiteral(resourceName: "green"), points: "5", mainLabel: masterchallengeList[3], timeText: "⏰ Ends at midnight", score: "+\(Int.random(in: 1 ..< 50))", region: "Carbon Footprint", lineStaticImage:#imageLiteral(resourceName: "blueline"), subtitle: masterSubtitles[3],challengeID: 3),
CustomData(img: #imageLiteral(resourceName: "green"), points: "5", mainLabel: masterchallengeList[4], timeText: "⏰ Ends at midnight", score: "+\(Int.random(in: 1 ..< 50))", region: "Community", lineStaticImage: #imageLiteral(resourceName: "blueline"), subtitle: masterSubtitles[4],challengeID: 4),
CustomData(img: #imageLiteral(resourceName: "green"), points: "5", mainLabel: masterchallengeList[5], timeText: "⏰ Ends at midnight", score: "+\(Int.random(in: 1 ..< 50))", region: "Carbon Footprint", lineStaticImage: #imageLiteral(resourceName: "blueline"), subtitle: masterSubtitles[5],challengeID: 5)
]
}
fileprivate let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.register(CustomCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
completer()
view.addSubview(collectionView)
collectionView.backgroundColor = .clear
collectionView.topAnchor.constraint(equalTo: descLabel.bottomAnchor, constant: 40).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40).isActive = true
collectionView.contentInset.left = 20
collectionView.delegate = self
collectionView.dataSource = self
print(recivedCompleteChallengeBool)
print(recievedCompleteChallengeID)
}
override func viewDidAppear(_ animated: Bool) {
challengeRemover()
}
func challengeRemover() {
if recivedCompleteChallengeBool {
data.remove(at: recievedCompleteChallengeID)
collectionView.reloadData()
print("removed at \(recievedCompleteChallengeID)")
}
}
}
extension WeeklyViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 250, height: 400)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
cell.data = self.data[indexPath.row]
cell.backgroundColor = UIColor.init(red: 92, green: 219, blue: 149, alpha: 1)
cell.layer.cornerRadius = 30.0
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
n = indexPath.row
print("selected obj at \(n)")
performSegue(withIdentifier: "challengeSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var detailController = segue.destination as! SecondChallengeViewController
detailController.dataValues = "\(data[n])"
detailController.regionR = data[n].region
detailController.titleLabelLabel = data[n].mainLabel
detailController.points = data[n].score
detailController.subLabel = data[n].subtitle
detailController.receiverChallengeID = data[n].challengeID
}
@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {}
}
class CustomCell: UICollectionViewCell {
var id = Int()
var data: CustomData? {
didSet{
guard let data = data else { return }
bg.image = data.img
aa.text = data.mainLabel
timetext.text = data.timeText
scoreText.text = data.score
region.text = data.region
lineView.image = data.lineStaticImage
id = data.challengeID
}
}
fileprivate let bg: UIImageView = {
let iv = UIImageView()
iv.image = #imageLiteral(resourceName: "carousel3")
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.layer.cornerRadius = 30.0
return iv
}()
fileprivate let aa: UILabel = {
let iv = UILabel()
iv.text = "furf"
iv.numberOfLines = 0
iv.font = UIFont.systemFont(ofSize: 22, weight: .bold)
iv.layer.frame = CGRect(x: 0, y: 0, width: 220, height: 100)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
iv.isEnabled = true
iv.textColor = UIColor.init(red: 3/255, green: 29/255, blue: 59/255, alpha: 1)
iv.textAlignment = .natural
iv.sizeToFit()
iv.layer.backgroundColor = UIColor.clear.cgColor
return iv
}()
fileprivate let timetext: UILabel = {
let iv = UILabel()
iv.text = "timeText"
iv.numberOfLines = 0
iv.font = UIFont.systemFont(ofSize: 14, weight: .regular)
iv.layer.frame = CGRect(x: 0, y: 0, width: 220, height: 30)
iv.textColor = UIColor.init(red: 3/255, green: 29/255, blue: 59/255, alpha: 1)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
iv.textAlignment = .natural
iv.sizeToFit()
iv.layer.backgroundColor = UIColor.clear.cgColor
return iv
}()
fileprivate let scoreText: UILabel = {
let iv = UILabel()
iv.text = "scoreText"
iv.textColor = UIColor.init(red: 3/255, green: 29/255, blue: 59/255, alpha: 1)
iv.numberOfLines = 0
iv.font = UIFont.systemFont(ofSize: 20, weight: .bold)
iv.layer.frame = CGRect(x: 0, y: 0, width: 220, height: 50)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
iv.textAlignment = .natural
iv.sizeToFit()
iv.layer.backgroundColor = UIColor.clear.cgColor
return iv
}()
fileprivate let region: UILabel = {
let iv = UILabel()
iv.text = "regionText"
iv.textColor = UIColor.init(red: 3/255, green: 29/255, blue: 59/255, alpha: 1)
iv.numberOfLines = 0
iv.font = UIFont.systemFont(ofSize: 15, weight: .light)
iv.layer.frame = CGRect(x: 0, y: 0, width: 220, height: 50)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
iv.textAlignment = .natural
iv.sizeToFit()
iv.layer.backgroundColor = UIColor.clear.cgColor
return iv
}()
fileprivate let lineView: UIImageView = {
let iv = UIImageView()
iv.layer.frame = CGRect(x: 0, y: 0, width: 250, height: 20)
iv.contentMode = .scaleToFill
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
iv.sizeToFit()
return iv
}()
fileprivate let line2View: UIImageView = {
let iv = UIImageView()
iv.layer.frame = CGRect(x: 0, y: 0, width: 250, height: 20)
iv.contentMode = .scaleToFill
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
iv.sizeToFit()
return iv
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.contentView.addSubview(bg)
self.contentView.addSubview(aa)
self.contentView.addSubview(timetext)
self.contentView.addSubview(scoreText)
self.contentView.addSubview(region)
self.contentView.addSubview(lineView)
self.contentView.addSubview(line2View)
bg.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0).isActive = true
bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0).isActive = true
aa.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 40).isActive = true
aa.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15).isActive = true
aa.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -260).isActive = true
aa.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -15).isActive = true
timetext.topAnchor.constraint(equalTo: aa.bottomAnchor, constant: 230).isActive = true
timetext.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15).isActive = true
timetext.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
timetext.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -15).isActive = true
scoreText.topAnchor.constraint(equalTo: aa.bottomAnchor, constant: 30).isActive = true
scoreText.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15).isActive = true
scoreText.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -15).isActive = true
region.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 25).isActive = true
region.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15).isActive = true
region.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -15).isActive = true
lineView.topAnchor.constraint(equalTo: scoreText.bottomAnchor, constant: 140).isActive = true
lineView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0).isActive = true
lineView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0).isActive = true
line2View.topAnchor.constraint(equalTo: scoreText.bottomAnchor, constant: 137).isActive = true
line2View.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0).isActive = true
line2View.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
如何确定我必须删除哪张卡?您可以使用用户默认计数器创建一个userDefaults字典。每个新元素的计数器都会增加。计数器将是您在字典中的键,也是您的单元格标识符。然后将字典数据加载到单元格中,并删除删除每个单元格的字典键和值。重新加载数据时,单元格将仅为字典定义的单元格 此链接解释字典部分