更新数组对象并显示在collectionView中
Update array Object and display it in collectionView
我在 tableView 中有一个机器名称和类型的列表,当用户单击它时,它会推送到 detailVC。
起初用户没有图像,然后用户从图库中选择图像并将其作为 PHAssets return。
然后我将 PHAssets 转换为数据并将其显示在 collectionView 中,因此我创建了一个数据数组并将其显示在 collectionView 中。
我想将 MachineItem 对象更新为来自 PHAssets 的数据,因为 MachineItem 对象中有一个数据数组。
所以当用户 return 来自 tableView 中的机器列表时,对象已经更新。但是当我从 tableView 中点击列表时。我保存在对象中的照片没有显示,如何在我的 collectionView 中显示它。
这是我的模特
struct MachineItem: Codable {
var id = UUID().uuidString
var name: String
var type: String
var qrNumber = Int.random(in: 1..<10)
var maintenanceDate: String?
var images: [Data]?
}
这是我的 MachineStore class,它执行从 MachineItem
添加、更新和删除对象的所有操作
class MachineStore {
var items: [MachineItem] = []
@discardableResult func add(_ machine: MachineItem, at index: Int) -> MachineItem {
let newMachine = MachineItem(id: machine.id, name: machine.name, type: machine.type, qrNumber: machine.qrNumber, maintenanceDate: machine.maintenanceDate, images: machine.images)
items.insert(newMachine, at: index)
return newMachine
}
func update(_ machine: MachineItem) {
if let index = items.firstIndex(where: { [=11=].id == machine.id }) {
items[index].name = machine.name
items[index].type = machine.type
items[index].qrNumber = machine.qrNumber
items[index].maintenanceDate = machine.maintenanceDate
items[index].images = machine.images
}
}
@discardableResult func remove(at index: Int) -> MachineItem {
return items.remove(at: index)
}
}
这是我的 MachineDataVC,在 TableView 中有一个 MachineItem 对象列表
class MachineDataVC: UIViewController {
var tableView = UITableView()
var store = MachineStore()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = store.items[indexPath.row]
let detailVC = MachineDetailVC()
detailVC.item = item
detailVC.store = store
navigationController?.pushViewController(detailVC, animated: true)
tableView.deselectRow(at: indexPath, animated: true)
}
}
这是 detailVC,在从 MachineDataVC 返回到 detailVC 时我无法显示图像数据
class MachineDetailVC: UIViewController {
var item: MachineItem!
var store: MachineStore!
var images: [Data] = []
var photoCollectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
override func viewDidLoad() {
super.viewDidLoad()
// CollectionView setup
photoCollectionView.delegate = self
photoCollectionView.dataSource = self
photoCollectionView.register(MachineDetailCell.self, forCellWithReuseIdentifier: MachineDetailCell.cellID)
photoCollectionView.backgroundColor = .systemBackground
}
// This where PHAssets being retrieve
@objc func pickPhotos() {
let imagePickerVC = ImagePickerController()
imagePickerVC.settings.selection.max = 10
imagePickerVC.settings.theme.selectionStyle = .numbered
imagePickerVC.settings.fetch.assets.supportedMediaTypes = [.image]
imagePickerVC.settings.selection.unselectOnReachingMax = true
self.presentImagePicker(imagePickerVC) { (assets) in
} deselect: { (_) in
} cancel: { (_) in
} finish: { (assets) in
self.images = self.getImage(from: assets)
self.photoCollectionView.reloadData()
}
}
private func getImage(from assets: [PHAsset]) -> [Data] {
let images = assets.map { fetchImage(from: [=13=]) }
print("Pick image:", images)
return images
}
private func fetchImage(from asset: PHAsset) -> Data {
let manager = PHImageManager.default()
let options = PHImageRequestOptions()
options.isSynchronous = true
var thumbnail = Data()
manager.requestImage(for: asset, targetSize: .init(width: 100, height: 100), contentMode: .aspectFill, options: options) { (result, info) in
if let selectedImage = result?.data {
thumbnail = selectedImage
}
}
return thumbnail
}
// This is how I setup collectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MachineDetailCell.cellID, for: indexPath) as! MachineDetailCell
let image = images[indexPath.row]
cell.set(imageData: image)
return cell
}
// This is how I save the object from UIBarButtonItem
@objc func saveItem() {
guard let name = machineNameTF.text else { return }
guard let type = machineTypeTF.text else { return }
guard let date = machineMaintenanceDateTF.text else { return }
let machineItem = MachineItem(id: item.id, name: name, type: type, qrNumber: item.qrNumber, maintenanceDate: date, images: images)
store.update(machineItem)
}
}
到目前为止我一直在尝试的是这样的
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if !images.isEmpty {
return store.items.count
} else {
return images.count
}
}
如果有人能帮助我,我很高兴:)
我终于从我的问题中找到了答案,我需要做的是在我的 viewDidLoad 中我需要添加到我的 MachineDetailVC
self.images = self.item.images ?? []
因为当我将数据保存回 machineStore 中的项目时,我需要将数据放入 MachineDetailVC 中的图像数组中
我在 tableView 中有一个机器名称和类型的列表,当用户单击它时,它会推送到 detailVC。
起初用户没有图像,然后用户从图库中选择图像并将其作为 PHAssets return。
然后我将 PHAssets 转换为数据并将其显示在 collectionView 中,因此我创建了一个数据数组并将其显示在 collectionView 中。
我想将 MachineItem 对象更新为来自 PHAssets 的数据,因为 MachineItem 对象中有一个数据数组。
所以当用户 return 来自 tableView 中的机器列表时,对象已经更新。但是当我从 tableView 中点击列表时。我保存在对象中的照片没有显示,如何在我的 collectionView 中显示它。
这是我的模特
struct MachineItem: Codable {
var id = UUID().uuidString
var name: String
var type: String
var qrNumber = Int.random(in: 1..<10)
var maintenanceDate: String?
var images: [Data]?
}
这是我的 MachineStore class,它执行从 MachineItem
添加、更新和删除对象的所有操作class MachineStore {
var items: [MachineItem] = []
@discardableResult func add(_ machine: MachineItem, at index: Int) -> MachineItem {
let newMachine = MachineItem(id: machine.id, name: machine.name, type: machine.type, qrNumber: machine.qrNumber, maintenanceDate: machine.maintenanceDate, images: machine.images)
items.insert(newMachine, at: index)
return newMachine
}
func update(_ machine: MachineItem) {
if let index = items.firstIndex(where: { [=11=].id == machine.id }) {
items[index].name = machine.name
items[index].type = machine.type
items[index].qrNumber = machine.qrNumber
items[index].maintenanceDate = machine.maintenanceDate
items[index].images = machine.images
}
}
@discardableResult func remove(at index: Int) -> MachineItem {
return items.remove(at: index)
}
}
这是我的 MachineDataVC,在 TableView 中有一个 MachineItem 对象列表
class MachineDataVC: UIViewController {
var tableView = UITableView()
var store = MachineStore()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = store.items[indexPath.row]
let detailVC = MachineDetailVC()
detailVC.item = item
detailVC.store = store
navigationController?.pushViewController(detailVC, animated: true)
tableView.deselectRow(at: indexPath, animated: true)
}
}
这是 detailVC,在从 MachineDataVC 返回到 detailVC 时我无法显示图像数据
class MachineDetailVC: UIViewController {
var item: MachineItem!
var store: MachineStore!
var images: [Data] = []
var photoCollectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
override func viewDidLoad() {
super.viewDidLoad()
// CollectionView setup
photoCollectionView.delegate = self
photoCollectionView.dataSource = self
photoCollectionView.register(MachineDetailCell.self, forCellWithReuseIdentifier: MachineDetailCell.cellID)
photoCollectionView.backgroundColor = .systemBackground
}
// This where PHAssets being retrieve
@objc func pickPhotos() {
let imagePickerVC = ImagePickerController()
imagePickerVC.settings.selection.max = 10
imagePickerVC.settings.theme.selectionStyle = .numbered
imagePickerVC.settings.fetch.assets.supportedMediaTypes = [.image]
imagePickerVC.settings.selection.unselectOnReachingMax = true
self.presentImagePicker(imagePickerVC) { (assets) in
} deselect: { (_) in
} cancel: { (_) in
} finish: { (assets) in
self.images = self.getImage(from: assets)
self.photoCollectionView.reloadData()
}
}
private func getImage(from assets: [PHAsset]) -> [Data] {
let images = assets.map { fetchImage(from: [=13=]) }
print("Pick image:", images)
return images
}
private func fetchImage(from asset: PHAsset) -> Data {
let manager = PHImageManager.default()
let options = PHImageRequestOptions()
options.isSynchronous = true
var thumbnail = Data()
manager.requestImage(for: asset, targetSize: .init(width: 100, height: 100), contentMode: .aspectFill, options: options) { (result, info) in
if let selectedImage = result?.data {
thumbnail = selectedImage
}
}
return thumbnail
}
// This is how I setup collectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MachineDetailCell.cellID, for: indexPath) as! MachineDetailCell
let image = images[indexPath.row]
cell.set(imageData: image)
return cell
}
// This is how I save the object from UIBarButtonItem
@objc func saveItem() {
guard let name = machineNameTF.text else { return }
guard let type = machineTypeTF.text else { return }
guard let date = machineMaintenanceDateTF.text else { return }
let machineItem = MachineItem(id: item.id, name: name, type: type, qrNumber: item.qrNumber, maintenanceDate: date, images: images)
store.update(machineItem)
}
}
到目前为止我一直在尝试的是这样的
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if !images.isEmpty {
return store.items.count
} else {
return images.count
}
}
如果有人能帮助我,我很高兴:)
我终于从我的问题中找到了答案,我需要做的是在我的 viewDidLoad 中我需要添加到我的 MachineDetailVC
self.images = self.item.images ?? []
因为当我将数据保存回 machineStore 中的项目时,我需要将数据放入 MachineDetailVC 中的图像数组中