objective c: exchange cell across sections - objective-c

I have a tableview contain many sections, in each of section, there is one cell, what I want to do is, when enter the editing mode, I will drag and drop one cell to another section, and I wish when drag is finished, the origin cell in target section will auto exchange to the section which the cell moved out.
Here's the code I did test, but didn't work
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
NSInteger destRow=destinationIndexPath.row;
NSInteger srcRow=0;
NSIndexPath *srcIndexPath=[NSIndexPath indexPathForRow:srcRow inSection:destinationIndexPath.section];
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:srcIndexPath];
[cell.textLabel setText:#"aaa"];// test if I got right cell, the result is ok.
NSIndexPath *trgIndexPath=[NSIndexPath indexPathForRow:0 inSection:sourceIndexPath.section];
[self.tableView moveRowAtIndexPath:srcIndexPath toIndexPath:trgIndexPath];
}
Kindly help me to check if there is any solutions, thanks!

Related

Objective-C linking two Tableviews

What I want is when you click on any cell in the table you go to another table view. I also need for each different cell you click on the view you get taken to has different strings. However I don't know
1) how to link a table cell to another tableview in the ViewController when you press it
2) how do you change the detail Tableview (including text and audio files) in View controller for each different cell you click on.
For detecting any row click in tableview use delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(#"index path cell row number =======%ld",(long)indexPath.row);//you can get the index number of that cell
NSLog(#"data of clicked cell====%#",[yourArray objectAtIndex:indexPath.row]);//here you can get the data of that cell
}

UITableView Center Cell Details

I am trying to sync a UITableView with a UILabel to make sure they show the same data; of course, things will be different in the end, but for testing this is what I need to do.
See the arrow? I want that middle cell (from px44-88) to show the cell.textLabel.text in a UILabel when it is the "middle cell".
I tried using - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath but I was having so many problems I figured I'd come here to ask if anyone has a better way of doing this. I'm not sure if it would make a difference or not but I am using NSFetchedResultsController to populate my UITableView.
UITableView is a subclass of UIScrollView, so probably you can use UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
member to detect which cell is currently in the middle.
I.e. assuming you have a plain table with no sections, and tableView is an outlet for the table, label is an outlet for the label, than this will function in your controller will work:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
int row = (scrollView.contentOffset.y + tableView.frame.size.height / 2) / 44;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
label.text = cell.textLabel.text;
}
Of course, you need to do some scrolling to make it work ;)
You can use visibleCells method to get layout of visible cells for non-plain table and use it to detect cell in the middle of the table.

UITableViewCell unselectable while its accessoryView is selectable

I want to have a UITableViewCell that is not selectable while its accessory view (a UISwitch in my case) is editable.
The issue is that I have two other cells of which one needs to remain active; this is very similar to the following image of the Time/Date selector from the iOS calendar app:
http://www.theiphoneblog.com/images/stories/2009/01/photo.jpg
I cannot post the image due to being a new user.
Note that in this view the "All-day" cell cannot be selected but its UISwitch can be changed, while one of "Starts" and "Ends" cells must remain selected.
I've tried both:
[cell setUserInteractionEnabled:NO];
[cell.contentView setUserInteractionEnabled:NO];
The first one works but does not allow the switch to be changed whereas the second does not work, it allows one of the top cells to be deselected which I do not want to happen.
Implement in delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([selectablePaths contains:indexPath])
{
// cell selected
selectedPath = indexPath;
}else
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
[tableView selectRowAtIndexPath:selectedPath animated:YES scrollPosition:UITableViewScrollPositionNone];
}
}
And enable user interaction for all cells.

More control over updating UITableView and UITableViewCell

