Sort multiple data from the rapid fire base in Table view cell in alphabetical order by Initials Gold - swift4

I'm doing a dictionary application. firebase also has a dictionary title and description. I pull this data into x code. I will show the title in the table view cell. but I could not sort it in alphabetical order, for example;
to
apple
B
book
I want to sort it.
I will only list fizik.baslik. swift 4, I work in xcode 10.3
class FizikSozluk{
var fizik_id : String?
var baslik :String?
var aciklama:String?
var animasyonAdi:String?
#IBOutlet weak var tableview: UITableView!
#IBOutlet weak var seachbar: UISearchBar!
var fizikListe = [FizikSozluk]()
var ref : DatabaseReference!
extension ViewController2 : UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
fizikListe.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let fizik = let fizik = self.fizikListe.sorted(by: { $0.baslik ?? "" < $1.baslik ?? ""})[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "sozluk", for: indexPath) as? TableViewCell
cell?.baslik.text = fizik.baslik
return cell!
}
Sort the information alphabetically with the above code. however, with the staging function, the information I send to the other view controller is mixed. I also want to sort the information under letters.
A
apple
B
book

Related

I can't show data in UITableView

I'm new to swift, I made a simple table and added 21 data in it.
When I debug, the compiler enters here, I see that there are 21.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(menus.count)
return menus.count
}
but it doesn't go into this part
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "mCell", for: indexPath) as! HomeViewCell
let men = menus[indexPath.row]
print(men.Title)
cell.mTitle.text = men.Title
cell.subTitle.text = men.SubTitle
return cell
}
I'm learning new things from books, videos, sorry for the newbie question
I think I've done all the work but I couldn't figure out what I'm skipping I watched too many videos and I'm confused
all code,
class ViewController: UIViewController , UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var menuTable: UITableView!
var menus = [Menu]()
override func viewDidLoad() {
super.viewDidLoad()
loadMenus()
}
override func viewDidLayoutSubviews(){
}
func loadMenus(){
for index in 0...20 {
menus.insert(Menu(Image: "0", Title: "String \(index)", SubTitle: "String"), at: index)
}
self.menuTable.reloadData()
// DispatchQueue.main.async {
//
// }
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(menus.count)
return menus.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "mCell", for: indexPath) as! HomeViewCell
let men = menus[indexPath.row]
print(men.Title)
cell.mTitle.text = men.Title
cell.subTitle.text = men.SubTitle
return cell
}
}
class HomeViewCell: UITableViewCell {
#IBOutlet weak var mTitle: UILabel!
#IBOutlet weak var subTitle: UILabel!
#IBOutlet weak var mImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
I tried your code and everything works well.
The only thing I can think of:
Make sure you have assigned the class to the table view cell and connected the outlets.
What you showed me above is the identifier. See below for class.
After I do this, I see the result:
Output in the console
21
21
21
String 0
String 1
String 2
String 3
String 4
String 5
String 6
String 7
String 8
String 9
String 10
String 11
String 12
String 13
String 14
Can you confirm you assigned HomeViewCell class to the Cell in storyboard ?
Update
You use auto layouts to set up your table and give the cell a height of 138 but you do not add any constraints for the subviews within your cell so I believe the runtime is unable to determine the actual height of your cell if the subviews in the cell do not have proper constraints.
add this UITableView delegate method and run your app to see if you see results:
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 138
}
Of Course, change 138 to whatever you want or better yet configure your cell layout in autolayout.
End result:
Try adding this in viewDidLoad:
menuTable.register(HomeViewCell.self, forCellReuseIdentifier: "mCell")

Sorting multiple data from swift firebase in alphabetical order in tableview cell

I'm doing a dictionary application. firebase also has a dictionary title and description. I pull this data into x code. I show the title in the tableview cell. but I could not sort by alphabetical order, I will just sort the fizik.baslik.
I'm working in swift 4, xcode 11
class FizikSozluk{
var fizik_id : String?
var baslik :String?
var aciklama:String?
var animasyonAdi:String?
class ViewController2: UIViewController {
#IBOutlet weak var tableview: UITableView!
#IBOutlet weak var seachbar: UISearchBar!
var fizikListe = [FizikSozluk]()
var ref : DatabaseReference!
extension ViewController2 : UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
fizikListe.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let fizik = fizikListe[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "sozluk", for: indexPath) as? TableViewCell
cell?.baslik.text = fizik.baslik
return cell!
}
I want to do the alphabetical order in cell? .baslik.text = fizik.baslik
Modify your fizik declaration in cellForItem to this:
let fizik = self.fizikListe.sorted(by: { $0.baslik ?? "" < $1.baslik ?? ""})[indexPath.row]

Define new variable for each index of an array

I am creating a grade logging iOS app that takes a users input of a grade and stores that grade into an array. Then on a separate view all of the grades are spit out into a cell table. I would like to create a new cell each time that the user inputs a new grade, rather than currently having the cells appear as hardcoded specific cells.
I was thinking some sort of for loop could be created... but I don't know how to do so.
struct MyVariables {
static var physicsExamGradesArray = [Double]()
static var GradeArray = [Double]()
static let classesOption = ["Choose Class", "Physics", "Math"]
static let assignmentOption = ["Choose Type","Exam", "Quiz", "Homework"]
static var physicsGradesArray = [Double]()
}
import UIKit
class GradeLogViewController: UIViewController {
#IBOutlet var tableView: UITableView!
var gradesCellsToBeDisplayed: [GradeProperties] = []
override func viewDidLoad() {
super.viewDidLoad()
gradesCellsToBeDisplayed = createArray()
}
}
func createArray() -> [GradeProperties] {
var grades: [GradeProperties] = []
let grade1 = GradeProperties(assignmentClass: "Physics", assignmentType: "Exam", assignmentIndex: 1, assignmentGrade: MyVariables.physicsExamGradeArray[0])
let grade2 = GradeProperties(assignmentClass: "Physics", assignmentType: "Exam", assignmentIndex: 2, assignmentGrade: MyVariables.physicsExamGradeArray[1])
grades.append(grade1)
grades.append(grade2)
return grades
}
extension GradeLogViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return gradesCellsToBeDisplayed.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let displayedGrade = gradesCellsToBeDisplayed[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "PhysicsCell") as! PhysicsCell
cell.setContents(grade: displayedGrade)
return cell
}
}
Right now I have two grade cells hardcoded... but I would like for the cells to auto generate based on the number of grades that are inputted...
--EDIT--
The user inputs their grades through a UITextField, and the values are passed into variables shown under struct MyVariables.

