I have a custom uitableviewcell that i would like to indent when I turn on this:
[self.boatsDisplay setEditing:YES animated:YES];
Could anyone provide me a hint or some guidance?
Thanks
You'll need to subclass UITableViewCell and override -layoutSubviews. When the cell's editing bit is set to YES, -layoutSubviews will automatically be invoked. Any changes made within -layoutSubviews are automatically animated.
Consider this example
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat xPosition = 20.0f; // Default text position
if (self.editing)
xPosition = 40.0f;
CGRect textLabelFrame = self.textLabel.frame;
textLabelFrame.origin.x = xPosition;
self.textLabel.frame = textLabelFrame;
}
In your UITableViewDelegate you can use the tableView:indentationLevelForRowAtIndexPath: method:
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
if(tableView.editing == YES){
return 1; // or higher integer
} else {
return 0;
}
}
if you want to check for your custom cell only you can add &&[[tableView cellForRowAtIndexPath:indexPath] isKindOfClass:yourTableViewCell] in the if condition.
Related
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 50;
}
In this place, i would like to add a button dynamically to increase the height of the cell, so when user clicks upon that button it should be increase the height of cell and then click again to resize the height.
I want to something like :
-(void)IncreaseCell
{
UIButton *DownArrow = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[DownArrow addTarget:self
action:#selector(IncreaseCell:)
forControlEvents:UIControlEventTouchDown];
//[DownArrow setTitle:#"Arrow" forState:UIControlStateNormal];
DownArrow.frame = CGRectMake(121.0, 112.0, 72.0, 37.0);
[cell.contentView addSubview:DownArrow];
UIImage *buttonDown = [UIImage imageNamed:#"friendsDownArrowButton.png"];
[DownArrow setBackgroundImage:buttonDown forState:UIControlStateNormal];
[cell.contentView addSubview:DownArrow];
}
You will need to create a NSMutableArray as an instance variable, in which you keep track of all the cells, that you want to have "increased".
#interface YourTableViewController : UITableViewController {
NSMutableDictionary *increasedRows;
}
Remember to alloc/init that variable.
To get your cell increased:
-(void)increseCell: (BOOL)status forIndexPath: (NSIndexPath*)indexPath {
[increasedRows setObject:[NSNumber numberWithBool:status] forKey: indexPath];
[self.tableView beginUpdates]; //Delete if you don't want it animated
[self.tableView endUpdates]; //Delete if you don't want it animated
// [self.tableView reloadData]; //Uncomment if you don't want it animated
}
You change your tableView: heightForRowAtIndexPath: declaration to check this dictionary for your indexPath.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Check if cell is increased, return custom height
if([[increasedRows objectForKey:indexPath] boolValue]) {
return 150;
}
// Cell isn't increased so return regular height
return 50;
}
This method will allow you to do it for every row individually and allows you to animate it.
You need to change your implementation of heightForRowAtIndexPath.
Add some storage, like an array, which holds flags indicating if a row is expanded or not. When a button is tapped, get the index path of the cell that it is on and edit the array contents to set / unset the flag. Reload the table view (or the row for the changed index path).
All you have to do is declare a variable:
#interface yourViewController ()
{
CGFloat cellSize;
}
And in your heightForRowAtIndexPath::
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return cellSize;
}
in your viewDidLoad
-(void)viewDidLoad
{
[super viewDidLoad];
cellSize = 50;
}
and last in your increaseCell:
-(void)IncreseCell {
cellSize += 10;
[self reloadData];
}
what i did in one of my project is i created a custom cell and add subview to it statically
1 st scene non collapsed view
custom cell shows only button on click of which it will show extended view by increasing size of cell..
i.e on click of button you should increse size of cell using function..
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
BOOL check=[[booleanArrayofrows objectAtIndex:indexPath.row] boolValue];
if (check)
{
return 180; ..expanded view height
}
return 40; collapse view height
}
}
i have a table view which has header for the tableview and another header for section.
the header for section has a button on top of it, when the button is pressed i need to change the size of this header.
i did changed the header size but the content within it does not change accordingly.
i even fixed it using this-
_isHeaderExtended = !_isHeaderExtended;
[self.testTable beginUpdates];
CGPoint point = testTable.contentOffset;
point.y = (_isHeaderExtended)? point.y - 1: point.y + 1;
[testTable setContentOffset:point animated:NO];
[self.testTable endUpdates];
my entire code is below
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 30;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return testView;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
[self.testTable beginUpdates];
CGFloat fl = (_isHeaderExtended)?200:100;
[self.testTable endUpdates];
return fl;
}
-(IBAction)buttonPushed:(id)sender {
_isHeaderExtended = !_isHeaderExtended;
[self.testTable beginUpdates];
CGPoint point = testTable.contentOffset;
point.y = (_isHeaderExtended)? point.y - 1: point.y + 1;
[testTable setContentOffset:point animated:NO];
[self.testTable endUpdates];
}
basically i need the content of the header to stretch according to the resize i use,
any ideas ???
I think it should be changed into:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if( _isHeaderExtended ){
return bigTestView;
} else {
return smallTestView;
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return _isHeaderExtended?200:100;
}
-(IBAction)buttonPushed:(id)sender {
_isHeaderExtended = !_isHeaderExtended;
[self.testTable reloadData];
}
Then you need to create a bigTestView and a smallTestView for the header.
Do this:
Eliminate the calls to beginUpdate and endUpdate in heightForHeaderInSection. They have no business in the datasource protocol.
Make sure the view you return in the header view is initialized and configured as intended. Presumably you do this in viewDidLoad.
In order to let the content of the header stretch, you can set this view's autoresizingMask to the desired value. Alternatively, you can use IB to configure the views to resize with the container view. You will have to return a properly sized view in viewForHeaderInSection.
A recommended design pattern would be quite different: put all the logic of the size into your datasource methods (heightForHeaderInSection and viewForHeaderInSection), i.e. you could check your _isHeaderExpanded variable. Then, in the toggle method, just reload the section.
I'm developing an iPhone app and I have one problem. I have a UITableView with a few editable rows(
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ )
and one not editable row. If I click edit, the editable rows slide a bit to the right and there is a red round button at the left of it, but the not editable row doesn't slide at all. Is there a way to also slide it to the right but without the red button at the left? It doesn't look that nice at the moment. I hope someone can help me with this:)
I am not sure if it's a good idea to change the default behavior of the tableView.
But if you really want to, you could e.g. use indentation.
// Might be target of button
- (void) setEditingMode
{
tableView.editing = YES;
[tableView reloadData];
}
// Might be target of button
- (void) resetEditingMode
{
tableView.editing = NO;
[tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = ...;
....
Boolean cellIsEditable = ...;
if( tableView.editing && !cellIsEditable )
{
cell.indentationWidth = ...; // (please experiment to find the exact value)
cell.indentationLevel = 1;
}
else
{
cell.indentationLevel = 0;
}
}
Subclass the UITableViewCell and slide the uneditable row yourself.
#interface MyHistoryTableViewCell : UITableViewCell
#end
#implementation MyHistoryTableViewCell : UITableViewCell
#define CELL_SLIDE_WIDTH 32 // found empirically
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if ( self.editingStyle == UITableViewCellEditingStyleNone ) { // not editable
CGRect frame = self.frame;
UITableView *tableView = ((UITableView *)(self.superview));
if ( tableView.editing ) { // going to editing mode
frame.origin.x = CELL_SLIDE_WIDTH;
frame.size.width = tableView.frame.size.width - CELL_SLIDE_WIDTH;
} else { // ending editing
frame.origin.x = 0;
frame.size.width = tableView.frame.size.width;
}
[UIView animateWithDuration:0.3 animations:^{ // match the tableView slide duration
self.frame = frame;
}];
}
}
#end
If you have subviews that need to be anchored to the right of the cell (e.g., a button that should not slide), then do
mySubview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; // anchors to the right margin
Also, you have to be creative when setting the subview's frame.origin.x. I experimented with many values until I found something that worked (the value made no sense to me).
In my UITableView, when it enters editing mode, I'd like only a select few cells to be selectable. I know the UITableView class has the property allowsSelectionDuringEditing, but this applies to the whole UITableView. I don't see any relevant delegate methods to set this on a per-cell basis.
The best solution I can come up with is to set allowsSelectionDuringEditing to YES. Then, in didSelectRowAtIndexPath, filter out any unwanted selections if the table view is editing. Also, in cellForRowAtIndexPath, change those cells selectionStyle to None.
The problem with this is that going into editing mode does not reload the UITableViewCells, so their selectionStyle doesn't change until they scroll offscreen. So, in setEditing, I also have to iterate over the visible cells and set their selectionStyle.
This works, but I just wonder if there is a better/more elegant solution to this problem. The basic outline of my code is attached. Any suggestions greatly appreciated! Thank you.
- (void) tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
if (self.editing && ![self _isUtilityRow:indexPath]) return;
// Otherwise, do the normal thing...
}
- (UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
// UITableViewCell* cell = ...
if (self.editing && ![self _isUtilityRow:indexPath])
{
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
else
{
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}
return cell;
}
- (void) setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (editing)
{
for (UITableViewCell* cell in [self.tableView visibleCells])
{
if (![self _isUtilityRow:[self.tableView indexPathForCell:cell]])
{
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
}
}
else
{
for (UITableViewCell* cell in [self.tableView visibleCells])
{
if (![self _isUtilityRow:[self.tableView indexPathForCell:cell]])
{
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}
}
}
}
I'm not sure how your app works, but perhaps you could try make use of the following somewhere in your DataSource definition:
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
when going into editing mode, use the function to filter the first selection level, then on to your second selection level
i am very much new to iphone development ,I wanted to reduce the size of a section in the grouped table view i.e reducing the width of the section . how can it be implemented
thanks in advance
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return kHeightForHeaderInSection;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
// wrapperView - by default has the width of the table, you can change the height
// with the heightForHeaderInSection method
UIView *aView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
// your real section view: a label, a uiview, whatever
CGRect myFrame; // create your own frame
myFrame.origin = CGPointMake(10, 0);
myFrame.size = CGSizeMake(tableView.bounds.size.width-10,kHeightForHeaderInSection);
UILabel *label = [[[UILabel alloc] initWithFrame:myFrame] autorelease];
label.text = #"myText"
[aView addSubview:label];
return aView;
}
Hi add this UITableviewdelegate method
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return height;
}
its a very simple soln ...
#interface MyController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableview *myTableview;
just right click on "UITableViewDelegate" and "UITableViewDataSource"
n implement all the delegates....u will find all types of adjustment over there....weather u want to change or adjust height or width of section or row ...or how many section or how many rows in a section do u want....
its simple n called automatically.... regards