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
}
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
}
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
Calayer - Cabasicanimation Not Scaling Around Center/Anchorpoint
Opens Apple Maps App from iOS App with Directions
Swift 3: How to Add Watermark on Video? Avvideocompositioncoreanimationtool iOS 10 Issue
Detect Which App Is Currently Running on iOS Using Sysctl
Cllocationmanager Responsiveness
iOS Uicollectionview - Default Flow, Fill Rows from Right to Left
Swift - Must Call a Designated Initializer of the Superclass Skspritenode Error
Sqlite Database on Phonegap/iOS - More Than 5Mb Possible
Container View Getting Pushed Down as If It Had a Uinavigationbar
Invalid Redeclaration in Auto Code Generate Nsmanagedobject Subclass Swift 3
Change App Language in iOS Without Restarting the App
Always Stop in App Delegate After Enabling All Exceptions Break Point
React-Native iOS Not Showing Images (Pods Issue)
How to Prevent Initial White Flash When Showing a Uiwebview
Xcode 4.3:Missing Icons for iOS Apps in Organizer's Archives
iPhone - Didselectrowatindexpath: Only Being Called After Long Press on Custom Cell
How to Set Accessibility Identifier in Interface Builder? Xcode4.2