Custom Tableview Cell Disappears when reloading table with a new picture - swift

I have a very strange issue occurring that I have not seen before while developing. It makes it very difficult to troubleshoot due to the fact the app is not crashing and there is no erroneous debug output in the console window.
I have an edit user profile ViewController. On this page it displays the users first and last name, e-mail and phone number, along with a picture. This is all being pulled from Firebase and is working fine. The "picture" you see is an actual JPG that is "uploaded" when someone creates an account, this way the photo URL is stored in their database and I can retrieve it to display a photo. In theory, when "editing" a profile, the user would see a real pic in there, and "change" it with the one they are taking or upload.
The issue I am having is that when I finish selecting a picture from the gallery or take one from the camera, it correctly dismisses the camera or gallery, but the "tableviewcell" dissapears, and I do not see the picture or the text. Oddly enough, the text fields remain that are not part of the table. The intent is to have the pic that is "taken" temporarily appear in the UIImage view (which lives in the tableviewcell) and then when the user hits "save", it will upload to FireBase (that part I know how to do). That VC then gets dismissed and the data on in ProfileVC is reloaded from FireBase with the new pic.
I have the firebase part down as well as I correctly (I think) coded the image picker, but there has to be something I am missing as to why the temporary image is not displaying.
As an additional troubleshooting step I commented out the line: self.editProfileTable.reloadData() under the function imagePickerContoller in the EditProfileVC.swift file. When I did that, after hitting "chose Photo" that view dismisses and it goes right back to the Before Update Picture picture below. It has to be something with the table, but I am just not seeing it.
I have included all relevant code below.
EditProfileVC.swift
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
class EditProfileVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, Alertable, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var delegate : ImagePickerDelegate?
var tempImage : UIImage?
var imagePicker : UIImagePickerController?
#IBOutlet var editProfileTable: UITableView!
#IBOutlet var editEmailTextField: UITextField!
#IBOutlet var editMobileTextField: UITextField!
var editProfileInfo = [EditProfileModel]()
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return editProfileInfo.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "editprofilecell", for: indexPath) as! EditProfileTableViewCell
let editprofile: EditProfileModel
editprofile = editProfileInfo[indexPath.row]
cell.firstNameLabel.text = editprofile.firstname
cell.lastNameLabel.text = editprofile.lastname
cell.emailLabel.text = editprofile.email
cell.mobileLabel.text = editprofile.mobile
cell.tapButton = {(user) in
self.pickImage()
}
if tempImage == nil {
DataService.instance.REF_USERS.observeSingleEvent(of: .value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
self.editProfileInfo.removeAll()
for snap in snapshot {
if snap.key == Auth.auth().currentUser?.uid {
let imageUrl = snap.childSnapshot(forPath: "userPhoto").value
// print(imageUrl)
let storage = Storage.storage()
let ref = storage.reference(forURL: imageUrl as! String)
ref.getData(maxSize: 1 * 1024 * 1024) { data, error in
if error != nil {
// Uh-oh, an error occurred!
} else {
cell.updateProfileImage.image = UIImage(data: data!)
}
}
}
}
}
})
}
delegate?.pickImage()
cell.updateProfileImage.image = tempImage
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
editEmailTextField.delegate = self
editMobileTextField.delegate = self
view.bindtoKeyboard()
imagePicker = UIImagePickerController()
let tap = UITapGestureRecognizer(target: self, action: #selector(handleScreenTap(sender:)))
self.view.addGestureRecognizer(tap)
DataService.instance.REF_USERS.observeSingleEvent(of: .value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
self.editProfileInfo.removeAll()
for snap in snapshot {
if snap.key == Auth.auth().currentUser?.uid {
let profileObject = snap.value as? [String: AnyObject]
let profileFirstName = profileObject?["first_name"]
let profileLastName = profileObject?["last_name"]
let profileMobile = profileObject?["mobile_number"]
let profileEmail = Auth.auth().currentUser?.email
let editprofile = EditProfileModel(firstname: profileFirstName as! String?, lastname: profileLastName as! String?, email: profileEmail , mobile: profileMobile as! String?)
self.editProfileInfo.append(editprofile)
}
self.editProfileTable.reloadData()
}
}
})
delegate?.pickImage()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
#objc func handleScreenTap(sender: UITapGestureRecognizer) {
self.view.endEditing(true)
}
func pickImage() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
self.openCamera()
}))
alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
self.openGallery()
}))
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
// let imagePicker = UIImagePickerController()
// imagePicker.delegate = self
// imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
// imagePicker.allowsEditing = false
// self.present(imagePicker, animated: true, completion: nil)
}
func openCamera()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerController.SourceType.camera
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func openGallery()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have perission to access gallery.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
tempImage = pickedImage
self.editProfileTable.reloadData()
dismiss(animated: true, completion: nil)
// imageViewPic.image = pickedImage
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
EditProfileModel.swift
class EditProfileModel {
var firstname: String?
var lastname: String?
var email: String?
var mobile: String?
init(firstname: String?, lastname: String?, email: String?, mobile: String?){
self.firstname = firstname
self.lastname = lastname
self.email = email
self.mobile = mobile
}
}
EditProfileTableViewCell.swift
import UIKit
import Foundation
var delegate : ImagePickerDelegate?
class EditProfileTableViewCell: UITableViewCell {
#IBOutlet var updateProfileImage: UIImageView!
#IBOutlet var firstNameLabel: UILabel!
#IBOutlet var lastNameLabel: UILabel!
#IBOutlet var emailLabel: UILabel!
#IBOutlet var mobileLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func btdDetailsClick(_ sender: Any) {
tapButton?(self)
delegate?.pickImage()
}
var tapButton: ((UITableViewCell) -> Void)?
}
ImagePicker.swift
import UIKit
import Foundation
protocol ImagePickerDelegate {
func pickImage()
}
Before Update Picture button is pressed
After Update Image button pressed and all code above is run

