我正在開發一個CollectionView
通過訪問用戶的照片庫將影像上傳到 a 的程式。到目前為止,它看起來很棒,并且大部分運行順利。
但是,當我退出應用程式并重繪 它時,曾經上傳的照片不再出現。
我只是有點熟悉Core Data
并且我一直在嘗試使用它,但是我的所有資源都沒有那么有用。
到目前為止,這是我的代碼:
import UIKit
import PhotosUI
import Photos
import CoreData
class ViewController: UIViewController, PHPickerViewControllerDelegate {
@IBOutlet var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// set up collection
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addPhotos))
collectionView.register(ClosetCollectionViewCell.nib(), forCellWithReuseIdentifier: "ClosetCollectionViewCell")
collectionView.delegate = self
collectionView.dataSource = self
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 125, height: 125)
collectionView.collectionViewLayout = layout
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
}
// access photo library
@objc private func addPhotos() {
var config = PHPickerConfiguration()
config.selectionLimit = 10
config.filter = .images
let vc = PHPickerViewController(configuration: config)
vc.delegate = self
present(vc, animated: true)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
let group = DispatchGroup()
results.forEach { result in
group.enter()
result.itemProvider.loadObject(ofClass: UIImage.self) { reading, error in
defer {
group.leave()
}
guard let image = reading as? UIImage, error == nil else {
return
}
// add to user's photo array
print(image)
imageArray.append(image)
}
}
group.notify(queue: .main) {
self.collectionView.reloadData()
}
}
}
// user images below
var imageArray = [UIImage]()
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
print("you tapped me!")
// when cell is tapped...
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// how many cells are shown? based on number of items the user uploaded
return imageArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// return cell for given item
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ClosetCollectionViewCell", for: indexPath) as! ClosetCollectionViewCell
cell.imageView.image = imageArray[indexPath.row]
return cell
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
// margin of padding between cells
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 115, height: 115)
}
}
我不知道從哪里開始!有任何想法嗎?
uj5u.com熱心網友回復:
對于您的問題,原因是您的應用在每次重繪 時都會丟失所有照片,因為它是臨時存盤但沒有保存在其他地方(互聯網或本地)。
如果要將其保存在自己的服務器上,請創建服務器端并使用 api。
來到本地這里,您已經找到了Core Data
要存盤的本地的正確路徑。但這里需要知道的關鍵點是:
- 將影像保存到本地應使用FileManager(這意味著每個應用程式在您的手機中都有自己的檔案檔案夾,因此不僅將影像保存到此處,還保存檔案、檔案和其他所有內容 - 只有當您的應用程式被卸載時它才會丟失)您只需要保留影像的名稱(您可以創建自己的名稱來保存影像)
代碼將是這樣的
func saveImage(imageName: String, image: UIImage) {
// get documentary path to save image to
guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let fileName = imageName
let fileURL = documentsDirectory.appendingPathComponent(fileName)
guard let data = image.jpegData(compressionQuality: 1) else { return }
//Checks if file exists, removes it if so.
if FileManager.default.fileExists(atPath: fileURL.path) {
do {
try FileManager.default.removeItem(atPath: fileURL.path)
print("Removed old image")
} catch let removeError {
print("couldn't remove file at path", removeError)
}
}
do {
try data.write(to: fileURL)
} catch let error {
print("error saving file with error", error)
}
}
func loadImageFromDiskWith(fileName: String) -> UIImage? {
let documentDirectory = FileManager.SearchPathDirectory.documentDirectory
let userDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(documentDirectory, userDomainMask, true)
if let dirPath = paths.first {
let imageUrl = URL(fileURLWithPath: dirPath).appendingPathComponent(fileName)
let image = UIImage(contentsOfFile: imageUrl.path)
return image
}
return nil
}
接下來是Core Data
或UserDefaults
是您保存密鑰的位置連接到您之前保存的名稱影像串列。所以每次你進入應用程式時,只需從鍵中取出串列影像名稱并再次出現
我會用UserDefaults
你做的,可以嘗試用CoreData
. 我將影像保存為名稱是數字,所以我UserDefault
只保存影像的數量。您可以更改為您想要的內容
代碼將是這樣的
var imageArray = [UIImage]()
var countImage = 0
override func viewDidLoad() {
super.viewDidLoad()
// get number of image have been saved
let countImage = UserDefaults.standard.integer(forKey: "test")
if countImage < 1 {
return
}
for i in 1...countImage {
// get image from disk
imageArray.append(self.loadImageFromDiskWith(fileName: String(i))!)
}
print(imageArray)
self.collectionView.reloadData() // reload collection view
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
let group = DispatchGroup()
results.forEach { result in
group.enter()
result.itemProvider.loadObject(ofClass: UIImage.self) { reading, error in
defer {
group.leave()
}
guard let image = reading as? UIImage, error == nil else {
return
}
// add to user's photo array
print(image)
self.imageArray.append(image)
// append self.countImage to 1 and save number to UserDefault and image to FileManager
self.countImage = 1
UserDefaults.standard.set(self.countImage, forKey: "test")
self.saveImage(imageName: String(self.countImage), image: image)
}
}
group.notify(queue: .main) {
self.collectionView.reloadData()
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/512857.html
上一篇:在嵌套JSON中決議Swift時出錯(JSON序列化)
下一篇:在組合接收器中呼叫并發的簡寫?