I am using Firebase Authentication Tutorial 2020 - Custom iOS Login Page (Swift) - YouTube this video to create a sign-in and login page for my app. Although the creation and logging in of the app is successful, when I segue into my ViewController with a tableview, whenever I click on the tableviewcells a segue that is supposed to happen does not happen.
LoginViewController code:
‘’’
//
// LoginViewController.swift
// CM PT
//
// Created by Lim Jun Rui on 22/9/22.
//
import UIKit
import FirebaseAuth
import Firebase
class LoginViewController: UIViewController {
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var logInButton: UIButton!
@IBOutlet weak var errorLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
setUpElements()
}
func setUpElements() {
//Hide Error Label
errorLabel.alpha = 0
//Styling TextFields
Utilities.styleTextField(emailTextField)
Utilities.styleTextField(passwordTextField)
Utilities.styleFilledButton(logInButton)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
@IBAction func loginTapped(_ sender: Any) {
//Validate Text Fields (Todo)
//Log the user in
let email = emailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let password = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
Auth.auth().signIn(withEmail: email, password: password) { (Result, error) in
if error != nil {
self.errorLabel.text = error!.localizedDescription
self.errorLabel.alpha = 1
}
else {
let homeViewController = self.storyboard?.instantiateViewController(withIdentifier: Constants.Storyboard.homeViewController) as? TableViewVideoViewController
self.view.window?.rootViewController = homeViewController
self.view.window?.makeKeyAndVisible()
}
}
}
}
‘’’
SignUpViewController:
‘’’
//
// SignUpViewController.swift
// CM PT
//
// Created by Lim Jun Rui on 22/9/22.
//
import UIKit
import FirebaseAuth
import Firebase
import FirebaseFirestore
import AVFAudio
class TabBarController: UITabBarController {
}
class SignUpViewController: UIViewController {
@IBOutlet weak var firstNameTextFIeld: UITextField!
@IBOutlet weak var lastNameTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var signUpButton: UIButton!
@IBOutlet weak var errorLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
setUpElements()
}
func setUpElements() {
//Hide Error Label
errorLabel.alpha = 0
//Styling TextFields
Utilities.styleTextField(firstNameTextFIeld)
Utilities.styleTextField(lastNameTextField)
Utilities.styleTextField(emailTextField)
Utilities.styleTextField(passwordTextField)
Utilities.styleFilledButton(signUpButton)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
//Checks fields to see if the data inputted by the user is correct. If it is correct, it will return nil, if it is incorrect, it will return the error message.
func validateFields() -> String? {
//Check if all fields are filled in
if firstNameTextFIeld.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
lastNameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
emailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
passwordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == ""{
return "Please fill in all fields."
}
//Check if password is safe :D
let cleanedPassword = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
if Utilities.isPasswordValid(cleanedPassword) == false {
return "Password is not secure, please ensure that your password contains at least 8 characters, contains a special character and a number."
}
return nil
}
@IBAction func signUpTapped(_ sender: Any) {
//Validate Fields
let error = validateFields()
if error != nil {
//There's an error!!!
showError(error!)
}
else {
//No error :D
//Create user yay (i am losing my mind)
let firstName = firstNameTextFIeld.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let lastName = lastNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let email = emailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let password = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
Auth.auth().createUser(withEmail: email, password: password) {(result, err) in
//Check for errors
if err != nil {
print(err?.localizedDescription)
//ERROR ALERT
self.showError("Error creating user, too bad")
}
else {
//User created successfully yay :D
let db = Firestore.firestore()
db.collection("users").addDocument(data: ["firstname" : firstName, "lastname" : lastName, "uid" : result!.user.uid]) { (error) in
if error != nil {
self.showError("There was a problem saving your data, please try again.")
}
}
//Segue to home screen
self.transitionToHome()
}
}
}
}
func showError(_ message : String) {
errorLabel.text = message
errorLabel.alpha = 1
}
func transitionToHome() {
//The Segue
let homeViewController = storyboard?.instantiateViewController(withIdentifier: Constants.Storyboard.homeViewController) as? TableViewVideoViewController
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
}
}
‘’’
The ViewController (there’s a searchbar as well as a segmented control, i dunno if it affects anything just might be worth telling):
‘’’
//
// ShirtsNETableViewController.swift
// CM PT
//
// Created by Lim Jun Rui on 22/8/22.
//
//THINGS YOU NEED TO DO:
//CREATE A DATA UPDATE FUNCTION
//MAKE THE VIDEO LINK INTO AN ACTUAL VIDEO
//MAKE THE IMAGES WORK
//DESIGN
import AVKit
import AVFoundation
import UIKit
class TableViewVideoCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var subtextLabel: UILabel!
@IBOutlet weak var vidImageView: UIImageView!
@IBOutlet weak var cellView: UIView!
}
class TableViewVideoViewController: UIViewController, UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource {
var classmate = MyData().Alldata
var NE = MyData().dataNE
var E = MyData().dataE
var allDataNames = MyData().allDataNames
var allDataNENames = MyData().dataNENames
var allDataENames = MyData().dataENames
var allDataImgCode = MyData().allDataImgCode
var allDataNEImgCode = MyData().dataNEImgCode
var allDataEImgCode = MyData().dataEImgCode
var NENames = MyData().dataNENames
var ENames = MyData().dataENames
var filteredData = MyData().allDataNames
var filteredDataNE = MyData().dataNENames
var filteredDataE = MyData().dataENames
var filteredDataImgCode = MyData().allDataImgCode
var filteredDataNEImgCode = MyData().dataNEImgCode
var filteredDataEImgCode = MyData().dataEImgCode
@IBOutlet var tableView: UITableView!
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var videoSearch: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
//Setup
self.filteredData = allDataNames
self.filteredDataNE = allDataNENames
self.filteredDataE = allDataENames
self.filteredDataImgCode = allDataImgCode
self.filteredDataNEImgCode = allDataNEImgCode
self.filteredDataEImgCode = allDataEImgCode
//making tableview look good
tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
}
/*
func updateTasks() {
guard let count = UserDefaults().value(forKey: "count") as? Int else {
return
}
for x in 0..<count {
if let task = UserDefaults().value(forKey: "task_\(x + 1)") as? String {
tasks.append(task)
}
}
tableView.reloadData()
}
@IBAction func didTapAdd() {
let vc = storyboard?.instantiateViewController(identifier: "entry") as! EntryViewController
vc.title = "New Task"
vc.update = {
DispatchQueue.main.async {
self.updateTasks()
}
}
navigationController?.pushViewController(vc, animated: true)
}
*/
// MARK: - Table view data source
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let category = classmate[indexPath.row]
let vc = ShowVideoViewController(items: category.imgCode)
vc.title = category.name
navigationController?.pushViewController(vc, animated: true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = self.tableView.indexPathForSelectedRow
let items = classmate[indexPath?.row ?? 0].imgCode
if let videoVC = segue.destination as? ShowVideoViewController {
try? videoVC.var1 = items
}
}
func numberOfSections(in tableView: UITableView) -> Int {
// We will be only having 1 section for this lesson
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// This varies according to how many classmates we have in the array
switch segmentedControl.selectedSegmentIndex {
case 0:
return filteredData.count
case 1:
return filteredDataNE.count
case 2:
return filteredDataE.count
default:
break
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yesCell", for: indexPath) as! TableViewVideoCell
// Configure the cell…
switch segmentedControl.selectedSegmentIndex {
case 0:
let classmate2 = self.filteredData[indexPath.row]
let classmate3 = self.filteredDataImgCode[indexPath.row]
cell.titleLabel?.text = classmate2//NEW
cell.vidImageView?.image = UIImage(named: classmate3)
case 1:
let classmate2 = self.filteredDataNE[indexPath.row]
let classmate3 = self.filteredDataNEImgCode[indexPath.row]
cell.titleLabel?.text = classmate2 //NEW
cell.vidImageView?.image = UIImage(named: classmate3)
case 2:
let classmate2 = self.filteredDataE[indexPath.row]
let classmate3 = self.filteredDataEImgCode[indexPath.row]
cell.titleLabel?.text = classmate2 //NEW
cell.vidImageView?.image = UIImage(named: classmate3)
default:
break
}
cell.cellView.layer.cornerRadius = 10
//cell.cellView.layer.borderWidth = 1
//cell.cellView.layer.borderColor = UIColor.black.cgColor
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
switch segmentedControl.selectedSegmentIndex {
case 0:
if searchText != "" {
filteredData = allDataNames.filter{($0.contains(searchText))}
} else {
self.filteredData = allDataNames
}
tableView.reloadData()
case 1:
if searchText != "" {
filteredDataNE = allDataNENames.filter{($0.contains(searchText))}
} else {
self.filteredDataNE = allDataNENames
}
tableView.reloadData()
case 2:
if searchText != "" {
filteredDataE = allDataENames.filter{($0.contains(searchText))}
} else {
self.filteredDataE = allDataENames
}
tableView.reloadData()
default:
break
}
}
@IBAction func segmentedChanged(_sender: Any) {
tableView.reloadData()
}
}
// videoVC.imgCode = classmate[indexPath?.row ?? 0].imgCode
/* override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) → Int {
return (data2.myDB.count + tasks.count)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) → UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: “cell”, for: indexPath) as! CountryTableViewCell
let country = data2.myDB[indexPath.row]
cell.titleLabel?.text = country.name
cell.subtextLabel?.text = country.isoCode
cell.vidImageView?.image = UIImage(named: country.isoCode)
return cell
}*/
/*func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = []
if searchText == "" {
filteredData = data3.data
}
else {
for dataSet in data3.data {
if dataSet.lowercased().contains(searchText.lowercased()) {
filteredData.append(dataSet)
}
}
}
self.tableView.reloadData()
}
}
*\*/
‘’’
The Data File:
‘’’
//
// MyData.swift
// CM PT
//
// Created by Lim Jun Rui on 22/8/22.
//
import Foundation
class MyData {
struct Classmate {
var name : String
var imgCode : String
var description : String
public init(name : String, imgCode : String, description : String) {
self.name = name
self.imgCode = imgCode
self.description = description
}
}
var Alldata = [
Classmate(name: "Shirt to cltoh", imgCode: "el", description: "yes"),
Classmate(name: "Skirt to cltoh", imgCode: "el", description: "yes"),
Classmate(name: "Towel to cltoh", imgCode: "el", description: "yes"),
Classmate(name: "Pants to cltoh", imgCode: "ptc", description: "yes"),
Classmate(name: "Shirt to cltoh", imgCode: "stcE", description: "yes"),
Classmate(name: "Skirt to cltoh", imgCode: "sktcE", description: "yes"),
Classmate(name: "Towel to cltoh", imgCode: "ttcE", description: "yes"),
Classmate(name: "Pants to cltoh", imgCode: "ptcE", description: "yes")]
var dataNE = [
Classmate(name: "Shirt to cltoh", imgCode: "el", description: "yes"),
Classmate(name: "Skirt to cltoh", imgCode: "el", description: "yes"),
Classmate(name: "Towel to cltoh", imgCode: "el", description: "yes"),
Classmate(name: "Pants to cltoh", imgCode: "ptc", description: "yes")]
var dataE = [
Classmate(name: "Shirt to cltoh", imgCode: "stcE", description: "yes"),
Classmate(name: "Skirt to cltoh", imgCode: "sktcE", description: "yes"),
Classmate(name: "Towel to cltoh", imgCode: "ttcE", description: "yes"),
Classmate(name: "Pants to cltoh", imgCode: "ptcE", description: "yes")]
var allDataNames = ["Shirt to cltoh", "Skirt to cltoh", "Towel to cltoh", "Pants to cltoh", "Shirt to cltoh", "Skirt to cltoh", "Towel to cltoh", "Pants to cltoh"]
var dataNENames = ["Shirt to cltoh", "Skirt to cltoh", "Towel to cltoh", "Pants to cltoh"]
var dataENames = ["Shirt to cltoh", "Skirt to cltoh", "Towel to cltoh", "Pants to cltoh"]
var allDataImgCode = ["el", "el", "el", "ptc", "stcE", "sktcE", "ttcE", "ptcE"]
var dataNEImgCode = ["el", "el", "el", "ptc"]
var dataEImgCode = ["stcE", "sktcE", "ttcE", "ptcE"]
}
class UserData {
struct Classmate2 {
var name : String
var imgCode : String
var description : String
}
var AllUserdata = [
Classmate2(name: "Shirt to cltoh", imgCode: "el", description: "NE"),
Classmate2(name: "Towel to cloth", imgCode: "at", description: "E")]
var dataUserNE = [
Classmate2(name: "Shirt to cltoh", imgCode: "el", description: "NE"),
]
var dataUserE = [
Classmate2(name: "Towel to cltoh", imgCode: "at", description: "E"),
]
var allUserDataNames = ["Shirt to cltoh", "Towel to cloth"]
var dataUserNENames = ["Shirt to cltoh"]
var dataUserENames = ["Towel to cltoh"]
var allUserDataImgCode = ["el", "at"]
var dataUserNEImgCode = ["el"]
var dataUserEImgCode = ["at"]
}
‘’’
The ViewController I want to segue to:
‘’’
//
// testViewController.swift
// CM PT
//
// Created by Lim Jun Rui on 26/8/22.
//
import AVKit
import AVFoundation
import UIKit
import WebKit
class ShowVideoViewController: UIViewController {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var buttonVideo: UIButton!
var var1 : String!
var selectedVideo : MyData!
private let items : String?
init(items : String) {
self.items = items
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@IBAction func playVideo(_sender: Any) {
if let path = Bundle.main.path(forResource: "videoplayback", ofType: "mp4") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
present(videoPlayer, animated : true, completion : {
video.play()
})
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
]
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.frame = view.bounds
}
}
‘’’
Sorry if this is a lot, and thanks for reading!