i haave problem i can't Pass ImageView From collection to viewcontroller using Firebase Database
This My Code
import UIKit
import Firebase
import FirebaseDatabase
import SDWebImage
import FirebaseStorage
import KRProgressHUD
class ViewControllerCollocation: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var MyColloctaion: UICollectionView!
var imagePicker = UIImagePickerController()
var images = [ImagePost]()
var dbRef:DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
setutxent()
designCollectionView()
imagePicker.delegate = self
dbRef = Database.database().reference().child("Images")
/////////
loadDB()
KRProgressHUD.set(style: .custom(background: .black, text: .white, icon: nil))
KRProgressHUD.show(withMessage: "Loading...")
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
KRProgressHUD.dismiss()
}
}
func loadDB(){
dbRef.observe(DataEventType.value, with: { (snapshot) in
var newImages = [ImagePost]()
for imageFireSnapshot in snapshot.children {
let ImagesFireObject = ImagePost(snapshot: imageFireSnapshot as! DataSnapshot)
newImages.append(ImagesFireObject)
}
self.images = newImages
self.MyColloctaion.reloadData()
}
)}
func collectionView(_ colloction: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
internal func collectionView(_ colloction: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = colloction.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! UploadOneCollectionViewCell
let image = images[indexPath.row]
cell.ImageView.layer.cornerRadius = 13
cell.ImageView.clipsToBounds = true
cell.ImageView.sd_setImage(with: URL(string: image.url), placeholderImage: UIImage(named: "Image1"))
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
func designCollectionView() {
let itemSize = UIScreen.main.bounds.width/3 - 3
let layout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
layout.itemSize = CGSize(width: itemSize, height: 230)
layout.minimumInteritemSpacing = 1
layout.minimumLineSpacing = 1
//layout.scrollDirection = .horizontal
self.MyColloctaion.isPagingEnabled = true
MyColloctaion.collectionViewLayout = layout
}
func steupbar(){
navigationController?.navigationBar.barTintColor = UIColor.black
tabBarController?.tabBar.barTintColor = UIColor.black
self.navigationController?.navigationBar.titleTextAttributes =
[NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont(name: "Baskerville-BoldItalic", size: 21)!]
}
#IBAction func Upload(_ sender: Any) {
imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
}
func generateRandom(size: UInt) -> String {
let prefixSize = Int(min(size, 43))
let uuidString = UUID().uuidString.replacingOccurrences(of: "-", with: "")
return String(Data(uuidString.utf8)
.base64EncodedString()
.replacingOccurrences(of: "=", with: "")
.prefix(prefixSize))
}
}
this is My ""ImagePost.swift"""
import Foundation
import FirebaseDatabase
struct ImagePost {
let key: String!
let url:String!
let itemRef:DatabaseReference?
init(url:String, key:String) {
self.key = key
self.url = url
self.itemRef = nil
}
init(snapshot:DataSnapshot) {
key = snapshot.key
itemRef = snapshot.ref
let snapshotValue = snapshot.value as? NSDictionary
if let imageUrl = snapshotValue?["url"] as? String {
url = imageUrl
}else{
url = ""
}
}
}
and This is My detail view
import UIKit
class VC1: UIViewController {
var imageURL : String?
#IBOutlet weak var ImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
and Thanks for your help guys!
You can pass image to detail view by getting image in didselect method:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let image = images[indexPath.row]
let vc = self.storyboard?.instantiateViewController(withIdentifier: "VC1") as! VC1
vc.imageObject = images[indexPath.row]
self.navigationController?.pushViewController(vc, animated: false)
}
Just create a variable as imageObject in VC1 and pass data to it as shown above.
Related
Hello Respected Comrades,
I made a gallery app. initially I get a data of media from phone.
but when i add some new photos to device. i cant see them until :
re install app
fetching in view will appear (this is just a temperory fix)
I want to update my data dynamically with respect to phone data
code:
import UIKit
import Foundation
import Photos
import CoreData
enum MediaType{
case video, photo
}
View model
class GalleryPageViewModel : BaseViewModel{
var mediaArray = Spectator<MediaArray?>(value:
[])
var title = "Gallery"
var appDelegate:AppDelegate?
var context : NSManagedObjectContext?
let responder : AppResponder
var tempMedia = [MediaModel]()
init(with responder:AppResponder){
self.responder = responder
super.init()
}
}
extension GalleryPageViewModel{
func populatePhotos(){
mediaArray.value = []
tempMedia = []
PHPhotoLibrary.requestAuthorization{ [weak self] status in
if status == .authorized{
let assets = PHAsset.fetchAssets(with: nil)
assets.enumerateObjects{ (object,_,_) in
var image = UIImage()
image = self!.conversionPhotoToImage(asset: object)
var mediaType : MediaType = .photo
if object.mediaType == .video{
mediaType = .video
}
let media = MediaModel(img: image, asset: object, mediaType: mediaType)
self?.tempMedia.append(media)
}
}
else{
print("auth failed")
}
self?.setUpData()
}
}
func conversionPhotoToImage(asset : PHAsset) -> UIImage{
let manager = PHImageManager.default()
var media = UIImage()
let requestOptions=PHImageRequestOptions()
requestOptions.isSynchronous=true
requestOptions.deliveryMode = .highQualityFormat
manager.requestImage(for: asset, targetSize: CGSize(width: 1000, height: 1000), contentMode:.aspectFill, options: requestOptions) { image,_ in
media = image!
}
return media
}
func setUpData(){
self.mediaArray.value = tempMedia
}
}
extension GalleryPageViewModel{
func numberOfItemsInSection() -> Int{
return mediaArray.value?.count ?? 0
}
func didSelectAtRow(index:IndexPath){
self.responder.pushToDetailVc(data: mediaArray.value![index.row])
}
}
extension GalleryPageViewModel{
func setUpCoreData(){
appDelegate = UIApplication.shared.delegate as! AppDelegate
context = appDelegate?.persistentContainer.viewContext
}
func storeInCoreData(){
let entity = NSEntityDescription.entity(forEntityName: "MediaData", in: context!)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
var i = 1
for data in mediaArray.value!{
newUser.setValue(data.img, forKey: "image")
newUser.setValue(data.duration, forKey: "duration")
newUser.setValue("data", forKey: "mediaType")
newUser.setValue(data.location, forKey: "location")
newUser.setValue(data.creationDate, forKey: "creationDate")
var id = String()
if data.mediaType == .photo{
id = "imgEn\(i)"
}
else{
id = "vidEn\(i)"
}
i+=1
newUser.setValue(id, forKey: "id")
}
}
}
View controller
import UIKit
import Photos
class GalleryPageViewController: BaseViewController {
var galleryCollectionView : UICollectionView?
var galleryCollectionViewFlowLayout : UICollectionViewFlowLayout? = nil
var viewModel: GalleryPageViewModel? {
didSet {
self.bindViewModel()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = viewModel?.title
view.backgroundColor = .systemBackground
setUpFlowLayout()
galleryCollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: galleryCollectionViewFlowLayout!)
galleryCollectionView?.register(MediaCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
setUpCollectionView()
viewConstraintsForGalleryPage()
viewModel?.populatePhotos()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
}
// MARK: - UI WORKS
extension GalleryPageViewController{
func setUpFlowLayout(){
galleryCollectionViewFlowLayout = UICollectionViewFlowLayout()
galleryCollectionViewFlowLayout?.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10)
galleryCollectionViewFlowLayout?.itemSize = CGSize(width: (view.frame.width/2) - 20, height: (self.view.frame.width/2)-10)
}
func setUpCollectionView(){
galleryCollectionView?.dataSource = self
galleryCollectionView?.delegate = self
}
func viewConstraintsForGalleryPage(){
// adding sub view to maintain heirarchy.
view.addSubview(galleryCollectionView!)
// constraints for views in this page
// collection view
galleryCollectionView?.translatesAutoresizingMaskIntoConstraints = false
// galleryCollectionView?.backgroundColor = .blue
galleryCollectionView?.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 10).isActive = true
galleryCollectionView?.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
galleryCollectionView?.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor,constant: 10).isActive = true
galleryCollectionView?.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
}
}
//MARK: - COLLECTION VIEW DELEGATE AND DATA SOURCE
extension GalleryPageViewController : UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// vc.data = viewModel?.mediaArray.value?[indexPath.row]
viewModel?.didSelectAtRow(index: indexPath)
}
}
extension GalleryPageViewController : UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewModel?.numberOfItemsInSection() ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MediaCollectionViewCell
let cellData = viewModel?.mediaArray.value?[indexPath.row]
cell.imageView.image = cellData?.img
if cellData?.mediaType == .video{
cell.playBtn.isHidden = false
cell.durationLabel.isHidden = false
let manager = PHImageManager.default()
manager.requestAVAsset(forVideo: (cellData?.asset)!, options: nil){asset,_,_ in
let duration = asset?.duration
let durationTime = CMTimeGetSeconds(duration!)
let finalTime = durationTime/60
DispatchQueue.main.async {
cell.durationLabel.text = "\(Int(finalTime)) : \(Int(durationTime) % 60)"
}
}
}
else{
cell.playBtn.isHidden = true
cell.durationLabel.isHidden = true
}
return cell
}
}
//MARK: - BINDING VARIABLES
extension GalleryPageViewController{
private func bindViewModel(){
viewModel?.mediaArray.bind { [weak self] _ in
print("i am gonna reload")
print(self?.viewModel?.mediaArray.value?.isEmpty)
DispatchQueue.main.async {
self?.galleryCollectionView?.reloadData()
}
}
}
}
I am new to iOS and trying to build an app to learn more. I'm stuck at the last stage of my application. I want to be able to swipe between two container views using segmented control. I want to add two overlapping container views (container views with an embed segue with child controller) of the same size on half screen in single controller like instagram profile. I want to add a tableview to both child controllers. When I run the app the data of the first child view should be seen but when I swipe left, the second child controller should be seen with same size and in the same position. I want this to be like an instagram profile.
Currently, when I swipe left the second child controller opens in full screen and hides everything else on that screen. I have tried various tutorials, but to no avail.
Can you help me to do this?
Thank You!
This is my view controller's code
// CODE //
{
//
// ViewController.swift
// BeautyParlor
//
// Created by Mohammad Affan Siddiqui on 20/11/2019.
// Copyright © 2019 Mohammad Affan Siddiqui. All rights reserved.
//
import UIKit
//import PinterestLayout
class ViewController: UIViewController {
#IBOutlet weak var SegmentedControl: UISegmentedControl!
#IBOutlet weak var thirdView: UIView!
#IBOutlet weak var collectionViewOutletPortfolio: UICollectionView!
#IBOutlet weak var collectionViewOutletAbout: UICollectionView!
#IBOutlet weak var secondView: UIView!
#IBOutlet weak var firstView: UIView!
#IBOutlet weak var collectionViewOutletStatic: UICollectionView!
// FOR STATIC DATA
var arrimgbackground = [UIImage]()
var arrimglogo = [UIImage]()
var arrimglocation = [UIImage]()
var arrimginsta = [UIImage]()
var arrlblname = ["ABC Saloon"]
var arrlblrating = ["Rating 4.5/5"]
var arrlbllocation = ["ABC,Street,karachi"]
var arrlblinsta = ["qqq"]
var arrlblservicename = ["We are serving you"]
var arrlblrs = ["Rs:200"]
// FOR ABOUT DATA
var arrlbldescription = ["Before you can begin to determine what the will grow. The whole process is an organic one—a natural progression from a seed to a full-blown "]
// FOR PORTFOLIO DATA
var arrimgportfolio = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
//
//
//
//
// setupSegmentedContrl()
setupHorizontalBar()
// let swipright = UISwipeGestureRecognizer(target: self, action: #selector(self.swipGesture))
// swipright.direction = UISwipeGestureRecognizer.Direction.right
// self.thirdView?.addGestureRecognizer(swipright)
// let rightSwipe = UISwipeGestureRecognizer(target: SegmentCotroller, action: Selector("swiped:"))
// rightSwipe.direction = .Right
// self.SegmentCotroller.addGestureRecognizer(rightSwipe)
//
let rightSwipe = UISwipeGestureRecognizer(target: self, action: Selector(("swiped:")))
rightSwipe.direction = .right
self.secondView?.addGestureRecognizer(rightSwipe)
// let swipright = UISwipeGestureRecognizer(target: self, action: #selector(self.swipGesture))
// swipright.direction = UISwipeGestureRecognizer.Direction.right
// self.secondView?.addGestureRecognizer(swipright)
//
//
// let layout = PinterestLayout()
// collectionViewOutletPortfolio.collectionViewLayout = layout
//
// layout.delegate = self
// layout.cellPadding = 5
// layout.numberOfColumns = 2
//
//
//
// if let layout = collectionViewOutletPortfolio?.collectionViewLayout as? PinterestLayout {
// layout.delegate = self as! PinterestLayoutDelegate
// }
//
thirdView?.isHidden = true
arrimgbackground = [#imageLiteral(resourceName: "d.png")]
arrimglogo = [#imageLiteral(resourceName: "roundimage.png")]
arrimglocation = [#imageLiteral(resourceName: "location.jpeg")]
arrimginsta = [#imageLiteral(resourceName: "insta.png")]
arrimgportfolio = [#imageLiteral(resourceName: "c.png"), #imageLiteral(resourceName: "d.png"), #imageLiteral(resourceName: "down.png"), #imageLiteral(resourceName: "down.png"), #imageLiteral(resourceName: "c.png"), #imageLiteral(resourceName: "c.png"), #imageLiteral(resourceName: "c.png"), #imageLiteral(resourceName: "c.png"), #imageLiteral(resourceName: "d.png"), #imageLiteral(resourceName: "d.png"), #imageLiteral(resourceName: "d.png"), #imageLiteral(resourceName: "d.png"), #imageLiteral(resourceName: "down.png"), #imageLiteral(resourceName: "down.png"), #imageLiteral(resourceName: "down.png")]
// setupSegmentedControl().topAnchor.constraintEqualToAnchor(topLayoutGuide)
}
private func setupHorizontalBar(){
}
private func setupSegmentedControl(){
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// SegmentedControl
}
// #objc func swipGesture(sender: UISwipeGestureRecognizer?){
// // #objc func swipeAction (swipe: UISwipeGestureRecognizer) {
// if let swipGesture = sender{
// switch swipGesture.direction {
// case UISwipeGestureRecognizer.Direction.right:
// print ("i just swip right")
// let redVC = UIViewController()
// redVC.view.backgroundColor = UIColor.red
// //self.navigationController?.popViewController(animated: true)
// //performSegue(withIdentifier: "goRight", sender: self)
// default:
// break
// }
// }
//
// }
// thirdView = uivi(frame: thirdView)
//self.collectionViewOutletPortfolio? = UICollectionView()
// ViewController.swipGesture(index: index)(index: index)
// case UISwipeGestureRecognizer.Direction.left:
// print ("i just swiped left")
////
// // arrlbl = UICollectionView()
// default:
// break
//
// }
// }
// FOR SWIPPING CHECK WORKING OR NOT
// #IBAction func swipBetweenViews(_ sender: UISwipeGestureRecognizer) {
// print ("HelowSwipped")
//
//}
#IBAction func switchViews(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0{
firstView.isHidden = false
secondView?.isHidden = false
thirdView?.isHidden = true
// firstView.alpha = 0
// secondView.alpha = 1
// thirdView.alpha = 0
//
}else{
firstView.isHidden = false
secondView?.isHidden = true
thirdView?.isHidden = false
// firstView.alpha = 0
// secondView.alpha = 0
// thirdView.alpha = 1
}
}
}
extension ViewController: UICollectionViewDataSource , UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (collectionView == collectionViewOutletStatic){
let cell = collectionViewOutletStatic.dequeueReusableCell(withReuseIdentifier: "cellone", for: indexPath)as! CollectionViewCellStatic
cell.imgbackground.image = arrimgbackground[indexPath.row]
cell.imglogo.image = arrimglogo[indexPath.row]
cell.imglocation.image = arrimglocation[indexPath.row]
cell.imginsta.image = arrimginsta[indexPath.row]
cell.lblname.text = arrlblname[indexPath.row]
cell.lblrating.text = arrlblrating[indexPath.row]
cell.lbllocation.text = arrlbllocation[indexPath.row]
cell.lblinstaname.text = arrlblinsta[indexPath.row]
cell.lblservicename.text = arrlblservicename[indexPath.row]
cell.lblrs.text = arrlblrs[indexPath.row]
return cell
}else{
if (collectionView == collectionViewOutletAbout){
let cello = collectionViewOutletAbout.dequeueReusableCell(withReuseIdentifier: "celltwo", for: indexPath)as! CollectionViewCellAbout
cello.lbldescription.text = arrlbldescription[indexPath.row]
return cello
}else{
let cellt = collectionViewOutletPortfolio?.dequeueReusableCell(withReuseIdentifier: "cellthree", for: indexPath)as! CollectionViewCellPortfolio
cellt.imgPortfolio.image = arrimgportfolio[indexPath.row]
return cellt
// THIS CODE FOR 3 COLUMNS OF IMAGES COLLECTION LIKE PORFOLIO
// _ = UIScreen.main.bounds.width/2-2
// let layout = UICollectionViewFlowLayout()
//
// collectionViewOutletPortfolio?.collectionViewLayout = layout
//
// layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
// // layout.itemSize = CGSize(width: itemSize, height: itemSize)
////
//// layout.minimumInteritemSpacing = 0
//// layout.minimumLineSpacing = 0
}
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// let x = CGFloat(indexPath.item) * frame.width
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (collectionView == collectionViewOutletStatic){
return arrimgbackground.count
}else{
if (collectionView == collectionViewOutletAbout){
return arrlbldescription.count
}else{
return arrimgportfolio.count
}
}
}
}
extension ViewController: UICollectionViewDelegateFlowLayout{
// THIS FOR 3 COLUMNS OF IMAGES IN CLLECTION VIEW CELL
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let collectionwidth = collectionView.bounds.width
return CGSize(width: collectionwidth/3, height: collectionwidth/3)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
}
//extension ViewController: PinterestLayoutDelegate{
// func collectionView(_ collectionView: UICollectionView, heightForItemAtIndexPath indexPath: IndexPath) -> CGSize {
// //return UIImage(named: row[indexPath.item].imageename)?.size
//
// }
//}
//
//extension ViewController: PinterestLayoutDelegate{
// func collectionView(_ collectionView: UICollectionView, heightForItemAtIndexPath indexPath: IndexPath) -> CGFloat {
// return 100
// }
//
//
//
// func collectionView(
// _ collectionView: UICollectionView,
// heightForPhotoAtIndexPath indexPath:IndexPath) -> CGFloat {
// return arrimgportfolio[indexPath.row]
// //return arrimgportfolio[indexPath.item].image.size.height
// }
This is the simple example that you want. This is design for full screen. I think you can get an idea and customize this for your requirement
class ContainerController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 13.0, *) {
view.backgroundColor = .systemBackground
} else {
view.backgroundColor = .white
}
navigationItem.titleView = sgControll
updateView()
sgControll.addTarget(self, action: #selector(segmentControllValueChanged (_:)), for:.valueChanged)
}
//MARK: Components
let sgControll:UISegmentedControl = {
let sg = UISegmentedControl()
sg.insertSegment(withTitle: "first Child", at: 0, animated: true)
sg.insertSegment(withTitle: "Second Child", at: 1, animated: true)
sg.selectedSegmentIndex = 0
return sg
}()
private lazy var secondView : SecondChildViewController = {
let vc = SecondChildViewController()
self.add(asChildViewController: vc)
return vc
}()
private lazy var firstView:FirstChildViewController = {
let vc = FirstChildViewwController()
self.add(asChildViewController: vc)
return vc
}()
}
//MARK: Functions
extension ContainerController {
#objc func segmentControllValueChanged(_ sender : UISegmentedControl){
print(sender.selectedSegmentIndex)
updateView()
}
private func add(asChildViewController viewController: UIViewController){
addChild(viewController)
view.addSubview(viewController.view)
viewController.view.translatesAutoresizingMaskIntoConstraints = false
viewController.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
viewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
viewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
viewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
viewController.didMove(toParent: self)
}
private func remove(asChildViewController viewController: UIViewController) {
viewController.willMove(toParent: nil)
viewController.view.removeFromSuperview()
viewController.removeFromParent()
}
private func updateView() {
if sgControll.selectedSegmentIndex == 0 {
remove(asChildViewController: firstView)
add(asChildViewController: secondView)
} else {
remove(asChildViewController: seconView)
add(asChildViewController: firstView)
}
}
}
I'm trying to create a photo album via UIImagePicker into a CollectionView and cannot get it to segue to that same photo again in a detailed UIViewController. Pulling my hair out and this is just a tutorial as I have just started coding!
Can anyone tell me what I'm doing wrong?
Here is my ViewController:
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate {
#IBOutlet private weak var addButton: UIBarButtonItem!
#IBOutlet private weak var collectionView:UICollectionView!
#IBOutlet private weak var trashButton:UIBarButtonItem!
var testItems = [Person]()
var stormTrooperCollectionArray: [UIImage] = [#imageLiteral(resourceName: "StormTrooper-3052-423a-8c57-7220081e1585_800x"), #imageLiteral(resourceName: "ST3"), #imageLiteral(resourceName: "ST2"), #imageLiteral(resourceName: "ST4")]
#IBAction func addItem() {
addNewPerson()
}
#IBAction func trashItem(_ sender: Any) {
if let selectedItems = collectionView.indexPathsForSelectedItems {
let itemsForDeletion = selectedItems.map{$0.item}.sorted().reversed()
for item in itemsForDeletion {
testItems.remove(at: item)
}
collectionView.deleteItems(at: selectedItems)
}
}
#objc func refresh() {
addItem()
collectionView.refreshControl?.endRefreshing()
}
override func viewDidLoad() {
super.viewDidLoad()
// Set up a 3-column Collection View
let width = (view.frame.size.width - 20) / 3
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width:width, height:width)
// Refresh Control
let refresh = UIRefreshControl()
refresh.addTarget(self, action: #selector(self.refresh), for: UIControlEvents.valueChanged)
collectionView.refreshControl = refresh
// Edit
navigationItem.leftBarButtonItem = editButtonItem
navigationController?.isToolbarHidden = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DetailSegue" {
if let dest = segue.destination as? DetailsViewController,
let index = sender as? IndexPath {
dest.detailedImageHi = stormTrooperCollectionArray [index.row]
}
}
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
navigationController?.isToolbarHidden = !editing
addButton.isEnabled = !editing
trashButton.isEnabled = editing
collectionView.allowsMultipleSelection = editing
let indexes = collectionView.indexPathsForVisibleItems
for index in indexes {
let cell = collectionView.cellForItem(at: index) as! CollectionViewCell
cell.isEditing = editing
}
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UIImagePickerControllerDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return stormTrooperCollectionArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
//cell.titleLabel.text = stormTrooperCollectionArray[indexPath.row]
cell.selectionImage.image = stormTrooperCollectionArray[indexPath.row]
cell.isEditing = isEditing
return cell
}
#objc func addNewPerson() {
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
present(picker, animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let image = info[UIImagePickerControllerEditedImage] as? UIImage else { return }
let imageName = UUID().uuidString
let imagePicture = getDocumentsDirectory()
if let jpegData = UIImageJPEGRepresentation(image, 80) {
try? jpegData.write(to: imagePicture)
}
//let detailedItem = Person(imageHi: imageName)
//testItems.append(detailedItem)
let detailedItem = Person(imageHi: imageName)
//KEEPS THROWING AN ERROR HERE WHICH SAYS: Cannot convert value of type 'String' to expected argument type 'UIImage'
stormTrooperCollectionArray.append(detailedItem)
collectionView?.reloadData()
dismiss(animated: true)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if !isEditing {
performSegue(withIdentifier: "DetailSegue", sender: indexPath)
}
}
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
}
Here is my VC for the Cell in the CollectionView:
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var selectionImage: UIImageView!
}
Here is my VC for the Detailed View Controller:
import UIKit
class DetailsViewController: UIViewController {
var selection: String!
var detailedImageHi: UIImage!
#IBOutlet private weak var detailsLabel: UILabel!
#IBOutlet private weak var detailedImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
detailsLabel.text = selection
detailedImage.image = detailedImageHi
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is my VC for the NSObject Swift File:
import UIKit
class Person: NSObject {
var imageHi: UIImage
init(imageHi: UIImage){
self.imageHi = imageHi
}
}
In your code the UIImage is image and not imageName:
guard let image = info[UIImagePickerControllerEditedImage] as? UIImage else { return }
So all you have to do is pass the right argument to the constructor of Person:
let detailedItem = Person(imageHi: image)
imageName is a random string generated via UUID().uuidString, and used in this code to save the image to the documents directory with a random and unique name.
Everyone, I'm having difficulties finding documentation on how to implement a Search filter for My Movie DB app ill attach my code so far below I've managed to get the data to show up in the table view
The title and Image What I need to do now is being able to filter the movies with a search bar then when clicking on a row it goes to a new View controller displaying expanded information about the movie then a button to "bookmark" save it to core data then appear on a bookmark screen for the user to view later.
Thanks in Advance
My code is here:
import UIKit
import AFNetworking
class ViewController: UIViewController, UITableViewDataSource,
UITableViewDelegate, UISearchBarDelegate {
var movies: [NSDictionary]?
#IBOutlet weak var txtSearch: UITextField!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view, typically from a nib.
fetchMovies()
searchBar()
}
func searchBar(){
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width:
self.view.frame.width, height: 50))
searchBar.delegate = self
searchBar.showsScopeBar = true
searchBar.tintColor = UIColor.lightGray
searchBar.scopeButtonTitles = ["Now Playing"]
self.tableView.tableHeaderView = searchBar
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
{
if searchText == ""{
fetchMovies()
}else{
if searchBar.selectedScopeButtonIndex == 0 {
movies = movies?.filter({ (movies) -> Bool in
return movies.title.lowercased()
})
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return movies?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MovieTableViewCell
let movie = movies![indexPath.row]
let title = movie["title"] as! String
let posterPath = movie["poster_path"] as! String
let baseUrl = "https://image.tmdb.org/t/p/w300/"
let imageUrl = NSURL(string: baseUrl + posterPath)
cell.lblTitle.text = title
cell.imgMovie.setImageWith(imageUrl! as URL)
print("row \(indexPath.row)")
return cell
}
func fetchMovies(){
let apiKey = "2c0a8efe934c162f5535ff33303e70bd"
let url = NSURL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)")
let request = URLRequest(url: url! as URL, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 10)
let session = URLSession(
configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: OperationQueue.main
)
let task: URLSessionDataTask = session.dataTask(with: request, completionHandler:{(dataOrNil, repsonse, error) in
if let data = dataOrNil {
if let responseDictionary = try! JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary{print("response: \(responseDictionary)")
self.movies = responseDictionary["results"] as? [NSDictionary]
self.tableView.reloadData()
}
}
})
task.resume()
}
#IBAction func btnBookmark(_ sender: UIButton) {
}
}
I have been trying to find a answer for this problem but no luck. When I use my refreshcontrol my UICollectionView Cells start repeating/duplicating cells. The thumbnails start switching around whenever I start refreshing the UICollectionView.
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var postImage: UIImageView!
override func prepareForReuse() {
self.postImage.image = nil
super.prepareForReuse()
}
}
I've already added the prepareForReuse for the UICollectionViewCell but no luck.
import UIKit
import Firebase
import SVProgressHUD
import SDWebImage
import SwiftyJSON
import CoreLocation
class CollectionView: UICollectionViewController, UICollectionViewDelegateFlowLayout, CLLocationManagerDelegate {
#IBOutlet var collectionViews: UICollectionView!
var posts = [Post]()
var uid: String?
let user = Auth.auth().currentUser?.uid
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
locationManager.delegate = self
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
locationManager.stopUpdatingLocation()
collectionViews.dataSource = self
collectionViews.delegate = self
if CLLocationManager.locationServicesEnabled() {
switch(CLLocationManager.authorizationStatus()) {
case .notDetermined, .restricted, .denied:
print("No access")
downloadImagesWithoutLocation(refreshing: false, refreshControl: nil)
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
downloadImages(refreshing: false, refreshControl: nil)
}
} else {
print("Location services are not enabled")
}
// refresh control
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refreshControlAction(refreshControl:)), for: UIControlEvents.valueChanged)
self.collectionViews.insertSubview(refreshControl, at: 0)
}
#objc func refreshControlAction(refreshControl: UIRefreshControl) {
if CLLocationManager.locationServicesEnabled() {
switch(CLLocationManager.authorizationStatus()) {
case .notDetermined, .restricted, .denied:
print("No access")
downloadImagesWithoutLocation(refreshing: true, refreshControl: refreshControl)
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
downloadImages(refreshing: true, refreshControl: refreshControl)
}
} else {
print("Location services are not enabled")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func downloadImagesWithoutLocation(refreshing: Bool, refreshControl: UIRefreshControl?) {
let ref = Database.database().reference().child("posts")
MBProgressHUD.showAdded(to: self.view, animated: true)
ref.queryOrdered(byChild: "businessName").observe(.childAdded, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
self.posts = []
for item in dict {
let json = JSON(item.value)
let uid = json["uid"].stringValue
var name: String = json["businessName"].stringValue
let address: String = json["businessStreet"].stringValue
let state: String = json["businessCity"].stringValue
let caption: String = json["caption"].stringValue
let downloadURL: String = json["download_url"].stringValue
let timestamp = json["timestamp"].doubleValue
let date = Date(timeIntervalSince1970: timestamp/1000)
let postID: String = json["postID"].stringValue
//let lat = json["businessLatitude"].doubleValue
//let long = json["businessLongitude"].doubleValue
//let businessLocation = CLLocation(latitude: lat, longitude: long)
//let latitude = self.locationManager.location?.coordinate.latitude
//let longitude = self.locationManager.location?.coordinate.longitude
//let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)
//let distanceInMeters: Double = userLocation.distance(from: businessLocation)
//let distanceInMiles: Double = distanceInMeters * 0.00062137
//let distanceLabelText = String(format: "%.2f miles away", distanceInMiles)
let distanceLabelText = "Not Available"
let usersReference = Database.database().reference(withPath: "users").queryOrderedByKey().queryEqual(toValue: uid)
usersReference.observeSingleEvent(of: .value, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
let userInfo = dict.allValues[0]
let userJSON = JSON(userInfo)
name = userJSON["name"].stringValue
}
let post = Post(uid: uid, caption: caption, downloadURL: downloadURL, name: name, date: date, address: address, state: state, distance: distanceLabelText, postID: postID)
self.posts.append(post)
//self.posts.sort {$0.distance.compare($1.distance) == .orderedAscending}
self.posts.sort {$0.date.compare($1.date) == .orderedAscending}
self.collectionViews.reloadData()
})
}
}
if refreshing {
refreshControl?.endRefreshing()
}
MBProgressHUD.hide(for: self.view, animated: true)
})
}
func downloadImages(refreshing: Bool, refreshControl: UIRefreshControl?) {
let ref = Database.database().reference().child("posts")
MBProgressHUD.showAdded(to: self.view, animated: true)
ref.queryOrdered(byChild: "businessName").observe(.childAdded, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
self.posts = []
for item in dict {
let json = JSON(item.value)
let uid = json["uid"].stringValue
var name: String = json["businessName"].stringValue
let address: String = json["businessStreet"].stringValue
let state: String = json["businessCity"].stringValue
let caption: String = json["caption"].stringValue
let downloadURL: String = json["download_url"].stringValue
let timestamp = json["timestamp"].doubleValue
let date = Date(timeIntervalSince1970: timestamp/1000)
let postID: String = json["postID"].stringValue
let lat = json["businessLatitude"].doubleValue
let long = json["businessLongitude"].doubleValue
let businessLocation = CLLocation(latitude: lat, longitude: long)
let latitude = self.locationManager.location?.coordinate.latitude
let longitude = self.locationManager.location?.coordinate.longitude
let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)
let distanceInMeters: Double = userLocation.distance(from: businessLocation)
let distanceInMiles: Double = distanceInMeters * 0.00062137
let distanceLabelText = String(format: "%.2f miles away", distanceInMiles)
//let distanceLabelText = "Not Available"
let usersReference = Database.database().reference(withPath: "users").queryOrderedByKey().queryEqual(toValue: uid)
usersReference.observeSingleEvent(of: .value, with: { snapshot in
if let dict = snapshot.value as? NSDictionary {
let userInfo = dict.allValues[0]
let userJSON = JSON(userInfo)
name = userJSON["name"].stringValue
}
let post = Post(uid: uid, caption: caption, downloadURL: downloadURL, name: name, date: date, address: address, state: state, distance: distanceLabelText, postID: postID)
self.posts.append(post)
self.posts.sort {$0.distance.compare($1.distance) == .orderedAscending}
self.collectionViews.reloadData()
})
}
}
if refreshing {
refreshControl?.endRefreshing()
}
MBProgressHUD.hide(for: self.view, animated: true)
})
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
cell.postImage.image = nil
if self.posts[indexPath.row].downloadURL != nil {
cell.postImage.downloadImagezzz(from: self.posts[indexPath.row].downloadURL)
} else {
print("\n \(indexPath.row) could not return a value for pathToImage256 from Post. \n")
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 2
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.size.width / 3 - 1, height: collectionView.frame.size.width / 3 - 1)
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "PostSegue", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "PostSegue") {
let selectedCell = sender as! NSIndexPath
let selectedRow = selectedCell.row
let imagePage = segue.destination as! CollectionViewFeed
let user = self.posts[selectedRow].uid
imagePage.seguePostID = self.posts[selectedRow].downloadURL
imagePage.otherUser = user
print(self.posts[selectedRow].downloadURL)
} else {
print("\n Segue with identifier (imagePage) not found. \n")
}
}
}
extension UIImageView {
func downloadImagezzz(from imgURL: String) {
let url = URLRequest(url: URL(string: imgURL)!)
let task = URLSession.shared.dataTask(with: url) {
(data, responds, error) in
if error != nil {
print(error!)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}
}
Heres my whole view controller that loads the UICollectionView.
Below are the images of whats happening.
In your cellForItemAt method add this before you start the task to download the new image and it will work.
cell.postImage.image = nil
cell.postImage.sd_cancelCurrentImageLoad()