Get count of child in firebase when view controller is showing - ios

I have a collection view with a list of matches cell and a button to add new matches.
I'd like to have the same numbers of cell as per matches (IE: 10 matches, 10 cells) . I want the list every time the view appears.
var countOfMatches = [DataSnapshot]()
viewWillAppear {
ref.child("matches").observe(.childAdded, with: { (snapshot) in
self.countOfMatches = [DataSnapshot]()
for item in snapshot.children {
self.countOfMatches.append(item as! DataSnapshot)
}
})}
and in the collection view
return countOfMatches.count
Why my cells are not showing? I can see the results created under /matches in Firebase DB but not the cells

You should use .value instead of .childAdded.
Also you should reload the tableView.reloadData() method.

Related

sorting UITableview rows in a UI Segmented Controller

I am using a Segmented controller to control how data is presented in my table view. One of the views should be chronologically which is easy because I use firebase so the query is effectively already chronological. However, I want to sort by highest rated which is a computed value (the "number of likes" is the count of a child which is an array of users who clicked "like". the table view controller instantiates an array:
var media = [Media]()
and a function fetches the media and ends like this:
let ref = DatabaseReference.media.reference()
let query = ref.queryOrdered(byChild: "uid").queryEqual(toValue: (value))
query.observe(.childAdded, with: { snapshot in
let media = Media(dictionary: snapshot.value as! [String : Any])
if !self.media.contains(media) {
self.media.insert(media, at: 0)
I think I need to make 2 different arrays and use a switch statement on segmented controller before the last 2 lines to populate them, then use switch statements in my TableView Data Source to read the associated arrays. Is this the right idea? If so, how do I sort snapshots?

swift iOS filter on array containing uitableviews

func convertPointToIndexPath(_ point: CGPoint) -> (UITableView, IndexPath)? {
if let tableView = [tableView1, tableView2, tableView3].filter({ $0.frame.contains(point) }).first {
let localPoint = scrollView.convert(point, to: tableView)
let lastRowIndex = focus?.0 === tableView ? tableView.numberOfRows(inSection: 0) - 1 : tableView.numberOfRows(inSection: 0)
let indexPath = tableView.indexPathForRow(at: localPoint) ?? IndexPath(row: lastRowIndex, section: 0)
return (tableView, indexPath)
}
return nil
}
So i got this method, which converts a CGPoint into the indexPath of the given uitableView. I struggle with the filter-Method on the array which contains uitableViews.
I got an array outside of this method which contains any number of uitableViews. For example:
public var littleKanbanColumnsAsTableViews: [UITableView] = []
So i got to make a change inside of the method. Like this:
if let tableView = littleKanbanColumnsAsTableViews.filter({ $0.frame.contains(point)}).first { ... }
Now when i click on any tableView on the gui, i track the coordinates of the point and transform it on the belonging tableview with the frame.contains(point) method.
My problem is that the filter is not working, it always gives me the first tableView back, no matter which tableview is clicked. Why it doesn't work with my littleKanbanColumnsAsTableViews-Array?
One hint:
let tableView = littleKanbanView.littleKanbanColumnsAsTableViews[3]
When i indexing its direct then it works. But i want it depending on which tableView is containing the clicked point.
Here is my array with the tableViews, in this case the array contains 5 tableviews.
array containing tableviews
Now i want to filter the tableView out of them, which includes the point from tapping on this tableView. How can i achieve this?
For more understanding, i add the ui, here is it:
UI of my app
When i click on this tableView it works, because it is the first element in my array of tableViews. So for this case the convertPointToIndexPath-Method is working.
But when i scroll horizontally to the second tableView for example and click on that, it doesn't work. Because I think the method gives me always the first element back, but i thought it filters it with the given condition.
What is the problem, why doesn't work the condition{ $0.frame.contains(point)}? It have to localize the tableView when the coordinates of the point are tracked.
Preferred Solution:
In this case the moment the first satisfying condition is met, the rest of the elements are not traversed.
if let tableView = littleKanbanColumnsAsTableViews.first(where: { $0.frame.contains(point) }) {
}
Not so efficient solution:
In this case all the elements in the array are traversed to build an array of table views that satisfy the condition. Then the first element of that filtered array is chosen.
if let tableView = (littleKanbanColumnsAsTableViews.filter{ $0.frame.contains(point)}).first {
}

Is there any way to grab the text and detail text labels of multiple selected table view cells in swift?

I have some code right now that gets what cells were selected. The following is my code for doing that:
if let selectedUserRows = self.tableView.indexPathsForSelectedRows {
self.groupUserArray.append(selectedUserRows)
for index in selectedUserRows {
let text = groupUserArray[index.row]
print(text)
}
}
The new error is saying that the index is out of range!
I was trying to use the logic for grabbing one selected cells text but it does not work. So I was wondering if anyone knew how to grab multiple selected cell's text?
Any help would be appreciated!
self.tableView.indexPathsForSelectedRows returns a [IndexPath]? so if you obtain an array of all the rows and sections of you selected rows. I suppose you are using some sort of collection to populate your tableView (in my example I will call it textArray: [String] ) so you can do something like that to get all the text you need:
if let selectedUserIndexes = self.tableView.indexPathsForSelectedRows {
for index in selectedUserIndexes {
let text = textArray[index.row]
}
}

Updating Table View after Updating Values in Firebase

I'm able to successfully update my entries in Firebase, for it shows up on the console, but not the table view. If I restart my app the changes will then show, but I want them to show immediately.
My approach is to edit the array that populates the tableview as soon possible under the "ChildChanged" notification.
ref.observeEventType(.ChildChanged, withBlock: { (snapshot) in
print("One of the entries were changed so we're reloading the table view")
if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname")
{
let fullname = "\(firstname) \(lastname)"
names[I_Need_This_Index] = fullname
dispatch_async(dispatch_get_main_queue())
{
self.tableView.reloadData()
}
}
}, withCancelBlock: nil)
As you can see, I just need to locate index of what I need, for I already have the "fullname" value which is the edited value that I wish to update the table view with.
How would I go about doing that?
You need to lookup the index using the key of the changed child. Therefore a dictionary could be set up initially to map the keys for all children to the index of your tableview cell when receiving all values.
Edit:
If you need the old value itself you have to obtain the initial change snapshot yourself.

Create an array for each collection view cell

I am trying to create a collection view with custom collection view cells.
I want to keep track of the number of times each cell is tapped and store in an array. So, my custom cell has a label, IBAction and an array.
I am able to do this by appending 1 to the array inside IBAction and printing out the count.
However, I want to access this data outside the custom cell view class. I want to have an array specific to each cell i.e. by the name
self.titleLabel.text!
Of course, I can't use a variable for the name of an array! (I wish I could)
How do I store data in such case?
Where and how do I need to define the array to easily store and process data?
You may declare Dictionary that holds tap count in your UIViewController:
var tapCounts = [NSIndexPath: Int]()
let collectionView = UICollectionView()
func tapAction(sender: UICollectionViewCell) {
if let indexPath = collectionView.indexPathForCell(sender) {
tapCounts[indexPath] = (tapCounts[indexPath] ?? 0) + 1
}
}

Resources