A UITableView which have UITableViewCell of 20 rows, each row do have one button on it, click button I want to drop the UITableViewCell to bottom to UITableView.
Is there any delegate method which do for it.
Your feedback will be appreciated.
Yes, there is a method on tableview
- (void)moveRowAtIndexPath:(NSIndexPath*)indexPath
toIndexPath:(NSIndexPath*)newIndexPath
You can read more https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/occ/instm/UITableView/moveRowAtIndexPath:toIndexPath:
Yes, there is one!
Use below delegate methods for that:
have to return YES to allow moving of tableView row in canMoveRowAtIndexPath delegate method as per your requirement,
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) // Don't move the first row
return NO;
return YES;
}
Then, use moveRowAtIndexPath delegate method to Updating the data-model array for the relocated row accordingly,
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath
{
//Updating the data-model array
}
Like moveRowAtIndexPath in button click,
- (void)btnClick:(UIButton*)sender
{
UITableViewCell *cell = (UITableViewCell *)sender.superview;
NSIndexPath *indexpath = [tableView indexPathForCell:cell];
//Change accordindly as per requirement
[tableView moveRowAtIndexPath:[NSIndexPath indexPathForItem:indexpath.row inSection:indexpath.section] toIndexPath:[NSIndexPath indexPathForItem:0 inSection:indexpath.section]];
}
Also, read Apple documentation for same:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/ManageReorderRow/ManageReorderRow.html
Related
I took approach of the UITableview to get cell click ExpandView. I want something like this to be implement.
So, UITableView would be best approach for this or suggest me any good way of implementing, also I am not able to get subview to adjust according to screenSize.
Could be there are another ways to accomplish this but this is how I am expand UITableViewCell on the fly. This could give the idea and you can implement your solution.
I keep row heights in my data model:
- (void)viewDidLoad {
[super viewDidLoad];
//Data source
datasource = [[NSMutableArray alloc] init];
NSMutableDictionary *aDicti = [[NSMutableDictionary alloc] init];
[aDicti setValue:#"a TEXT" forKey:#"text"];
[aDicti setValue:#(50) forKey:#"cellheight"]; // here
}
When selection changed, just updating related key in data source.
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[[datasource objectAtIndex:indexPath.row] setObject:#(50) forKey:#"cellheight"];
[tableView endUpdates];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
[[datasource objectAtIndex:indexPath.row] setObject:#(200) forKey:#"cellheight"];
[tableView endUpdates];
}
Once [tableView endUpdates]; executed heightForRowAtIndexPath and numberOfRowsInSection delegate methods fired and automatically adjust cell height with the value from data source.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [[[datasource objectAtIndex:indexPath.row] objectForKey:#"cellheight"] intValue];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return datasource.count;
}
If you do not want to keep row height in your data source you can basically apply this.
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[tableView endUpdates];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
[tableView endUpdates];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView.indexPathForSelectedRow.row == indexPath.row) {
return 100;
}
return 50;
}
That's call, accordion, this site having good examples (with demos) for it, here's the link.
Basically when you are working with TableView you should play with number of section headers and cells.
In case of using section headers you should set numberOfRowsInSection to 0 (roll up) to X when you want to expand it. After that call
tableView.reloadData
I implemented this behavior here, with animation, with different heights:
https://github.com/rudald/expandedTableViewIOSSwift/
There are numerous open source projects regarding this feature. I've downloaded a few projects and the most customizable and issue-less, for me, was SLExpandableTableView
SDNestedTable does exactly what you want.
The module concept is that of having all the default functionality of
a UITableView and its cells while at the same time adding for each
cell a child UITableView. Each cell (SDGroupCell) in the main
SDNestedTableViewController tableview acts as controller for its own
sub table. The state, population and behavior of the table and
subtable is instead mostly controlled by
SDNestedTableViewController.
If you’re looking for a straight forward easy-to-setup library for expandable views, HVTableView is your choice. It provides an acceptable performance which is sufficient for using in regular projects.
I have a TableView with three sections. Section one and two can be deleted, (delete with swipe)
section three can't. My problem now is that when I swipe on a cell in the third section, it gets selected. I tried deselecting it when "canEditRowAtIndexPath" is called(and it really gets called), but that doesn't work and the cell remains selected. My "canEditRowAtIndexPath" looks like this:
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.section == 2)
{
return NO;
}
return YES;
}
I found ( in my opnion ) a better solution to this matter
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Right)
I hope that helps!!
Regards
You may check and close the 3rd section cell selections in -(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath by using tableViewCell.selectionStyle = UITableViewCellSelectionStyleNone;
You should call [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; in this method -
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Or in -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Set selection style none. cell.selectionStyle = UITableViewCellSelectionStyleNone;
Use this delegate method of UITableView
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
I found a great workaround.
A swipe on the cell, forces the app to call viewWillAppear.
Add [self.tableView reloadData];into that method and the selected state will be removed.
I implemented the body of the method moveRowAtIndexPath:toIndexPath: as follows:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
XYZToDoItem *itemToMove = [self.toDoItems objectAtIndex:fromIndexPath.row];
NSLog(#"Moving");
NSLog( itemToMove.itemName);
[self.toDoItems removeObjectAtIndex:fromIndexPath.row];
[self.toDoItems insertObject:itemToMove atIndex:toIndexPath.row];
}
I'd like to call this method from TableViewController's didSelectRowAtIndexPath method.
When I do the rows of the table do move, but the above method doesn't seem to execute. Nothing logs to the console and the items in the array toDoItems DO NOT swap.
Here's the body of that method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *indexPathOfLastItem =
[NSIndexPath indexPathForRow:([self.toDoItems count] - 1) inSection:0];
[tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
}
How do I get the table view to move rows properly from within the delegate (the TableViewController)?
Moving (or adding, removing) table view rows by code (and not by user interaction) does not cause the
data source methods to be called.
If you need the data source method to be executed, you need to call it explicitly:
// Move table view row:
[tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
// Call data source method:
[self tableView:tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
Swift 3:
// Move table view row:
tableView.moveRow(at: indexPath, to: indexPathOfLastItem)
// Call data source method:
self.tableView.moveRow(at: indexPath, to: indexPathOfLastItem)
I don't think you're calling the method correctly, since it's not a real delegate method you have to call it on self.
Try:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *indexPathOfLastItem =
[NSIndexPath indexPathForRow:([self.toDoItems count] - 1) inSection:0];
[self tableView:tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
}
I want to open more information in small view of every cell selection , like exapnding able view cell.i am taaching screen shot also. I am not able to dot this plase help.How it can be done!
I am using below code , it is working fine but how to show hidden view on particular cell position
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Deselect cell
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
// Toggle 'selected' state
BOOL isSelected = ![self cellIsSelected:indexPath];
// Store cell 'selected' state keyed on indexPath
NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
[selectedIndexes setObject:selectedIndex forKey:indexPath];
// This is where magic happens...
[tbleLectures beginUpdates];
[tbleLectures endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
// If our cell is selected, return double height
if([self cellIsSelected:indexPath]) {
return kCellHeight * 2.0;
// return 44;
}
// Cell isn't selected so return single height
return kCellHeight;
}
You can reload your tableview to make it effective or reload just the cell in your tableView:didSelectRowAtIndexPath::
// This is where magic happens...
[tbleLectures beginUpdates];
[tbleLectures reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[tbleLectures endUpdates];
If you want to change the height of the cell then you should reload the table view and use
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
delegate method to show/hide detail view
another logic is to maintain the state of the tableView and populate cells based on the state of the tableView. The tableView should have isSelectedCell/notSelected state. if tableView is selected then number of returning cell always +1 (One for detail cell); and Insert the detail cell after selected cell. to maintain the index of selected cell you might need class variable.
For this kind of work in iOS you need to have some logic!
Hope this helps
I have a "UITableView", I am trying to handle selected row and use its data accordingly,
I have written necessary code to take the selected row, unfortunately it seems it does not work
If i select nothing,
NSIndexPath *path = [tableViewDoctorName indexPathForSelectedRow];
int rowSelected = path.row;
rowSelected's value is 0;
But, when i select the row it is again 0.
I have only one row in a table, i am not sure does it matter?
How can i accurately determine the selected row in a "UITableView"?
Set the UITableView delegate and implement this method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int rowSelected = indexPath.row;
}
indexPath.row start with 0 for first row, And you have only one row then it return always 0;
But if you want to get data of selected Row then you delegate method of UITableView.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// here you can get directly indexPath.row so you can get required data;
}
Of course how many rows you have in your tableView matters : if you only have 1, then its indexpath is (0 ,0) and this is the only one that can be (selected) in this case.
The selected row generally is highlighted (in blue) so you might want to store it in another property of your tableView delegate, if you don't want this blue selection to stay on-screen.
Typically, in your UITableViewDelegate :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// deselect the row, to avoid the 'blue' selection to stay on-screen
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// save your own copy of 'last' selected indexPath
self.mySavedIndexPath = indexPath;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selectedIndexPath = indexPath;
}
In outside the function,
use this to get selected row,
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: _selectedIndexPath.row inSection:0];
int rowSelected = indexPath.row;