Related

I can not see all items on my prototype cell.It seems like default cell but it is not

I want to make some blog or forum app.I made a home page to see other users's posts.I used tableview and prototype cell to do that.But when i run my app, i can not see all my items in my prototype cell.And they seem like default cells but they are not.I debugged it with changing cell's background color.I can see it but not completely true.
Here is my Home Page View Controller
import UIKit
import Parse
class FeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var postDizisi = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
verileriAl()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postDizisi.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "protCell", for: indexPath) as! FeedTableViewCell
cell.textView.text = postDizisi[indexPath.row].content
cell.usernameLabel.text = postDizisi[indexPath.row].username
return cell
}
#objc func verileriAl() {
print("done")
let query = PFQuery(className: "Post")
query.addDescendingOrder("createdAt")
query.findObjectsInBackground { (objects, error) in
if error != nil {
self.createAlert(title: "HATA", message: error?.localizedDescription ?? "HATA")
}else {
if objects!.count > 0 {
self.postDizisi.removeAll(keepingCapacity: false)
for object in objects! {
if let username = object.object(forKey: "username") as? String {
if let userContent = object.object(forKey: "content") as? String {
let post = Post(username: username, content: userContent)
self.postDizisi.append(post)
}
}else {
print("hata aldık")
}
}
self.tableView.reloadData()
}
}
}
}
func createAlert(title : String , message : String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let okBut
ton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
alert.addAction(okButton)
present(alert, animated: true)
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(verileriAl), name: NSNotification.Name(rawValue: "veriGirildi"), object: nil)
}
}
Here is my upload View Controller
import UIKit
import Parse
class UploadViewController: UIViewController {
#IBOutlet weak var shareButton: UIButton!
#IBOutlet weak var usernameLabel: UILabel!
#IBOutlet weak var postTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
usernameLabel.text = PFUser.current()?.username
}
#IBAction func shareButtonClicked(_ sender: Any) {
let post = PFObject(className: "Post")
if PFUser.current() != nil {
post["username"] = PFUser.current()?.username
post["content"] = postTextView.text
post.saveInBackground { (success, error) in
if error != nil {
let alert = UIAlertController(title: "HAT", message: error?.localizedDescription ?? "HATA", preferredStyle: UIAlertController.Style.alert)
let okButton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
alert.addAction(okButton)
self.present(alert, animated: true)
}else {
self.postTextView.text = ""
self.tabBarController?.selectedIndex = 0
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "veriGirildi"), object: nil)
}
}
}
}
}
I want to see like this
But when i runned my app it seems like this
Atil and ibrahimmbyrrm is just usernameLabel contents.Why it doesn't display other items on prototype cell
I want to see other users's posts on Home Page but my cell doesn't work successfully.I need help to fix it.I have this problem at all my projects.

Cannot infer contextual base in reference to member 'originalImage'