I am trying to implement expanding UITableViewCells where I have complete control over the animation of the transition from collapsed to expanded and back.
I have an array, cellDataList, that holds the state of my UITableViewCells, i.e. height, color, data, isExpanded etc.
I implement:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath == selectedIndex)
return expandedHeight;
return collapsedHeight;
}
and I implement:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
some logic that tests if the indexPath is already selected,
which will collapse the cell, if a previous cell needs to be collapsed before the
new expands etc.
*/
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
}
My cell is a custom UITableViewCell where I build my content in drawRect:
The cell has a UIView (background) that serves as a custom background for the cell, this view I would like to
animate from collapsed to expanded and back, not just setFrame in one 'jump', as it does now.
I can't really figure out where to 'intercept' the tableView updater chain, to achieve this.
When I do the [tableView beginUpdates] - [tableView endUpdates] above, it starts to get a bit obscure what happens.
I assume
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
is called to update the cells
at the indexes specified. This in turn will ask heightForCellAtIndexPath which height to set the cell. If I set a breakpoint in my custom cells setFrame: method
I can see the caller is
[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] ().
This sets the new frame for the cell, then I assume [cell setNeedsDisplay] is called somehow so the cell can render for the frame provided.
The [cell setNeedsDisplay] will eventually call my custom drawRect: and render the content of the cell. This works as expected, but I can't figure
out where and how I will animate the frame for my background, also in a way so it is only done when clicked and not every time setFrame: is called (during scrolling etc).
When I do the above the tableView animates to make room for the new cell size, it is
this animation I would like to 'mimic' with the background view on my cell.
I see this effect in apps like Tweetbot and path but I can't seem to replicate it.
Hope some one can help me in the right direction, thanks:)
I am not totally sure that i understood your question exactly:) But you can use Key Value Observer (KVO) to check when you need to play your animation then call your table reload method.
- (void)reloadTable
{
if (self.isViewLoaded) {
[self.tableView reloadData];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[self reloadTable];
}
The best way to do this is to add a dummy cell below the cell that was tapped. I explain this thorougly here.
Basically:
Keep track of what cells are been tapped in your didSelectRowAtIndexPath and update it appropriately. Which one needs to be deleted? Where will the new dummy cell be next?
Return the correct account whenever the dummy cell is present.
Account for the fact that the dummy cell is not part of your model. Offset the indexPath.

Add editing elements to UITableViewCell

I have a couple of rows in a table view which I like to edit.
I thought that setEditing method would give me a Edit and Delete button, but it only shows a Delete button. Because I don't have a detail view controller that's going to be pushed in didSelectRowAtIndexPath I thought I could show a couple of editing elements in the selected cell.
I need to add three buttons to specify priority on assignments: Low, High and Medium priority. This means that I have to change the height of the selected cell to make room for these buttons, I think that's rather easy to do.
What I'm wondering is if this is the correct path to choose?
I have done quite a lot research today without finding examples of how other have solved editing in a UITableViewCell. If you edit a contact in the Contacts app in the iPhone the UITableViewCells changes to enable quick and easy editing, that's what I'm looking for.
So what do you have for tips for me regarding this question?
Edit #1
My code in didSelectRowAtIndexPath is:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Cell *selectedCell = (Cell *)[tableView cellForRowAtIndexPath: indexPath];
UIButton *btn = [UIButton buttonWithType: UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0, 0, 50, 100);
btn.titleLabel.text = #"Set this item to High Priority";
btn.backgroundColor = [UIColor greenColor];
[selectedCell.contentView addSubview: btn];
self.editing = YES;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject: indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
Code for heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
Cell *cell = nil;
if (self.editing)
cell = (Cell *)[tableView cellForRowAtIndexPath: indexPath];
else
cell = nil;
BOOL expandCell = NO;
NSInteger expandationHeight = 0;
if (cell != nil)
{
for (UIButton *btn in cell.contentView.subviews)
{
NSLog(#"A button was found.");
expandationHeight = 70;
expandCell = YES;
}
}
return expandationHeight + heightOfOtherElements;
}
When I click at a cell nothing happends but everything becomes disabled, I can't click any elements on the hole view. This has something to do with [tableView cellForRowAtIndexPath: indexPath], because if I uncomment that line the UI does not become disabled.
What am I doing wrong?
That's not too complicated though it requires some stuff.
You want to change the content of one cell or of all cells?
To specify a specific height for one cell, use the - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath delegate method.
It is called for each cell each time the table view is displayed. If you want to change a single row, call reloadRowsAtIndexPaths:withRowAnimation: method from UITableView. If you want to update all cells, simply use - (void)reloadData method.
You can also access a specific cell using - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath method from UITableView. Then you can reconfigure it to add various elements on it, as you want.
Thus, when a cell is selected, check whether you have to edit it or not, then :
update your cell get from cellForRowAtIndexPath
be sure your method tableView:heightForRowAtIndexPath: will return the good height
tell the table view to update the view using reloadRowsAtIndexPaths:withRowAnimation: