我在核心数据中建立了一对多关系
相册可以保存许多图像
每次创建新相册时,都会加载相同的图像。我希望用户能够将不同的照片保存到每个相册
当我尝试加载数据时,我认为问题可能出在谓词上,但我不确定。抱歉,我发布了所有可能不相关的代码,但我想发布所有代码,以防万一我看不到别人可能抓到的东西。
我还想补充一点,当我单击相册单元格时添加NSPredicate的代码时,在集合视图中没有图像显示,但是当我在loadData()中注释了谓词的代码时,图像显示了起来我不知道为什么会这样。
class ViewController: UIViewController {
var fetchedResultsController: NSFetchedResultsController<PhotoAlbum>!
var contextApp = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var moc:NSManagedObjectContext! = nil
@IBOutlet weak var tableView: UITableView!
func setupFetchedResultsController() {
let fetchRequest:NSFetchRequest<PhotoAlbum> = PhotoAlbum.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "album", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: contextApp, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
}catch {
print(error)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.delegate = self
tableView.dataSource = self
setupFetchedResultsController()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupFetchedResultsController()
}
@IBAction func createNewAlbum(_ sender: UIBarButtonItem) {
presentnewAlbumAlert()
}
func presentnewAlbumAlert () {
let alert = UIAlertController(title: "New Album", message: "Enter a name for this album", preferredStyle: .alert)
// Create actions
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let saveAction = UIAlertAction(title: "Save", style: .default) { [weak self] action in
if let name = alert.textFields?.first?.text {
self?.addAlbumCell(name: name)
}
}
saveAction.isEnabled = false
// Add a text field
alert.addTextField { textField in
textField.placeholder = "Name"
NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: textField, queue: .main) { notif in
if let text = textField.text, !text.isEmpty {
saveAction.isEnabled = true
} else {
saveAction.isEnabled = false
}
}
}
alert.addAction(cancelAction)
alert.addAction(saveAction)
present(alert, animated: true, completion: nil)
}
func addAlbumCell(name: String) {
let album = PhotoAlbum(context: contextApp)
album.album = name
do {
try contextApp.save()
}catch{
print(error)
}
}
func deleteNote(at indexPath: IndexPath) {
let albumToDelete = fetchedResultsController.object(at: indexPath)
contextApp.delete(albumToDelete)
try? contextApp.save()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toCollection" {
if let indexPath = tableView.indexPathForSelectedRow {
let object = fetchedResultsController.object(at: indexPath)
(segue.destination as! PhotoViewController).album = object
}
}
}
} //标记:DATASOURCE
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section:
Int) -> Int {
return fetchedResultsController?.sections![section].numberOfObjects
?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let aNewalbum = fetchedResultsController.object(at: indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: "toCollection", for: indexPath)
cell.textLabel?.text = aNewalbum.album
return cell
}
}
//标记:删除
extension ViewController : UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultsController?.sections?.count ?? 1
}
}
// SETUP NSFetchedResultsControllerDelegate
extension ViewController : NSFetchedResultsControllerDelegate {
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete :
tableView.deleteRows(at: [indexPath!], with: .fade)
default:
break
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
let indexSet = IndexSet(integer: sectionIndex)
switch type {
case .insert:
tableView.insertSections(indexSet, with: .fade)
case .delete :
tableView.deleteSections(indexSet, with: .fade)
default:
break
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
tableView.reloadData()
}
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
tableView.reloadData()
}
}
集合视图的代码
class PhotoViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout , UIImagePickerControllerDelegate , UINavigationControllerDelegate {
var imageDataArray = [Images]()
var imageArray = [UIImage]()
var managedObjectContext:NSManagedObjectContext!
var mySelection:Int?
var album: PhotoAlbum!
@IBOutlet var collectionView: UICollectionView!
@IBAction func addImage(_ sender: Any) {
let picker:UIImagePickerController = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
picker.delegate = self
picker.allowsEditing = false
self.present(picker, animated: true, completion: nil)
}
// Setup the collection view
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: imageCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "thumbnail", for: indexPath) as! imageCollectionViewCell
let imageItem = imageDataArray[indexPath.row]
if let presentImage = UIImage(data: (imageItem.images as! Data) ){
cell.chosenImage.image = presentImage
mySelection = indexPath.row
imageArray.append(presentImage)
}
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageDataArray.count
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let pickedImage = (info[UIImagePickerController.InfoKey.originalImage] as? UIImage) {
picker.dismiss(animated: true) {
self.createImageContext(with: pickedImage)
self.imageArray.append(pickedImage)
}
}
}
//加载和保存图像
func loadData() {
let imageReqeust: NSFetchRequest<Images> = Images.fetchRequest()
let predicate = NSPredicate(format: "images.album == %@", album)
imageReqeust.predicate = predicate
// print(predicate.description)
do {
imageDataArray = try managedObjectContext.fetch(imageReqeust)
self.collectionView.reloadData()
}catch {
print("Could not load data from database \(error.localizedDescription)")
}
}
func createImageContext( with image: UIImage) {
let imageItem = Images(context: managedObjectContext!)
imageItem.images = NSData(data: image.jpegData(compressionQuality: 1.0)!) as Data
// imageItem.image = NSData(data: UIImageJPEGRepresentation(image, 0.3)!) as Data
do {
try self.managedObjectContext.save()
self.loadData()
}catch {
print("Could not save data \(error.localizedDescription)")
}
}
// ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addImage(_:)))
loadData()
// Do any additional setup after loading the view.
}
答案 0 :(得分:1)
在第二个视图控制器中,您无需从Core数据中获取图像,而是可以通过相册属性访问它们。
-(CIImage *)getBlurredImage:(CIImage *)img withAmount:(float)intensity {
CIFilter *blurFilter = [CIFilter filterWithName:@"CIDiscBlur"];
[blurFilter setValue:img forKey:kCIInputImageKey];
[blurFilter setValue:@(intensity) forKey:@"inputRadius"];
return blurFilter.outputImage;
}
-(CIImage *)getPixellatedImage:(CIImage *)img withAmount:(float)scale
{
CIFilter *pixilateFilter = [CIFilter filterWithName:@"CIPixellate"];
[pixilateFilter setValue:img forKey:kCIInputImageKey];
[pixilateFilter setValue:@(scale) forKey:@"inputScale"];
return pixilateFilter.outputImage;
}
保存新图像实例时,请不要忘记将其分配给相册
imageDataArray = Array(album.images)