im trying to use imagePickerController and im getting this weird error "Cannot infer contextual base in reference to member 'originalImage'"
I've used this code before but im not sure why im getting this error this time, or how to fix it.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
{
guard let pickImage = info[.originalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
photoImageView.image = pickImage
dismiss(animated: true, completion: nil)
}
please help!
heres the full code:
class AddCardViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var saveButton: UIBarButtonItem!
#IBOutlet weak var questionField: UITextField!
#IBOutlet weak var answerField: UITextField!
#IBOutlet weak var photoImageView: UIImageView!
private let imagePickerController = UIImagePickerController()
let defaultImage = UIImage(named: "q")
private var newCard: Card?
private func updateSaveButtonState() {
let questionText = questionField.text ?? ""
let answerText = answerField.text ?? ""
saveButton.isEnabled = !questionText.isEmpty && !answerText.isEmpty
}
public func getCard() -> Card? {
return newCard
}
override func viewDidLoad() {
super.viewDidLoad()
photoImageView.image = defaultImage
questionField.delegate = self
answerField.delegate = self
}
#IBAction func pickImage(_ sender: Any) {
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
private func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let pickImage:UIImage = info [.originalImage] as? UIImage else {
fatalError("expected a dictionary containing an image, but was provided the following: \(info)")
}
photoImageView.image = pickImage
dismiss(animated: true, completion: nil)
}
func alertMessage(_ message: String) {
let alertController = UIAlertController(title: "Add a card", message: message, preferredStyle: UIAlertController.Style.alert)
alertController.addAction(UIAlertAction(title: "okie dokie", style: UIAlertAction.Style.default, handler: nil))
self.present(alertController, animated: true, completion: nil)
}
I just checked your code and it works for me.
It could be that you don't have an IBOutlet for photoImageView
If it isn't that, then I would need to see the rest of your imagePickerController code to understand what's wrong.
The issue was I was using Swift 4 when I should've been using Swift 5.

when fetch images from firebase, tableView not scroll to row Swift

I begin to create a chat app and want it to scroll to bottom every time I enter text or image. For text, the code is perfect to execute scrollToRow after tableView reload. However, the image always shows under the keyboard, I tried many ways to solve this issue but still get the same result.
image does not show above the keyboard
image is under keyboard
class ChatTableViewController: UITableViewController, UITextViewDelegate {
private let reuseIdentifier = "reuseIdentifier"
private let chatImageIdentifier = "chatImageCell"
var sSection = 0
var rRow = 0
var commentRef: DatabaseReference!
var firebaseHandle: DatabaseHandle?
var dataSnapshot: DataSnapshot?
let uid = FirebaseHelper.shared.getUserId()
let username = FirebaseHelper.shared.getUsername()
let email = FirebaseHelper.shared.getUserEmail()
var comments = [Comment]()
var intArray: [Int]? {
didSet{
guard let intArray = intArray else {return}
self.sSection = intArray[0]
self.rRow = intArray[1]
commentRef = FirebaseHelper.shared.getCommentRef(firebaseRef: .comments, section: sSection, row: rRow)
comments = []
tableView.reloadData()
observeCommentsFromFirebase {
}
setUpKeyboardObserver()
}
}
func observeCommentsFromFirebase(completion: #escaping (()->Void)) {
firebaseHandle = commentRef.queryOrdered(byChild: "timeStamp").observe(.childAdded, with: { (snapshot) in
self.dataSnapshot = snapshot
if let dictionary = snapshot.value as? [String: Any]{
let comment = Comment(dictionary: dictionary)
self.comments.append(comment)
DispatchQueue.main.async {
self.tableView.reloadData()
self.handleKeyboardDidShow()
completion()
}
}
}, withCancel: nil)
}
func setUpKeyboardObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidShow), name: UIResponder.keyboardDidShowNotification, object: nil)
}
#objc func handleKeyboardDidShow() {
if comments.count > 0 {
let indexPath = IndexPath(row: comments.count - 1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(ChatTableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
tableView.register(ChatImageCell.self, forCellReuseIdentifier: chatImageIdentifier)
tableView.separatorStyle = .none
tableView.allowsSelection = false
tableView.backgroundColor = grayColor
tableView.keyboardDismissMode = .interactive
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(handleDismiss))
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
tableView.alwaysBounceVertical = true
}
#objc func handleDismiss() {
if let firebaseHandle = firebaseHandle {
self.commentRef.removeObserver(withHandle: firebaseHandle)
}
NotificationCenter.default.removeObserver(self)
self.dismiss(animated: true, completion: nil)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let comment = comments[indexPath.row]
if comment.imageUrl != "" {
let cell = tableView.dequeueReusableCell(withIdentifier: chatImageIdentifier, for: indexPath) as! ChatImageCell
if comments.count != 0 {
cell.comment = comment
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! ChatTableViewCell
if comments.count != 0 {
cell.comment = comment
}
return cell
}
}
#objc func uploadImage() {
showImageActionSheet()
}
extension ChatTableViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
func showImageActionSheet() {
// declaring action sheet
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
// declaring camera button
let camera = UIAlertAction(title: "Camera", style: .default) { (action) in
// if there is camera, then execute
if UIImagePickerController.isSourceTypeAvailable(.camera) {
self.showPicker(with: .camera)
}
}
// declaring library button
let library = UIAlertAction(title: "Library", style: .default) { (action) in
// if there is library, then execute
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
self.showPicker(with: .photoLibrary)
}
}
// declaring cancel button
let cancel = UIAlertAction(title: "Cancel", style: .cancel)
// add action to the sheet
alertController.addAction(camera)
alertController.addAction(library)
alertController.addAction(cancel)
// present action sheet to the user
self.present(alertController, animated: true, completion: nil)
}
func showPicker(with source: UIImagePickerController.SourceType) {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
picker.sourceType = source
self.present(picker, animated: true, completion: nil)
}
// fetch selected image from info with key
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
var selectedImage: UIImage?
// declaring editedImage
if let editedImage = info[.editedImage] as? UIImage {
selectedImage = editedImage
} else if let originalImage = info[.originalImage] as? UIImage {
selectedImage = originalImage
}
self.dismiss(animated: true, completion: nil)
FirebaseHelper.shared.uploadImage(image: selectedImage, firebaseRef: .comment_images, viewController: self) {
urlString in
let timeStamp = Helper.shared.dateOfCurrentTimeZone()
let childKey = FirebaseHelper.shared.getChildKey()
let profileImageUrlString: String
if let profileImageUrl = FirebaseHelper.shared.getPhotUrl() {
profileImageUrlString = profileImageUrl.absoluteString
} else {
profileImageUrlString = ""
}
let values: [String: Any] = ["text": "", "uid": self.uid, "timeStamp": timeStamp, "childkey": childKey, "username": self.username, "email": self.email ?? "", "imageUrl": urlString, "profileImageUrl": profileImageUrlString]
self.commentRef.child(childKey).updateChildValues(values, withCompletionBlock: { (error, dataRef) in
if error != nil {
Helper.shared.alertController(title: "Error", message: error!.localizedDescription, viewController: self)
return
}
})
}
}
}

