I can't interact with my CollectionView cells - ios

I am trying to interact with the cells in my CollectionView, but I can't get anything to work.
At first, I was just trying to print something to the logs by clicking on the cell. That didn't work. I did this by declaring a "didSelectItemAt" function.
Next I added a button to the cell, and added an IBAction to print something to the log, but that doesn't work either.
I tried adding collectionview.isUserInteractionEnabled = true to the viewDidLoad() method, that didn't work. I also checked the storyboard
I'm adding the datasource and delegate by doing
collectionview.delegate = self
collectionview.dataSource = self
I also tried adding a UITapGestureRecognizer in viewDidLoad, but that just made my app crash when loading the view.
I can interact with other collectionviews, but I just can't interact with this collection view. I'm not sure if scrolling works because I only have one cell loading in this collection view so far.
Anybody have any ideas on what I can do or how to correctly implement UITapGestureRecognizer?
Here is the full code for the CollectionView:
import UIKit
import Firebase
import SwiftKeychainWrapper
import SwiftUI
import FirebaseUI
class UserViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionview: UICollectionView!
var user = [User]()
var following = [String]()
var userStorage: StorageReference!
var ref : DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
collectionview.delegate = self
collectionview.dataSource = self
collectionview.isUserInteractionEnabled = true
// self.collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "UserCell")
retrieveUsers()
// let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKeyboard))
// tap.cancelsTouchesInView = false
// collectionview.addGestureRecognizer(tap)
}
#IBAction func buttonPress(_sender: Any){
print("fuck you")
}
func retrieveUsers() {
let uid = Auth.auth().currentUser!.uid
let ref = Database.database().reference().child("posts")
let uids = Database.database().reference().child("users")
uids.observeSingleEvent(of:.value, with:{
(snapshot) in
let users = snapshot.value as! [String : NSDictionary]
//self.user.removeAll()
for (_, value) in users {
if let uid = value["uid"] as? String {
if uid != Auth.auth().currentUser!.uid {
let userToShow = User()
if let username = value["username"] as? String, let imagePath = value["urlToImage"] as? String{
userToShow.username = username
userToShow.imagePath = imagePath
userToShow.userID = uid
self.user.append(userToShow)
print(userToShow)
}
}
}
}
self.collectionview.reloadData()
})
//ref.removeAllObservers()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return user.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "userCell", for: indexPath) as! UserCell
cell.userImage.sd_setImage(with: URL(string: self.user[indexPath.row].imagePath))
cell.nameLabel.text = self.user[indexPath.row].username
cell.userID = self.user[indexPath.row].userID
// let destinationVC = ProfileViewController()
// destinationVC.sentUserID = user[indexPath.row].userID!
// Let's assume that the segue name is called playerSegue
// This will perform the segue and pre-load the variable for you to use
//destinationVC.performSegue(withIdentifier: "toProfileFromSearch", sender: self)
// cell.addButtonTapAction = {
// // implement your logic here, e.g. call preformSegue()
// self.performSegue(withIdentifier: "toProfileFromSearch", sender: self)
// }
//cell.userImage.downloadImage(from: self.user[indexPath.row].imagePath!)
//checkFollowing(indexPath: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("hello world")
// let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
// VC1.sentUserID = user[indexPath.row].userID
// self.navigationController?.pushViewController(VC1, animated: true)
}
func checkFollowing(indexPath: IndexPath) {
let uid = Auth.auth().currentUser!.uid
let ref = Database.database().reference()
ref.child("users").child(uid).child("following").queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in
if let following = snapshot.value as? [String : AnyObject] {
for (_, value) in following {
if value as! String == self.user[indexPath.row].userID {
// self.tableview.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
}
}
})
ref.removeAllObservers()
}
#IBAction func logOutPressed(_ sender: Any) {
KeychainWrapper.standard.removeObject(forKey:"uid")
do{
try Auth.auth().signOut()
} catch let signOutError as NSError{
print("Error signing out: %#", signOutError)
}
dismiss(animated: true, completion: nil)
}
}
extension UIImageView {
func downloadImage(from imgURL: String!) {
let url = URLRequest(url: URL(string: imgURL)!)
let task = URLSession.shared.dataTask(with: url) {
(data, response, error) in
if error != nil {
print(error!)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}
}

Related

Custom Firebase cell not appearing in TableView

I am trying to populate a TableView with custom cells that have an image in them downloaded from Firebase. The custom cell is not appearing in the Tableview. I believe I configure the cells with an array named 'posts', that is full of 'TimeLinePost', however when I print 'posts.count' for the 'numberOfRows' func 0 appears, so something is not working somewhere. I may also be making a mistake in how I downloading the data. Any assistance where I am going wrong would be great thanks.
This is the code for the TableView and contains the 'TimeLinePost' Class -
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var table: UITableView?
var posts = [TimeLinePost]()
private let storage = Storage.storage().reference()
override func viewDidLoad() {
super.viewDidLoad()
self.table?.register(TableViewCell.nib(), forCellReuseIdentifier: TableViewCell.identifier)
table?.delegate = self
table?.dataSource = self
table?.reloadData()
}
#IBAction func unwindSegue(_ sender: UIStoryboardSegue){
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(posts.count)
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.identifier, for:indexPath) as! TableViewCell
cell.configure(with: posts[indexPath.row])
return cell
}
}
class TimeLinePost {
var image: String
init (image: String) {
self.image = image
}
}
This is the code for uploading the data -
struct MyKeys {
static let imagesFolder = "imagesFolder"
static let uid = "uid"
static let imagesURL = "imagesURL"
static let imagesCollection = "imagesCollection"
}
class uploadViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var imageDownloadUrl: String?
#IBOutlet weak var photoImageView: UIImageView!
var original: UIImage!
private let storage = Storage.storage().reference()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func choosePhoto() {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
navigationController?.present(picker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
self.navigationController?.dismiss(animated: true, completion: nil)
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
photoImageView.image = image
original = image
}
}
#IBAction func uploadPhoto(_ sender: Any) {
guard let image = photoImageView.image,
let data = image.jpegData(compressionQuality: 1.0)
else {
print("Error")
return
}
let imageName = UUID().uuidString
let imageReference = Storage.storage().reference().child("images").child(imageName)
imageReference.putData(data, metadata: nil) { (metadata, error) in
guard error == nil else {
print("Failed to upload")
return
}
imageReference.downloadURL{ (url, error) in
if let error = error {
print("Error")
return
}
guard let url = url else {
print("Error")
return
}
let dataReference = Firestore.firestore().collection(MyKeys.imagesCollection).document()
let documentUid = dataReference.documentID
let urlString = url.absoluteString
let data = [
MyKeys.uid: documentUid,
MyKeys.imagesURL: urlString,
]
dataReference.setData(data) { (error) in
if let error = error {
print("Error:\(error)")
return
}
UserDefaults.standard.set(documentUid, forKey: MyKeys.uid)
}
}
}
}
}
And this is the code for my custom cell -
class TableViewCell: UITableViewCell {
#IBOutlet var imagePost: UIImageView!
static let identifier = "TableViewCell"
static func nib() -> UINib {
return UINib(nibName: "TableViewCell", bundle: nil)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func configure(with posts: TimeLinePost) {
self.imagePost.image = UIImage(named: posts.image)
}
func downloadImage(){
guard let uid = UserDefaults.standard.value(forKey: MyKeys.uid) else {
print("Error1")
return
}
let query = Firestore.firestore().collection(MyKeys.imagesCollection).whereField(MyKeys.uid, isEqualTo: uid)
query.getDocuments { (snapshot, error) in
if let error = error {
print("Error2")
return
}
guard let snapshot = snapshot, let data = snapshot.documents.first?.data(), let urlString = data[MyKeys.imagesURL] as? String, let url = URL(string: urlString) else {
print("Error3")
return
}
let resource = ImageResource(downloadURL: url)
self.imagePost.kf.setImage(with: resource, completionHandler: { (result) in
switch result {
case .success(_):
print("Success")
return
case .failure(_):
print("Error4")
return
}
})
}
}
}

UISearchBar seems to be returning right count, but not the right rows

I am trying to implement a search function in my app. For now, I'm just trying to search by the State value my JSON, though I'd like to eventually include Category as well. There are 9 rows total, the first 7 are State=AZ and the last 2 are State=CA. When I search for "KK" the table is empty, which makes sense. But when I search for "CA" I get two rows like I expect, but they are the first two rows in the JSON, which are both AZ, not the two CA rows it should be.
I suspect my issue is somewhere in my filterContentForSearchText function, but since I'm not sure exactly which code you need, here is the ViewController (the function I think is the issue is down near the end):
import UIKit
import os.log
import Foundation
class BonusListViewController: UITableViewController {
var bonuses = [JsonFile.JsonBonuses]()
var filteredBonuses = [JsonFile.JsonBonuses]()
var detailViewController: BonusDetailViewController? = nil
let defaults = UserDefaults.standard
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
// MARK: Search Support
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Enter two letter state to filter"
navigationItem.searchController = searchController
definesPresentationContext = true
// MARK: Settings Data Struct
struct Constants {
struct RiderData {
let riderNumToH = "riderNumToH"
let pillionNumToH = "pillionNumToH"
}
struct RallyData {
let emailDestinationToH = "emailDestinationToH"
}
}
//MARK: Load the bonuses
loadBonuses { [weak self] bonuses in
self?.bonuses = bonuses ?? []
DispatchQueue.main.async {
self?.tableView.reloadData()
}
print("loadBonuses called")
}
}
// MARK: - Table View Configuration
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
print("Showing \(filteredBonuses.count) Filtered Results")
return filteredBonuses.count
}
print("Found \(bonuses.count) rows in section.")
return bonuses.count
}
/* Disabling the swipe function until I code it to actually do something
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let clearAction = UIContextualAction(style: .normal, title: "Clear Data") { (contextAction: UIContextualAction, sourceView: UIView, completionHandler: (Bool) -> Void) in
print("Clear Action Tapped")
completionHandler(true)
}
clearAction.backgroundColor = .blue
let swipeConfig = UISwipeActionsConfiguration(actions: [clearAction])
return swipeConfig
}
*/
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "BonusListViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? BonusListViewCell else {
fatalError("The dequeued cell is not an instance of BonusListViewCell.")
}
let bonus = bonuses[indexPath.row]
let bonusSet: JsonFile.JsonBonuses
if isFiltering() {
bonusSet = filteredBonuses[indexPath.row]
} else {
bonusSet = bonus
}
let urlString = "http://tourofhonor.com/appimages/"+(bonus.imageName)
let url = URL(string: urlString)
cell.primaryImage.downloadedFrom(url: url!)
cell.nameLabel.text = bonus.name.capitalized
cell.bonusCodeLabel.text = bonus.bonusCode.localizedUppercase
cell.categoryLabel.text = bonus.category
cell.valueLabel.text = "\(bonus.value)"
cell.cityLabel.text = "\(bonus.city.capitalized),"
cell.stateLabel.text = bonus.state.localizedUppercase
return cell
}
// MARK: Functions
// MARK: - Fetch JSON from ToH webserver
func downloadJSON(completed: #escaping ([JsonFile.JsonBonuses]?) -> ()) {
let url = URL(string: "http://tourofhonor.com/BonusData.json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error == nil, let data = data {
do {
let posts = try JSONDecoder().decode(JsonFile.self, from: data)
completed(posts.bonuses)
} catch {
print("JSON Download Failed")
}
} else {
print("downloadJSON completed")
completed(nil)
}
}.resume()
}
func saveBonuses(_ bonuses: [JsonFile.JsonBonuses], to url: URL) {
try? FileManager.default.removeItem(at: url)
do {
let data = try JSONEncoder().encode(bonuses)
try data.write(to: url)
print("saveBonuses successful")
} catch {
print("Error saving bonuses to file:", error)
}
}
func loadBonusesFromFile(_ url: URL) -> [JsonFile.JsonBonuses]? {
do {
let data = try Data(contentsOf: url)
let bonuses = try JSONDecoder().decode([JsonFile.JsonBonuses].self, from: data)
print("loadBonusesFromFile successful")
return bonuses
} catch {
print("Error loading bonuses from file:", error)
return nil
}
}
func loadBonuses(completion: #escaping ([JsonFile.JsonBonuses]?) -> Void) {
let localBonusesURL = try! FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("Bonuses.json")
downloadJSON { bonuses in
if let bonuses = bonuses {
completion(bonuses)
self.saveBonuses(bonuses, to: localBonusesURL)
} else {
completion(self.loadBonusesFromFile(localBonusesURL))
}
}
}
func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredBonuses = bonuses.filter({( bonus: JsonFile.JsonBonuses) -> Bool in
return bonus.state.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}
func isFiltering() -> Bool {
return searchController.isActive && !searchBarIsEmpty()
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? BonusDetailViewController {
destination.bonus = bonuses[(tableView.indexPathForSelectedRow?.row)!]
}
}
}
extension BonusListViewController: UISearchResultsUpdating {
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
and here is the JsonFile.swift:
import Foundation
struct JsonFile: Codable {
struct Meta: Codable {
let fileName: String
let version: String
}
struct JsonBonuses: Codable {
let bonusCode: String
let category: String
let name: String
let value: Int
let city: String
let state: String
let flavor: String
let imageName: String
}
let meta: Meta
let bonuses: [JsonBonuses]
}
EDIT: The JSON itself can be found at http://www.tourofhonor.com/BonusData.json
Also, on the line that says let bonusSet: JsonFile.JsonBonuses (under the cellForRowAt), I'm getting a warning that says "Immutable value bonusSet was never used; consider removing it" even though I use it in the very next line.
I guess the issue is in your cellForRow method, you are supposed to assignv alues with bonusSet and not bonus. as you are initializing the value from bonus dara structure which should be from bonusSet.
Try changing cellForRow as:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "BonusListViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? BonusListViewCell else {
fatalError("The dequeued cell is not an instance of BonusListViewCell.")
}
let bonus = bonuses[indexPath.row]
let bonusSet: JsonFile.JsonBonuses
if isFiltering() {
bonusSet = filteredBonuses[indexPath.row]
} else {
bonusSet = bonus
}
//CHANGE IS REQUIRED HERE: REPLACE THE bonus WITH bonusSet :
let urlString = "http://tourofhonor.com/appimages/"+(bonusSet.imageName)
let url = URL(string: urlString)
cell.primaryImage.downloadedFrom(url: url!)
cell.nameLabel.text = bonusSet.name.capitalized
cell.bonusCodeLabel.text = bonusSet.bonusCode.localizedUppercase
cell.categoryLabel.text = bonusSet.category
cell.valueLabel.text = "\(bonusSet.value)"
cell.cityLabel.text = "\(bonusSet.city.capitalized),"
cell.stateLabel.text = bonusSet.state.localizedUppercase
return cell
}
The problem is with your cell for row index path
search result you are getting from the filterContentForSearchText you are storing in filteredBonuses but in cellForRowAt you are still setting all your values from
bouns variable
bonus = bonuses[indexPath.row]
if isFiltering() {
bonusSet = filteredBonuses[indexPath.row] //even though you are creating bonusSet you are not using it while setting cell values below so use that bonusSet
} else {
bonusSet = bonus
}
//Like this
let urlString = "http://tourofhonor.com/appimages/"+(bonusSet.imageName)
let url = URL(string: urlString)
cell.primaryImage.downloadedFrom(url: url!)
cell.nameLabel.text = bonus.name.capitalized
cell.bonusCodeLabel.text = bonusSet.bonusCode.localizedUppercase
cell.categoryLabel.text = bonusSet.category
cell.valueLabel.text = "\(bonusSet.value)"
cell.cityLabel.text = "\(bonusSet.city.capitalized),"
cell.stateLabel.text = bonusSet.state.localizedUppercase
This code is useless:
let bonusSet: JsonFile.JsonBonuses
if isFiltering() {
bonusSet = filteredBonuses[indexPath.row]
} else {
bonusSet = bonus
}
You create a local variable bonusSet whose value depends on whether you are filtering; but, as the compiler rightly observes, nothing you do afterwards uses it. Your code thus behaves exactly the same way regardless of whether you are filtering.

