Uitableview Move to Cell

UITableView move to cell

You are right to identify the scrollToRowAtIndexPath method. So all you need to do is create a fresh IndexPath with the row you wish to move to, e.g., row index = 10:

[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:10 inSection:indexPath.section] 
atScrollPosition:UITableViewScrollPositionMiddle animated:NO];

iOS UITableView move Cells in Code

This code works, but it only example. adapt it for you. create new file and put this code in it, build it and check.

class ViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!

var scores = ["1", "2", "3", "4", "5"]

override func viewDidLoad() {
super.viewDidLoad()
}

func move(from: IndexPath, to: IndexPath) {
UIView.animate(withDuration: 1, animations: {
self.tableView.moveRow(at: from, to: to)
}) { (true) in
// write here code to remove score from array at position "at" and insert at position "to" and after reloadData()
}
}

@IBAction func buttonPressed(_ sender: UIButton) {
let fromIndexPath = IndexPath(row: 4, section: 0)
let toIndexPath = IndexPath(row: 1, section: 0)
move(from: fromIndexPath, to: toIndexPath)
}
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return scores.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? TableViewCell
if let cell = cell {
cell.setText(text: scores[indexPath.row])
}
return cell ?? UITableViewCell()
}

func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}

}

For correctly use, you need to insert new element in array at last, reload data and after you can call method move() and put in it current indexPath and indexPath to insert you need.

Move UITableViewCell

You need to utilise UITableView re-ordering capacity. The cells can be re-ordered across sections.
To enable re-ordering mode:

[self.tableView setEditing:TRUE animated:TRUE];

This enables the TableView in editing mode which includes enables deletion mode along with re-ordering. If you do not want the deletion mode implement:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;

}

The re-order support accessory view is shown if you have implemented moveRowAtIndexPath like, for your case:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{

// Logic to change data source
NSMutableArray *deleteFrom = [self getDataSourceArrayFromIndexPath:sourceIndexPath];
NSMutableArray *addTo = [self getDataSourceArrayFromIndexPath:destinationIndexPath];
[addTo insertObject:[deleteFrom objectAtIndex:sourceIndexPath.row] atIndex:destinationIndexPath.row];
[deleteFrom removeObjectAtIndex:sourceIndexPath.row];

}

where getDataSourceArrayFromIndexPath is:

-(NSMutableArray*) getDataSourceArrayFromIndexPath:(NSIndexPath*) index
{
switch (index.section) {
case 0:
return self.firstSection;
break;
case 1:
return self.secondSection;
break;
case 2:
return self.thirdSection;
break;
default:
break;
}
return nil;
}

How to prevent a UITableViewCell from moving (Swift 5)

To answer the first question, if you look at the tableView(_:canMoveRowAt:) documentation :

This method allows the data source to specify that the reordering
control for the specified row not be shown. By default, the reordering
control is shown if the data source implements the
tableView(_:moveRowAt:to:) method.

This mainly talks about the reordering control being shown rather than specifically saying it can never be moved. So if you look at your UI, the reordering control is not showing for indexPath.row == 0

I can suggest 2 alternatives:

1. Reverse the move action

override func tableView(_ tableView: UITableView,
moveRowAt sourceIndexPath: IndexPath,
to destinationIndexPath: IndexPath)
{
// Reverse the action for the first row
if destinationIndexPath.row == 0
{
// You need the give a slight delay as the table view
// is still completing the first move animation
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
{
tableView.beginUpdates()
tableView.moveRow(at: destinationIndexPath,
to: sourceIndexPath)
tableView.endUpdates()
}

return
}

// update the data source
}

UITableView reorder move UITableViewCell table view cell swift iOS

2. User a header view

This way you don't have to worry about specify any logic of which cells can move and which cannot as you can have the non movable data in a header view:

override func tableView(_ tableView: UITableView,
viewForHeaderInSection section: Int) -> UIView?
{
if section == 0
{
// Customize any view
let headerView = UIView(frame: CGRect(x: 0,
y: 0,
width: tableView.bounds.width,
height: 100))
headerView.backgroundColor = .red

let label = UILabel(frame: headerView.bounds)
label.text = "Header view"
label.textColor = .white
label.textAlignment = .center
headerView.addSubview(label)

return headerView
}

return nil
}