Firebase Database, display data at second app load

I'm using Firebase to store the data from my app.
Right now I can manage to save and delete my data inside Firebase database. My database structure is:
I'm facing the following problem: once app loads i'm able to save and display the data entered in Firebase, on the UITableView, but if I reload and open again the app the UITableView is empty. I would like to display the data stored in the database.
Here my code:
import UIKit
import Firebase
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
var emptyArray = [String] ()
var depAirp : String = ""
var destAirp : String = ""
var routeName : String = ""
var ref: DatabaseReference!
var keyArray = [String] ()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate=self
tableView.dataSource=self
ref = Database.database().reference()
tableView.allowsMultipleSelectionDuringEditing = true
// //create array for table view to be dispaly from fire base
ref.child("Rotta").observe(.childAdded, with: { (snapshot) in
let post = snapshot.value as? String
if let actualPost = post {
self.emptyArray.append(actualPost)
self.tableView.reloadData()
}
})
}
// display array on table view
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellid", for: indexPath)
let text = emptyArray[indexPath.row]
cell.textLabel?.text=text
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return emptyArray.count
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
//delate data at table view
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
emptyArray.remove(at: indexPath.row)
ref.child("Rotta").child(routeName).removeValue()
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
}
}
// button take data from 2 text field and save into the var and create the name for the routing name
#IBAction func button1(_ sender: Any) {
depAirp = textField1.text!
destAirp = textField2.text!
view.endEditing(true)
routeName=("\(depAirp)-\(destAirp)")
ref.child("Rotta").child(routeName).setValue(routeName)
ref.child("Rotta").child(routeName).child("Dep Airport").setValue(depAirp)
ref.child("Rotta").child(routeName).child("Dest Airport").setValue(destAirp)
print(routeName)
textField1.text=""
textField2.text=""
view.endEditing(true)
}
}
You have used observe, what that does it reads data once (in your case when you pressed run on the simulator) and then it continuously listens for changes, so when you close and open the app nothing is loaded on your UITableView as it has already been loaded once and no changes have been made.
You have two options:
Detach the listener when you leave the ViewController. See more here on https://firebase.google.com/docs/database/ios/read-and-write under detach listeners.
Instead of observe use observeSingleEvent. This will be called once and then get removed automatically.
You know the requirements of your app, you need to evaluate which approach is the suitable once.
Just remove below code from viewDidLoad() and put it inside viewWillAppear(), as below:
ref.child("Rotta").observe(.childAdded, with: { (snapshot) in
let post = snapshot.value as? String
if let actualPost = post {
self.emptyArray.append(actualPost)
self.tableView.reloadData()
}
})

UITableViewCell Separator using a date

I have a ViewController in which I have 2 TextFields and one DatePicker view when I click my Save Button I want to use the date I picked to be the section Header of my TableviewController. If other Objects follow and they have the same date they should all group together in the same date Section. I'm not using CoreData in this project so please don't propose using the method that CoreData Provides for this Task.enter image description here
Here's a simple implementation, which takes your tableData, and maintains a list of unique dates to be used as section headers. In this example, I recreate the headers from scratch , but in a real implementation, you may want to update instead.
I defined a struct for my sample data
struct SampleData
{
var date = Date()
var textField1 = ""
var textField2 = ""
}
and created some data
var tableData : [SampleData] = []
var tableDataSectionHeaderData : [Date] = []
override func viewDidLoad()
{
super.viewDidLoad()
tableData.append(SampleData(date: stringAsDate("Feb 13, 2017")!, textField1: "Title 1", textField2: "text2"))
tableData.append(SampleData(date: stringAsDate("Feb 13, 2017")!, textField1: "Title 2", textField2: "text2"))
tableData.append(SampleData(date: stringAsDate("Feb 14, 2017")!, textField1: "Title 3", textField2: "text2"))
// and so on...
createSectionHeaders()
}
func createSectionHeaders()
{
tableDataSectionHeaderData.removeAll() // in a realistic scenario, you would probably update this rather than recreating from scratch
for entry in tableData
{
if !tableDataSectionHeaderData.contains(entry.date)
{
tableDataSectionHeaderData.append(entry.date)
}
}
}
I have a couple of functions defined to switch between Date and String.
here's how to implement the tableView methods
extension ViewController : UITableViewDelegate, UITableViewDataSource
{
func numberOfSections(in tableView: UITableView) -> Int
{
return tableDataSectionHeaderData.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let filteredData = tableData.filter{$0.date == tableDataSectionHeaderData[section]}
return filteredData.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
return dateAsString(tableDataSectionHeaderData[section])
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let filteredData = tableData.filter{$0.date == tableDataSectionHeaderData[indexPath.section]}
cell.textLabel?.text = "\(dateAsString(filteredData[indexPath.row].date)) \(filteredData[indexPath.row].textField1)"
return cell
}
}