data getting fetched from server after assigning it to collection view

I am new to swift language so not sure how to resolve this issue. Here I am trying to display images using uicollectionview. But I not getting the proper output as it does not show anything on collection view when executed. Need help friends.
View Did Load Function
override func viewDidLoad() {
super.viewDidLoad()
ImageGet()
}
Collection View
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print(defectImages.count) // returns zero value here
return defectImages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell
cell.image.image = defectImages[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let largeVC = mainStoryBoard.instantiateViewController(withIdentifier: "ImageDisplayVC") as! ImageDisplayVC
largeVC.imgImage = defectImages[indexPath.row]
self.navigationController?.pushViewController(largeVC, animated: true)
}
Alamofire to get images
func ImageGet() {
let imageId = Int(details.id!)
let para: Parameters = ["imageId": imageId]
Alamofire.request(URL_IMG_List, method: .post, parameters: para).responseJSON { response in
if((response.result.value) != nil) {
let swiftyJsonVar = JSON(response.result.value!)
if let resData = swiftyJsonVar["data"].arrayObject {
self.arrRes = resData as! [[String:AnyObject]]
for index in 0..<self.arrRes.count{
self.imageData.file_name = self.arrRes[index]["file_name"] as! String
self.completeImagePath = self.get_image_path + self.imageData.file_name
self.imgpath.append(self.completeImagePath)
guard let url = URL(string: self.completeImagePath) else {return}
print(url)
if let data = try? Data(contentsOf: url) {
guard let image: UIImage = UIImage(data: data) else {return}
print(image)
self.defectImages.append(image as UIImage)
}
}
print(self.defectImages.count)
}
}
}
}
You just need to reload your collectionView once you fetch data from API and please check that you set your collectionView dataSource and delegate from storyBoard. if not than write below lines in viewDidLoad() before ImageGet().
self.collectionView.dataSource = self
self.collectionView.delegate = self
Replace below code with yours.
func ImageGet() {
let imageId = Int(details.id!)
let para: Parameters = ["imageId": imageId]
Alamofire.request(URL_IMG_List, method: .post, parameters: para).responseJSON { response in
if((response.result.value) != nil) {
let swiftyJsonVar = JSON(response.result.value!)
if let resData = swiftyJsonVar["data"].arrayObject {
self.arrRes = resData as! [[String:AnyObject]]
for index in 0..<self.arrRes.count{
self.imageData.file_name = self.arrRes[index]["file_name"] as! String
self.completeImagePath = self.get_image_path + self.imageData.file_name
self.imgpath.append(self.completeImagePath)
guard let url = URL(string: self.completeImagePath) else {return}
print(url)
if let data = try? Data(contentsOf: url) {
guard let image: UIImage = UIImage(data: data) else {return}
print(image)
self.defectImages.append(image as UIImage)
}
self.collectionView.reloadData() // RELOAD COLLECTIONVIEW
}
print(self.defectImages.count)
}
}
}
}