override func tableView(_ tableView: UITableView,
heightForHeaderInSection section: Int) -> CGFloat
{
if section == 0
{
// specify any height
return 100
}

return 0
}

UITableView custom header UIView swift iOS

I recommend the second option as it has the better user experience and seems to be the right way of approaching this problem.

To answer your second question, in your cellForRowAt indexPath or custom cell implementation, you probably set the background view of the cell or the contentView to black.

Try setting one of these or both:

cell.backgroundColor = .clear
cell.contentView.backgroundColor = .clear

This should not give you a black background

Moving cells to new sections in a tableview

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

// Only move cell from the 1st section
if indexPath.section == 0 {

// Append the selected element to the second array
goals[1].append(goals[0][indexPath.row])

// Remove the selected element from the first array
goals[0].remove(at: indexPath.row)

tableView.reloadData()
}
}

I want to move selected tabelview cell on top

You are moving the row and the item to the bottom not to the top. You just need to edit your code a bit. The first row of a table's section is row zero. The append method adds the item to the end of the array, you need to insert it at the front of the array instead.

 let itemToMove = arrInrestLocation[indexPath.row]
arrInrestLocation.remove(at: indexPath.row)
arrInrestLocation.insert(itemToMove, at: 0) //move to front of array
let destinationindexPath = NSIndexPath(row: 0, section: indexPath.section)
tableView.moveRow(at: indexPath, to: destinationindexPath as IndexPath)

When moving cells in UITableView, how do I make a cell remain stationary?

Do the normal rearrange logic on your model, then when it's done, put the nulls back in where you want them. Posted code doesn't include the model, so here's a plausible model to illustrate:

// always leave our array with a null at indexes 3,5,7
// i'm sure you have better logic about where nulls go, but just to illustrate
- (void)addNulls {

NSMutableArray *answer = [NSMutableArray array];
for (id object in self.peopleList) {
if (![object isKindOfClass:[NSNull self]]) {
[answer addObject:object];
}
}

assert(answer.count >= 4);
[answer insertObject:[NSNull null] atIndex:3];
[answer insertObject:[NSNull null] atIndex:5];
[answer insertObject:[NSNull null] atIndex:7];
self.peopleList = answer;
}

// build a pretend model with nulls
- (NSMutableArray *)peopleList {

if (!_peopleList) {
_peopleList = [NSMutableArray array];
[_peopleList addObject:@"Moe"];
[_peopleList addObject:@"Larry"];
[_peopleList addObject:@"Curly"];
[_peopleList addObject:[NSNull null]];
[_peopleList addObject:@"Groucho"];
[_peopleList addObject:[NSNull null]];
[_peopleList addObject:@"Chico"];
[_peopleList addObject:[NSNull null]];
[_peopleList addObject:@"Harpo"];
}
return _peopleList;
}

// normal rearrange logic, then fix your array up
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {

// reorder the list with the typical logic, ignoring nulls
NSString *stringToMove = [self.peopleList objectAtIndex:fromIndexPath.row];
[self.peopleList removeObjectAtIndex:fromIndexPath.row];
[self.peopleList insertObject:stringToMove atIndex:toIndexPath.row];

// now put nulls into the positions you want them
[self addNulls];
[self.tableView reloadData];
}

Animate UITableViewCell moving to bottom programatically

If you call tableView.reloadData() your will lose you animation effect. You should just be able to move the cell, then update your data source (the goals array) to reflect the new order of the items. You also do not need to call tableView.beginUpdates() and tableView.endUpdates() for a single update. You would use those calls to batch multiple updates (inserts, deletes, moves, etc.)

//inside the function for when the button is pressed
let cell = sender.superview?.superview?.superview as! MainTableViewCell
let indexPath = tableView.indexPathForCell(cell)
let goal = goals[(indexPath?.row)!]

tableView.moveRowAtIndexPath(indexPath!, toIndexPath: indexPaths.last!)
goals.removeAtIndex((indexPath?.row)!)
goals.append(goal)

I created a simple test project to verify, using simple strings as the data items, and the animation effect worked as expected. See gist here: MoveTableRow



Related Topics



Leave a reply



Submit