swift save multiple images from collection view to firebase storage and get downloadURL?

enter image description herePlease help me I want to upload multiple image from my uicollectionview to firebase Storage and show downloadURL in Realtime database
i have try to search a lot but it no one work for me.
i can import the pictures from libray and make it show in myCollectionView but i don't know how to save it in to firebase.
Reports
-(userID)
-(reportID) - Using childByAutoId
- where i want to save to image
import UIKit
import Firebase
class ProblemViewController: UIViewController, UITextViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
var reportID : String!
var phonNumber : String!
var ref: DatabaseReference!
let storage = Storage.storage()
let userID = Auth.auth().currentUser!.uid
#IBOutlet weak var problemButton: UIButton!
#IBOutlet weak var myCollectionView: UICollectionView!
#IBOutlet weak var problemImage: UIImageView!
var images = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
self.myCollectionView.delegate = self
self.myCollectionView.dataSource = self
retrieveUser()
generateReportID()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(importPicture))
}
#IBAction func sendProblemAction(_ sender: Any) {
//TODO: Storage image and Send information to Firebase and save it in our database
let imageName = UUID().uuidString
let storageRef = storage.reference().child("product_images/\(userID)/report/\(imageName).jpg")
if let uploadImage = problemImage.image!.jpegData(compressionQuality: 0.15) {
storageRef.putData(uploadImage, metadata: nil) { (metadata, error) in
if error != nil {
print("error")
return
}
storageRef.downloadURL(completion: {(url, error) in
if error != nil {
print(error!.localizedDescription)
return
}
let downloadURL = url?.absoluteString
let post = ["report_image_url": downloadURL!] as [String : Any]
self.registerUserIntoDatabase(userID: self.userID, values: post as [String : AnyObject])
})
}
}
self.navigationController?.popToRootViewController(animated: true)
}
private func registerUserIntoDatabase(userID: String, values: [String:AnyObject]){
//TODO: Send information to Firebase and save it in our database
ref = Database.database().reference()
let usersRef = ref.child("Reports").child("\(userID)/\(reportID!)")
usersRef.updateChildValues(values, withCompletionBlock: { (err, ref) in
})
}
func generateReportID () {
ref = Database.database().reference()
guard let key = self.ref.child("Reports").child("\(userID)/\(String(describing: reportID))").childByAutoId().key else { return }
reportID = key
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageView", for: indexPath)
if let imageView = cell.viewWithTag(1000) as? UIImageView {
imageView.image = images[indexPath.item]
}
return cell
}
#objc func importPicture() {
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "picture", style: .default, handler: { (action) in
picker.sourceType = .photoLibrary
self.present(picker, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "cancel", style: .default, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.editedImage] as? UIImage else { return }
dismiss(animated: true)
images.insert(image, at: 0)
myCollectionView.reloadData()
print("key = \(image)")
}
}
I want to upload multiple images that show in uicollectionview to my firebase storage and show downloadURL in realtime database.
like this
Reports
-(userID)
-(reportID) - Using childByAutoId
- image1 : "https://firebasestorage.googleapis.com/..."
- image2 : "https://firebasestorage.googleapis.com/..."
- image3 : "https://firebasestorage.googleapis.com/..."
- image4 : "https://firebasestorage.googleapis.com/..."
My UICollection
When i press save it will error like this
My error