Retrieve image from firebase storage to show on tableView cell

I just need help I building Instagram-clone with firebase and I have an issue whit post feed I can't Retrieve image from firebase storage to show on tableView cell can you help me, please :(
import UIKit
import FirebaseAuth
import FirebaseDatabase
class HomeViewController: UIViewController ,UITableViewDelegate {
#IBOutlet weak var tableview: UITableView!
var posts = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
loadposts()
// var post = Post(captiontxt: "test", photoUrlString: "urll")
// print(post.caption)
// print(post.photoUrl)
}
func loadposts() {
Database.database().reference().child("posts").observe(.childAdded){ (snapshot: DataSnapshot)in
print(Thread.isMainThread)
if let dict = snapshot.value as? [String: Any]{
let captiontxt = dict["caption"] as! String
let photoUrlString = dict["photoUrl"] as! String
let post = Post(captiontxt: captiontxt, photoUrlString: photoUrlString )
self.posts.append(post)
print(self.posts)
self.tableview.reloadData()
}
}
}
#IBAction func logout(_ sender: Any) {
do {
try Auth.auth().signOut()
}catch let logoutErrorr{
print(logoutErrorr)
}
let storyboard = UIStoryboard(name: "Start", bundle: nil)
let signinVC = storyboard.instantiateViewController(withIdentifier: "SigninViewController")
self.present(signinVC, animated: true, completion: nil)
}
}
extension HomeViewController: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "imagecell", for: indexPath) as! PostCellTableViewCell
cell.captionLabel.text = posts[indexPath.row].caption
cell.postimage.image = posts[indexPath.row].photoUrl
// print(cell.captionLabel.text)
// print(cell.daysLabel.text)
return cell
}
}
enter code here
import Foundation
class Post {
var caption: String
var photoUrl: String
init(captiontxt: String, photoUrlString: String) {
caption = captiontxt
photoUrl = photoUrlString
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "imagecell", for: indexPath) as! PostCellTableViewCell
cell.postimage.image = nil
cell.tag += 1
let tag = cell.tag
cell.captionLabel.text = posts[indexPath.row].caption
let photoUrl = posts[indexPath.row].photoUrl
getImage(url: photoUrl) { photo in
if photo != nil {
if cell.tag == tag {
DispatchQueue.main.async {
cell.postimage.image = photo
}
}
}
}
return cell
}
func getImage(url: String, completion: #escaping (UIImage?) -> ()) {
URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
if error == nil {
completion(UIImage(data: data!))
} else {
completion(nil)
}
}.resume()
}

