Reorder Uitableview with Parse Objects? - ios

I am trying to figure out how to reorder my Tableview of parse objects and get them to stay.
I can get the tableview items to move around, but the order doesn't save and reverts back to the original order as soon as I leave the Viewcontroller and go back. I have the tableview being populated from a query every time it loads.
I need to figure out how to save the new index order back to parse. I'm not sure how to do that. Here is some of the code I'm working with... or the lack there of.
I have seen people rearrange a static array, but I haven't found information on rearranging a dynamic parse query.
var thisArray:[PFObject] = [PFObject]()
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
//How do I rearrange the parse objects on the backend?
}

Related

Push to the next table view

I have two table views containing data, the first one is completely okay. I want to push from this table view to another view to another table view, but I cannot set the rows for it. How can I navigate through a multidimensional array in
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
Basically, my problem is about setting the right text for a row and getting from a multidimensional array :) (P.S. I have a different number of Strings in each subarray)
You just need to check on which tableView you are setting the values.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if tableView == myFirstTableView {
// put the data for the first tableView
} else {
// put the data for the second tableview
}
}

How to swap two custom cells with one another in tableview?

I have implemented two custom cells in the tableview.Now I want to replace these two custom cells with one another. How to achieve this?
Implement following tableview methods and write your code in it
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// return boolean value for a specific or all cells, you want to enable movement
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// Handle array element movement along with your row/cell
}
Share your full source code better help
If you would like to reorder rows in UITableView. Take a look at two delegates that are implemented in the UITableView.
They are: tableView:canMoveRowAtIndexPath: and moveRowAtIndexPath:toIndexPath:.
Also take a look at tutorial that show how it is possible to implement.
Along with tableview delegates, use moveRow(at: <IndexPath>, to: <IndexPath>), to move your row programatically (automatically), without user interaction.
tblTabel.moveRow(at: <IndexPath>, to: <IndexPath>)
// Tableview Delegates
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// return boolean value for a specific or all cells, you want to enable movement
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// Handle array element movement along with your row/cell
}

How to use estimatedHeightForRowAtIndexPath with async func? swift

I'm moving and app I had on Parse to Firebase and I ran into an issue with a cell that needs to get resized.It contains a textview that recieves data, since the text varies in size, I am using this two methods:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
With Parse this worked perfectly because I would recieve the entire object that I had to pass to the DetailTableView in the MainTableView. With Firebase, I handle it differently, I retrieve what the MainTableView needs, then I just pass a reference to the DetailTableView and again retrieve whatever I need there. The problem seems to be that the size of the cell gets set before the async function can set the text. Any ideas on how to solve this?
Thanks in advance!
I think you can wrap the code setting the text on the cell with calls to tableView.beginUpdates()
tableView.endUpdates()

Changing index of a cell

I'm starting to work with UITableViews and can't seem to find out how to change the position of a cell with code. Changing the position in the storyboard is straightforward enough but I need to be able to do it in swift.
TLDR;
Update your data. i.e. swap(&arr[2], &arr[3]).
Call the tableView's reloadData() method to reflect the changes to your data.
Long answer
An instance of UITableView works by checking its data source (UITableViewDataSource) for the information it needs. This includes the number of sections and rows, as well as the instance of UITableViewCell that the table view is to use. These are defined by the following UITableViewDataSource delegate methods:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int;
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int;
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell;
Usually, you would base the former two on some data you have, likely an Array or similar container. For example, if your tableView displayed data from an Array named fruitArray (which contained names of different fruit - a list of strings), then you might have something like the following:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Our array is one dimensional, so only need one section.
// If you have an array of arrays for example, you could set this using the number of elements of your child arrays
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Number of fruits in our array
return fruitArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("yourCellId") // Set this in Interface Builder
cell.textLabel?.text = fruitArray[indexPath.row]
return cell
}
Then, you can see that the answer to your question becomes simple! Since the contents of a given cell are based upon fruitArray, all you need to do is update your array. But how do you get the tableView to "recheck" its dataSource? Well, you use the reloadData method, like so:
swap(&fruitArray[2], &fruitArray[3])
tableView.reloadData()
This then triggers the tableView to "recheck" its dataSource, hence causing your data swap to appear on the screen!
If you'd like the user to be able to swap the positions of the cells, you can use the following UITableViewDelegate (not UITableViewDataSource) delegate method:
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
Have a look at this article for more info. You can also view Apple's documentation on UITableView, UITableViewDataSource, and UITableViewDelegate for further detail.
Hope this helps!

Prevent moveRowAtIndexPath beyond fixed index

I have a UITableViewController displaying dynamic table data with an additional row at the end (using a separate cell prototype) containing an 'Add' button.
I'd like for users to be able to re-order the table rows but prevent them from moving a row to a point after the last row.
I've implemented:
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return indexPath.row != elements.count
}
To prevent users moving the 'Add' table row
and am also testing for
if(toIndexPath.row < library.regularTasks.count)
inside
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath)
which prevents the rows being swapped in the model.
However I can't see a way to prevent the rows being dragged beyond the last row in the UI
Found it!
I used:
override func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
// Test whether destination is allowed
if(proposedDestinationIndexPath.row < elements.count){
return proposedDestinationIndexPath // if allowed move to proposed destination
}else{
return sourceIndexPath // if not, send back to where it came from!
}
}

Resources