Error in Table View Controller When using a segue Fatal error: Index out of range

I've ran into a problem and i cant resolve it
TableViewController:
var items: [String?] = ["door","table","chair"]
var givenDescription: [String?] = ["Change the description using
class TableViewController: UITableViewController, UIToolbarDelegate {
the edit option"]
#IBOutlet var myTableView: UITableView!
override func viewDidAppear(_ animated: Bool) {
myTableView.reloadData()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = items[indexPath.row]
cell.detailTextLabel?.text = givenDescription[indexPath.row]
return cell
}
ViewController:
import UIKit
import MobileCoreServices
class AddViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var newPic: Bool?
//Outlets
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var addName: UITextField!
#IBOutlet weak var addDescription: UITextField!
#IBAction func addImage(_ sender: Any) {
let myAlert = UIAlertController(title: "Select Image From", message: "", preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: nil)
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
self.newPic = true
}
let cameraRoll = UIAlertAction(title: "Camera Roll", style: .default, handler: nil)
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
self.newPic = false
}
myAlert.addAction(cameraAction)
myAlert.addAction(cameraRoll)
self.present(myAlert, animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let mediaType = info[UIImagePickerControllerMediaType] as! NSString
if mediaType.isEqual(to: kUTTypeImage as String) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
imageView.image = image
if newPic == true {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(imageError), nil)
}
}
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
#objc func imageError(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafeRawPointer) {
if error != nil {
let alert = UIAlertController(title: "Save Failed", message: "Failed to save image", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Okay", style: .cancel, handler: nil)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
}
}
//Action
#IBAction func create(_ sender: Any) {
if (addName.text != "") {
items.append(addName.text!)
addName.text = ""
}
if (addDescription.text != "") {
givenDescription.append(addDescription.text!)
addDescription.text = ""
}
self.navigationController?.popViewController(animated: true)
}
}
You can "fix" the create function in several ways, for example like this:
#IBAction func create(_ sender: Any) {
if (addName.text != "" && addDescription.text != "") {
items.append(addName.text!)
addName.text = ""
givenDescription.append(addDescription.text!)
addDescription.text = ""
}
self.navigationController?.popViewController(animated: true)
}
but a much better option is to create a simple struct
struct Item {
var name: String
var itemDescription: String
}
and use it instead
#IBAction func create(_ sender: Any) {
if (addName.text != "" && addDescription.text != "") { //or just check one depending on if one is more important
let item = Item(name: addName.text!, itemDescription: addDescription.text!)
items.append(item)
}
self.navigationController?.popViewController(animated: true)
}
and the items array is defined as
var items: [Item]()
andd for your table view
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
let item = items[indexPath.row]
cell.textLabel?.text = item.name
cell.detailTextLabel?.text = item.itemDescription
return cell
}
This was the answer so simple.
#IBAction func create(_ sender: Any) {
if (addName.text != "" && addDescription.text != "") {
items.append(addName.text!)
addName.text = ""
givenDescription.append(addDescription.text!)
addDescription.text = ""
}
self.navigationController?.popViewController(animated: true)
}