My UITableView has 3 sections. Only the cells in the 2nd sections are movable:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
BOOL canMove = NO;
if (indexPath.section == 1) {
canMove = YES;
}
return canMove;
}
However, a cell (B) in the 2nd section (originally contains A``B``C cells) can be moved to the 1st section (originally contains only the T cell):
How can I make sure cells are moved within its own section?
I think this will solve your problem
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if( sourceIndexPath.section != proposedDestinationIndexPath.section )
return sourceIndexPath;
else
return proposedDestinationIndexPath;
}
From Apple documentation
This method allows customization of the target row for a particular
row as it is being moved up and down a table view. As the dragged row
hovers over a another row, the destination row slides downward to
visually make room for the relocation; this is the location identified
by proposedDestinationIndexPath.
Related
I have a UITableView which has master records in it's cell. When the user selects a cell, some detail record is displayed on the same table and this record would be set below that particular cell.
One more thing is the cells that are below the selected cell of the master table will be displayed below the detail view.
In short I want to design a popup that will display the details of selected cell below that particular cell and rest of the cells(cells below the selected cell) of master will be moved down, so that the detail popup can be accomodated between the selected cell and the cells below it.
//Take int selectedCellIndex in your .h file, initialize selectedIndex with -1
//Take BOOL isSelected in your .h file
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedCellIndex = indexPath.row;
isSelected = YES;
[yourTable reloadData];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==selectedCellIndex)
{
return 100;
}
return 50; //Your default cell size
}
- (UITableViewCell *)tableView:(UITableView *)tV cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//after creating your cell
if(isSelected && selectedIndex>-1)
{
//Show your custom View , something like [cell.contentView addSubView:customView];
isSelected = NO; //Reset
selectedIndex = -1; //Reset
}
}
You can simply use this
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method . In here, You can allocate a new UIView every time the user clicks on the cell and display your information in it.
If you have any queries please feel free to reply . :)
Check these projects out, maybe they will of some help ...
Combo Box
I have a static table view in my application. This table view is used for preferences.
A section in the table view only has one cell which holds a UISwitch. When this switch is activated, I want to show the section beneath and when it is not, I want to hide the section beneath. All the sections (also the one which should be hidden / shown) is set up using Interface Builder.
Is there any way to hide or show this section when the table view is static as a static table view doesn't have a data source? Should it be easier, I could also agree to use the same section but add / hide rows from this section when the switch is on or off.
EDIT
I have come closer how to do this.
Setting the height of the cells in the section and the height of the footer and header of the section to 0, I can nearly hide the section. I still have some spacing between the section above and the section below that I cannot figure out how to get rid of.
Does anyone have an idea where this extra spacing comes from? See the photo below.
This is the code I use to nearly hide the section.
/* Will display cell */
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 2)
cell.hidden = YES;
else
cell.hidden = NO;
}
/* Height of cell */
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 2)
return 0;
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
/* Height of section header */
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == 2)
return 0;
return [super tableView:tableView heightForHeaderInSection:section];
}
/* Height of section footer */
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (section == 2)
return 0;
return [super tableView:tableView heightForFooterInSection:section];
}
This is how the table view looks now. There is still some space I need to hide. The extra space is between the sections labeled "Arbejde" and "Anden".
I got it working using the code in the question. Just set the height to 1.0f instead of 0. It seems that the height only has an effect when it's value is greater than zero.
Reducing the space between sections of the UITableView.
For static cells, I just use this:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = self.tableView(self.tableView, cellForRowAt: indexPath)
if cell.isHidden {
return 0
} else {
return cell.bounds.size.height
}
}
see this tutorial this may helps you www.cocoanetics.com/2011/03/expandingcollapsing-tableview-sections/
For static cells I found no decent answers either. If you wish to drop sections or expand a cell then this is the code I used.
Create a BOOL Value in your .m
#interface yourClassName (){
BOOL ddMenuButtonPressed;
}
#end
ddMenu means drop down menu.
Next I set the bool value to false in the viewDidLoad method.
ddMenuButtonPressed = false;
I then initialise the ddButton (in storyboard control+drag from your button or switch to your .h file and create action and set name to ddMenuButton) and use this method in my .m file.
- (IBAction)ddMenuShow:(UIButton *)sender
{
if (sender.tag == 0) {
sender.tag = 1;
ddMenuButtonPressed = true;
} else {
sender.tag = 0;
ddMenuButtonPressed = false;
}
//very important that you include these
//they update the view like a viewDidLoad statement without leaving the screen
//if you have any data entry points in your cell like a textfield it **will not** erase that data fortunately
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
Finally we add the following method:
// Handle expanding and minimising cell or section
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//if the section is 0 (and there is only one cell) and ddMenuButtonPressed hasn't been pressed
if (indexPath.section == 0 && ddMenuButtonPressed == false){
//return the height you have it set as in story board (or a number)
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
//if the section is 0 and the ddMenuButton has been pressed
if (indexPath.section == 0 && ddMenuButtonPressed == true){
//change the cell height to 380 or whatever size you want
return 380;
}
//otherwise leave cells as they are
else {
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
And that's it. No fancy coding, nice and clean (minus the commenting) and simple and you can use this over and over for as many sections as you like.
How can I disable that the user can move cells to other sections? I don't want to show an alert each time ;)
Thanks :D
Implement the targetIndexPathForMoveFromRowAtIndexPath delegate method:
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (proposedDestinationIndexPath.section != sourceIndexPath.section)
{
//keep cell where it was...
return sourceIndexPath;
}
//ok to move cell to proposed path...
return proposedDestinationIndexPath;
}
I'm set editing mode for UITableView to have a possibility of cell reordering. UITableViewCellEditingStyleNone is returned by editingStyleForRowAtIndexPath: method for every cell, but it reserve some area on the left of cell. Is it possible to prevent such an area reserving, because I'm not need an insert or delete icon on left? In short, i want have a cell that occupate all available area and still can be reordered.
// UITableViewDelegate
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
See the docs: You can set a boolean on the cell to make it not indent. Just add
cell.shouldIndentWhileEditing = NO;
to wherever you create your cell.
Set this to like 2 or 3
tableView:indentationLevelForRowAtIndexPath:
The shouldIndentWhileEditing property only works with grouped tables. I found that setting an indentation level of -3 does the job for plain tables. Is there a better way? Here's what I'm using now:
if (self.tableView.style == UITableViewStylePlain) {
cell.indentationLevel = -3;
} else if (self.tableView.style == UITableViewStyleGrouped) {
cell.shouldIndentWhileEditing = FALSE;
}
Do both
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
and
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
in your UITableViewDelegate. Otherwise the cell content is indented.
I have an iPhone app that utilizes TableView to list tagged items that the user has saved. I have Swipe to Delete enabled for these items yet I'm running into an issue with the very first item in the table. All other items show the "Delete" button when swiped, but it does not work for the very first row.
I've searched and searched for an answer to this. I'd appreciate the help!
- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if([indexPath row] == 0) {
return UITableViewCellEditingStyleNone;
}
return UITableViewCellEditingStyleDelete;
}
You should return UITableViewCellEditingStyleDelete from tableView:editingStyleForRowAtIndexPath: for all rows that should support delete.
UPDATE
I have explained what your code does in some added comments, so you can see the problem:
- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if([indexPath row] == 0) {
// any row that returns UITableViewCellEditingStyleNone will NOT support delete (in your case, the first row is returning this)
return UITableViewCellEditingStyleNone;
}
// any row that returns UITableViewCellEditingStyleDelete will support delete (in your case, all but the first row is returning this)
return UITableViewCellEditingStyleDelete;
}