Firebase Retrieve Image as Url pass tableView as Image (Swift)

I'm trying to retrieve my data as URL and pass my another viewController.
Here is my retrieve data's code:
private func loadPlaces() {
let ref = FIRDatabase.database().reference()
ref.child("places").queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in
let images = snapshot.value as! [String : AnyObject]
// self.places.removeAll()
for (_, value) in images {
let userToShow = historicalPlaces()
if let img = value["imagePath"] as? String,
let name = value["name"] as? String,
let information = value["information"] as? String
{
userToShow.historyImage = img
userToShow.historyName = name
userToShow.information = information
self.places.append(userToShow)
}
}
self.tableView.reloadData()
})
// ref.removeAllObservers()
}
In this code I'm using extension which can read URL.
Extension code here.
extension UIImageView {
func downloadImage(from imgURL: String!) {
let url = URLRequest(url: URL(string: imgURL)!)
let task = URLSession.shared.dataTask(with: url) {
(data, response, error) in
if error != nil {
print(error!)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}
}
and here I print my images and labels to viewController.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "historyTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? HistoryTableViewCell else {
fatalError("The dequeued cell is not an instance of historyTableViewCell.")
}
let place = places[indexPath.row]
cell.nameLabel.text = place.historyName
cell.photoImageView.downloadImage(from: place.historyImage!)
return cell
}
and this is the cell control code:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
switch(segue.identifier ?? "") {
case "ShowDetail":
guard let historyDetail = segue.destination as? selectedPlaceViewController else {
fatalError("Unexpected destination: \(segue.destination)")
}
guard let selectedPlace = sender as? HistoryTableViewCell else {
fatalError("Unexpected sender: \(sender)")
}
guard let indexPath = tableView.indexPath(for: selectedPlace) else {
fatalError("The selected cell is not being displayed by the table")
}
let Place = places[indexPath.row]
historyDetail.selectedPlaces = Place
default:
fatalError("Unexpected Segue Identifier; \(segue.identifier)")
}
}
now whenever I click the cell which has view and label print it's images and labels to another viewController.
I try something like this:
import UIKit
class selectedPlaceViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var photoImageView: UIImageView!
var selectedPlaces: historicalPlaces?
override func viewDidLoad() {
super.viewDidLoad()
nameTextField.delegate = self
if let history = selectedPlaces {
navigationItem.title = history.historyName
nameTextField.text = history.historyName
// photoImageView.downloadImage(from: selectedPlaces [IndexPath.init(row: 0, section: 0)].historyImage!)
}
}
}
In this code I can retrieve labels from another viewController but I can't retrieve images. How can I retrieve Images from another viewCell URL to image.

Resources