The user will click a button in one of the cell and the table will reload the data.
I would like to let the user stay in the same position after the reload.
My table contain many section and each section has two row.
Each of them may have different height.
I have tried some of the methods provided by others but its doesn't work.
CGPoint offset = tableView.contentOffset;
[tableView reloadData];
[tableView setContentOffset:offset];
Is it related to my table that each row in each section has different heigt?
I have also check that the offset is correct after the table is reloaded.
But the appearance is wrong.
I found that the view of the table is not change after the setting the offset
Related
I have rotated my table view by 90°. Now I want to get indexpath of middle cell. When table view is not scrolling, it is showing 3 cells. What I want is, when table view stops scrolling, it should middle cell of green color. Sometimes I get wrong indexpath when more then 3 cells are visible while fast scrolling.
I have attached image for reference
try this
NSIndexPath *middleIndexPath = [tableView indexPathForRowAtPoint:CGPointMake(tableView.center.y, tableView.center.x)];
UITableViewCell *middleCell = [tableView cellForRowAtIndexPath:middleIndexPath];
You can get contentOffset of table view. With contentOffset, you can calculate current row (contentOffset.y / row height)
I have an iOS application where I am displaying a UITableView, which in turn is composed of custom rows that are made up of UITextFields, and UILabels. On first launch, I have a UIImageView that covers the UITableView until the user presses a button in order to dismiss the UIImageView (thus revealing the UITableView behind it).
However, my problem is that instead of returning control to the first row of the UITableView, it is selecting the last row of the UITableView, and on top of that, despite me making an explicit call to the method, "becomeFirstResponder", the UITextField in the last row of the UITableView does not allow me to enter text until I explicitly select a row from the table. Then and only then am I able to enter text. I am assuming that my method "cellForRowAtIndexPath" populates my table from the top down, which is why the last row of the table is being selected, and not the top (this is my guess, and if I am wrong please correct me).
What I would like to do is enable the very first row of the UITableView once the user dismisses the UIImageView AND have it become the "firstResponder" automatically, allowing the user to enter text right away without having to explicitly select a particular row.
My code that dismisses the UIImageView after pressing a button is here:
- (IBAction)beginDataEntry:(id)sender {
[_imageView removeFromSuperview];
[_cell.dataField becomeFirstResponder];
}
It is as if my UITableView is in a "limbo" state until I explicitly select a row from the table. What am I doing wrong?
Use UITableView scrollToRowAtIndexPath:atScrollPosition:animated: to display the correct row when the view is redisplayed.
It is always safer to use index paths to refer to table rows rather than keeping references to cells. So, here's an alternative:
- (IBAction)beginTireCountEntry:(id)sender {
[_imageView removeFromSuperview];
NSIndexPath firstCellPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView scrollToRowAtIndexPath: firstCellPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
MyCell cell = (MyCell *)[self.tableView cellForRowAtIndexPath:firstCellPath];
[cell.dataField becomeFirstResponder];
}
I have a UITableView of cells where one cell contains a UITableView. Selecting that row that contains the table pushes a new view onto the screen with a list of items. The user selects a list of items and then presses 'back' to pop that view. The parent view looks at the number of items selected and the height of the cell is supposed to adjust to show all items selected.
What happens is that when the view is reshown, the listed items extends into the cell below. If I scroll that cell off the screen, then back to it, the cell is then the right height showing all items correctly.
I've tried several things such as putting code into viewWillAppear of the main table like [self.view setNeedsDisplay] and [self.view setNeedsLayout], but it doesn't work.
I can't seem to find a way to make that cell redraw to it's right size without scrolling the table once the view appears.
Is there some other method to force the redraw before it actually appears?
try:
NSIndexPath *theIndexPath = [NSIndexPath indexPathForRow:cellRow inSection:cellSection];
NSArray *theIndexPaths = [NSArray arrayWithObject:theIndexPath];
[table reloadRowsAtIndexPaths:theIndexPaths withRowAnimation:NO];
What are you currently using to redraw the cell? Just waiting for it to redraw itself when it goes off screen and back on? Or are you using something like [table reloadData];?
Ok, I'm stuck. This is an extension of a previous post of mine. Here is what I am trying to do.
I have an Edit button on a navigation bar that when pressed adds a cell at the beginning of my one section table view. The purpose of this cell if to allow the use to add new data to the table; thus it's editing style is Insert. The remaining cells in the table are configured with an editing style of Delete.
Here is my setediting method:
- (IBAction) setEditing:(BOOL)isEditing animated:(BOOL)isAnimated
{
[super setEditing:isEditing animated:isAnimated];
// We have to pass this to tableView to put it into editing mode.
[self.tableView setEditing:isEditing animated:isAnimated];
// When editing is begun, we are adding and "add..." cell at row 0.
// When editing is complete, we need to remove the "add..." cell at row 0.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSArray* path = [NSArray arrayWithObject:indexPath];
// fill paths of insertion rows here
[self.tableView beginUpdates];
if( isEditing )
[self.tableView insertRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationBottom];
else
[self.tableView deleteRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
// We nee to reload the table so that the existing table items will be properly
// indexed with the addition/removal of the the "add..." cell
[self.tableView reloadData];
}
I am accounting for this extra cell in my code, except I now have two index paths = [0,0] - the new cell and the old original first cell in the table. If I add a call to reload the table view cell in setEditing, the cells are re-indexed, but now my table view is no longer animated.
I want my cake and eat it too. Is there another way to accomplish what I am trying to do and maintain animation?
--John
You can do what you want but you need to keep your data source consistent with the table. In other words, When the table is reloaded, tableView:cellForRowAtIndexPath and the other UITableViewDataSource and UITableViewDelegate methods responsible for building the table should return the same cells depending on editing state that you are adding/removing in setEditing:antimated:.
So, when you insert/delete a cell in setEditing:animated: you need to also make sure your data source reflects the same change. This can be tricky if you are adding a special cell to the beginning of a section but the rest of the data is from an array. One way to do this is while reloading the table, if editing, make row 0 the add cell and use row-1 for your array index for subsequent cells. If you do that you'd also need to add one to tableView:numberOfRowsInSection: to account for the extra cell.
Another way would be to have a section for the add cell and it would have 0 rows when not editing, 1 row otherwise and you return the appropriate cell. This will also require you to configure your table and cell(s) appropriate depending on how you want things to look.
I have a UITableview cell that gets a tally from a core data database. The tallyTable is in a view controller inside a UITab view. I have an NSLog statement that prints out the tally value whenever it gets updated. Another tab has a list to change the source (different day) for the tallies. I am using iOS5 with ARC targeting iOS 4.2.
Here's the problem. When I load the application, the correct tallies for whatever the last selected day show up in the table tab. If I then go to the day tab and change the day and return to the tally tab there is no change in the display. However, the viewWillAppear on the tally tab runs and as the table cycles through cellForIndexPath, my NSLog statement prints out all the correct new values. If I then scroll the top label off the screen and back the label updates to the new value.
I've tried setNeedsLayout and setNeedsDisplay on the UILabel, the UITableViewCell, the UITableView and the view controller loading the table. I tried changing the CellReuse identifier so that it would never reuse a cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CollectionItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CollectionItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [[self.collectionKeys objectAtIndex:row] valueForKey:#"collectionTitle"];
NSInteger test1 = indexPath.row + 150;
NSLog(#"tag = %i", test1);
cell.tallyButton.tag = test1;
NSNumber * questionID = [[self.collectionKeys objectAtIndex:row] valueForKey:#"answerID"];
cell.tallyLabel.text = [NSString stringWithFormat:#"%i",[self updatePointTotal:questionID]];
NSLog(#"Collection text should be = %#", [NSString stringWithFormat:#"%i",[self updatePointTotal:questionID]]);
[cell setNeedsLayout];
return cell;
}
I've read over a half dozen other similar questions. Got about three hours invested so far in trying to solve this.
EDIT: I thought I fixed it by using the navigation controller to repush the top level view controller on to the view again. I'll admit now this feels like a classically kludgy hack in every way. When the view is PUSHED everything updates and it is seamless. However, in order to have a fixed footer to make selection settings for the table buttons, I used a UIView with two subviews, a UITableView on top and a simple UIView with four buttons below.
The captions on the buttons need to change with the data source. Now when the view controller is pushed onto the view it obscures my fixed footer view. So, I inserted the fixed footer into the UITableview and everything appeared fine until I scrolled the UITableView and the footer scrolled up with it. The table is basically a tally sheet with buttons next to each item and in the footer is four buttons to note the color of the tallied item. Say the next item was a green lego, you would tap "green" in the footer and the button next to "lego" in the table. When I push the view controller with the two subviews the UITableview labels do not update. Thus the tableview needs to be pushed itself (as far as I can tell).
ANSWER: see comment below but ultimately I needed to reload both the visible UITableView data and the delegate UITableView controller data behind it.
I'll give it a shot. First, are you using ARC? If not, you need to add autorelease when you alloc/init a new cell. Otherwise, it's fine as is.
If I'm understanding your question correctly:
The tableView displays the correct data at app launch
You switch away from the tab with the tableView and change the tableView dataSource
You switch back to the tab with the tableView and you see (via NSLog) that the table cells are reloaded with the correct data yet the old data is still visible in the cells
If you scroll a cell off the display and back forcing it to refresh it contains the correct data
Some thoughts:
the tableView will not reload itself automatically when it's view appears. You need to call [tableView reloadData] whenever the dataSource changes. This is independent of whether the tableView is currently displayed or not. My guess is this alone will solve your problem.
You don't need to call setNeedsLayout on the cell unless you want the cell to relayout its subviews based on the data. You also don't need setNeedsDisplay.
I'm assuming there aren't other complicating factors (such as multiple tableViews displaying the same data) that could confuse things.
If you use prepare for reuse method, remember to over the original method with [super prepareForReuse];
Another method if the above way does not work is re setup cell as describe here.
I use the same method i applied for some of my collection view : we should remove/reset your subview where you create/add it to cell 's content. That mean we need set up data each cell completely for each row.
I move the code reset data value from prepare reuse to where i set value and I worked simply !
In my CustomCell.m :
- (void)configCellWith:(id)item At:(NSUInteger)row {
if (_scrollView) {
[[_scrollView subviews]
makeObjectsPerformSelector:#selector(removeFromSuperview)];
_scrollView = nil;
[_scrollView removeFromSuperview];
}
else {
CGFloat y = labelHeight+15;
float scrollHeight = _imgArray.count*200;
_scrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(10, y,SCREEN_WIDTH-20, scrollHeight)];
_scrollView.scrollEnabled=YES;
_scrollView.userInteractionEnabled=YES;
_scrollView.layer.masksToBounds = YES;
[self.contentView addSubview:_scrollView]; } }
Remember to change your data source appropriately too.