fscheidl
fscheidl

Reputation: 2301

Prevent indentation of UITableViewCell (contentView) while editing

Is it possible to keep the contentView.frame always the same, regardless of tableView.editing? I already tried to override layoutSubviews and willTransitionToState but those options fizzled out too. I can't seem to be able to change the width of the contentView. Or maybe my approach ist just plain impossible ... Maybe there is another way to solve this.

The behaviour I want to achieve is the following: I want the standard textLabel of a UITableViewCell to be always indented and not change position when the tableView enters editing mode. The problem I will probably face is that the behaviour of the detailTextLabel will have to be corrected (e.g. truncation of text if textLabelcontent is too long). The reason why I don't want to implement my own UILabelis because a custom subviews will decrease the scrolling performance by a significant amount.

I hope that anyone already implemented something like this in their UITableViewand could show me a solution to this tedious problem. Thanks in advance!

EDIT: I'm dealing with a UITableView in plain and not grouped style.

Upvotes: 35

Views: 20847

Answers (9)

AechoLiu
AechoLiu

Reputation: 18368

Based on Usman.3D

On the storyboard, a property indent While Editing is checked by default. It can be unchecked manually. It equals to cell.shouldIndentWhileEditing = NO.

enter image description here

Upvotes: 9

Pradeep Reddy Kypa
Pradeep Reddy Kypa

Reputation: 4022

You can always get a tableviewcell with an indexpath. Using that tableviewcell reuseidentifier, You can avoid the tableview cell content size to be resized or not. I had a requirement to implement the similar kind of functionality to avoid resizing of seperate cells. PFB the code.

-(BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath{

BOOL shouldIndentWhileEditingRow = NO;

UITableViewCell *lTableViewCell = [tableView cellForRowAtIndexPath:indexPath];

/*Change the position of the target rect based on Sending messages or Receiving messages*/
if ([lTableViewCell.reuseIdentifier isEqualToString:@"SendingChatCellIdentifier"]) {

    shouldIndentWhileEditingRow = NO;

}else if ([lTableViewCell.reuseIdentifier isEqualToString:@"ReceivingChatCellIdentifier"]){

    shouldIndentWhileEditingRow = YES;
}

return shouldIndentWhileEditingRow;
}

Upvotes: 0

Usman.3D
Usman.3D

Reputation: 1811

Use the UITableViewDelegate method:

- (BOOL)tableView:(UITableView *)tableView 
        shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath 
{

    return NO;
}

This will work for both grouped and non-grouped UITableView types. However, if you have a grouped tableview, you can use this property on the cell:

cell.shouldIndentWhileEditing = NO;

Upvotes: 105

Andy
Andy

Reputation: 61

Just came across this as I was researching the same problem.

A very easy solution is to set the indentation level to a negative number - it is a signed integer after all.

A [cell setIndentationLevel:-3] worked perfectly for me, given a default indentation width of 10, to move the label back to the left in a plain table.

Upvotes: 0

snoersnoer
snoersnoer

Reputation: 193

A little late,

but I solved the problem by switching off the Autoresizing Mask for all views in my TableViewCell:

[<viewInCell> setAutoresizingMask:UIViewAutoresizingNone];

Or switch off Autoresizing of width and/or height directly in Interface Builder.

Upvotes: 0

mvds
mvds

Reputation: 47034

Luckily, iOS is perfectly equipped to keep whatever value constant.

This (ugly) piece of code will keep the frame fixed to whatever value has origin.x==0. This is easily adapted to your particular needs.

// put this in your UITableViewCell subclass
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"observed value for kp %@ changed: %@",keyPath,change);
    if ( [keyPath isEqual:@"frame"] && object == self.contentView )
    {
        CGRect newFrame = self.contentView.frame;
        CGRect oldFrame = [[change objectForKey:NSKeyValueChangeOldKey] CGRectValue];
        NSLog(@"frame old: %@  new: %@",NSStringFromCGRect(oldFrame),NSStringFromCGRect(newFrame));

        if ( newFrame.origin.x != 0 ) self.contentView.frame = oldFrame;
    }
}

// add the cell as an observer for frame changes, somewhere in initialization:
[self.contentView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionOld context:nil];

// IMPORTANT: remove the cell as an observer in -dealloc:
[self.contentView removeObserver:self forKeyPath:@"frame"];

This will only allow the frame to change to values with an origin.x==0. Remove the NSLog() lines for Release builds.

I have tested this for a few minutes and haven't seen any side effect.

Upvotes: 10

Razmig Sarkissian
Razmig Sarkissian

Reputation: 21

I had the same trouble with my plain style table even with shouldIndentWhileEditingRowAtIndexPath returning NO

On my side, I encounter the issue because my first row should not be deleted and the rest of the table view cells should.

I added this second method and it worked:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {

    if (indexPath.row == 0 && indexPath.section == 0) return NO;

    return YES;    
}

Hope it helps

Upvotes: 2

Nick Weaver
Nick Weaver

Reputation: 47241

You will have to override layoutSubviews to do this. It applies for the level of custom indentation so it does for none.

Please have a look at How can I change the amount of indentation on my custom UITableViewCell while editing?. I provided an example how to change the level of indentation. Though it didn't work 100% for the OP it worked in my example app. I think this will point you in the right direction.

Upvotes: 2

Steven Kramer
Steven Kramer

Reputation: 8513

Have you looked at UITableViewCell's shouldIndentWhileEditing and indentationLevel properties? Those might sort it.

Upvotes: 0

Related Questions