VERY weird UITableViewController.tableview behaviour on scrollToRowAtIndexPath - iphone

hey all, I'm very confused here, i've been trying to figure this one out. I have a UIViewController, viewControllerBrowse, with two TableViewController, Designations & Types, I call a second UIViewController, viewControllerSelectLibrary, that makes some SOLite operations and fills two arrays from where the first two TableView feed.
When I'm going to call back viewControllerBrowse, I perform inside a NSThread:
[appDelegate.viewControllerBrowse.tvcTypes.tableView reloadData];
[appDelegate.viewControllerBrowse.tvcTypes.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
[appDelegate.viewControllerBrowse.tvcDesignations.tableView reloadData];
[appDelegate.viewControllerBrowse.tvcDesignations.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
What TRUUUULY puzzles me is that on tvcTypes case, its tableView gets its first row selected and scrolled to the top
BUT, for tvcDesignations, its tableView get ITS FIRST ROW SELECTED BUT IT DOES NOT SCROLL TO THE TOP
the fact that the first row is selected tells me that it's not a problem of reference in the appDelegate, it's as if only half the method is working/??????????????
anyone hit this one before??????

Just a guess, but what happens if you pass NO to animated? I've never seen this behavior specifically, unfortunately, but I have seen some animations cause weird interactions.
Also, which view controller is visible? Either of them?

Related

Reloading a table's data

I have 5 view controllers, which are in a navigation controller hierarchy. When I reach my last view controller, there's a button that lets me go back to the "Home" view controller (named CardWalletViewController) which is a table view controller. Here's the method I have in my last VC (PointsResultsVC)
- (IBAction)homePressed:(id)sender {
NSArray *VCs = [self.navigationController viewControllers];
[self.navigationController popToViewController:[VCs objectAtIndex:0] animated:YES];
}
CardWalletVC's cells is being filled up by values coming from the saved instances of a Card in NSUserDefaults and it works fine.
Now, what I want is to update the value in my CardWalletViewController, which is the points of a card coming from my PointsResultsVC. Note that this points is saved in NSUserDefaults.
Upon the process of trying to update of the value shown in my CardWalletVC, I placed [self.tableView reloadData]; inside -viewDidLoad, -viewWillAppear, and -viewDidAppear of the said class. I tried placing it one by one in each of this methods, yet it doesn't seem to work.
Advice Please.
EDIT: problem solved
This one served as my guide Save data from one tab and reloadData in another tab.
And as I have discovered, -viewDidLoad of a certain class will only be called once, all throughout runtime of app. Whereas -viewWillAppear, it will be called every time the view appears.
So, I just moved the way I am loading the values saved in NSUserDefaults from -viewDidLoad to -viewWillAppear. Also, inside -viewWillAppear I placed the [self.tableView reloadData]. Then there, problem solved.
There's a lot of things that could be going wrong so you'll need to provide more info to narrow it down.
First of all, viewDidLoad will not be called so you can remove it from here. Both viewWillAppear and viewDidAppear will be called, so you only need it one of these 2 methods.
Next, you need to determine what the actual issue is.
1 - is self.tableView a proper reference to the table? Are you properly maintaining the reference?
2 - is the table actually reloading but using the old data, or is it not reloading at all? You can log the willDisplayCell method to see what is going on when the view appears.
With that info, the root cause can be narrowed down to a solvable problem.

iphone - scrollRectToVisible issue

This functions perfectly, but I want to make it an once-function, not fixed-function. When I change tableview with other data, the data displays at the index from previous tableview. So my solution to this is implementing the code below. When I implement this, it works, but when I scroll down, it scrolls up all the time, so it is virtually impossible to scroll down further. Any idea how to make it performs only once when I change tableview?
The code:
[tableView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
Edit 21 august:
Guys, thank you very much! The code was in cellforrowatindexpath. I moved it to inside the function which changes tableview and it works like a charm :D
You could override the reloadData method if that is how you are reloading the Table View with new data and put the code in there. Something like this in your table view controller should suffice:
- (void)reloadData {
[super reloadData];
[tableView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}
If it's scrolling up every time you scroll down, I assume you put the code in the cellForRowAtIndexPath method which will get called every time you want to present the cell. This is not the correct place to put that code.
It IS a once-function. Most probably, this code of yours is executing again & again. If you have kept this in a function such as cellForRowAtIndexPath:, which is called frequently, that may be the cause of this problem. Where have you put it?
HTH,
Akshay

Navigating with a UITableView and a detail view

I am sure this is a straight forward application, but not sure what the best way is (and this is all new). I have a Navigation Controller with a UITableViewController (all running in UITabViewController).
When a user taps a row the App goes to a detailed view. Now I am trying to link left and right swipe gestures to navigating the to previous and next record. But what is the right way to do this from within the detailed view, what is the easiest to get a link back to my TableViewController?
A related question is then how I could link a 'pull down' to the same action as the 'back' button of the Navigation Controller.
I hope the above makes sense. Thanks a million in advance!
I have something working kind-of in the way I like, but it is very clumsy.
When calling the DetailView I pass as parameter the pointer to 'self' and the current 'selectedRow'. Then when a swipe is made I call the function 'moveToNextRecord' on the tabelViewController (with the pointer provided) and have the selectedRow as a parameter. In the tableViewController I then call selectRowAtIndexPath and didSelectRowAtIndexPath.
-(void)moveToNextRecord:(NSIndexPath*) selectedRow{
//[self.navigationController popViewControllerAnimated:YES];
//NSIndexPath *selectedRow = [self.tableView indexPathForSelectedRow];
NSUInteger row = selectedRow.row;
NSUInteger section = selectedRow.section;
++row;
if(row >= [self.tableView numberOfRowsInSection:selectedRow.section])
{
row = 0;
++section;
if(section >= [self.tableView numberOfSections])
{
row = 0;
section = 0;
}
}
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section] animated:YES scrollPosition:UITableViewScrollPositionMiddle];
[self tableView:self.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]];
}
This seems to work, but the problem is that the next record is slotted after the previous one. This means that the back-button brings me back to the previous record and not back to the table view. So I guess I should tell the ViewController that I don't want to stack them but basically am going back and then select the next row, while showing the animation directly from one detailView to the next. Does that makes sense?
([self.navigationController popViewControllerAnimated:YES] as first fiction does not seem to work as it does not proper flow.)
From the detail view, once you recognize the gesture, then call:
[self.navigationController popViewControllerAnimated:YES];
this will navigate back.
I am moving towards a PageControl solution, as it is a much improved user experience as the page actually moves at the same time the user swipes. With the above suggestion I would need to over-ride the 'back' button, and manually populate the ViewController-stack in order to allow a left-to-right transition when doing a right swipe (and it only happens when the swipe is completed)

TableView's viewWillAppear() called but data is not refreshed

Sometimes tiny looking problem is ignored to handle in the last but you never know that will become nightmare for you, happening with me.
Thanks in advance, problem my app's settings page contains tableView and every setting element is one of the view. One of the setting item (row) offers show expands a few list of items in another listTableView. After making a selection in listTableView when i come back to my settings tableView using navigationItem.leftButton (Back), selected item value overlaps the previous item's value, in the sense [tableView reloadData] in viewWillAppear works fine but tableView rows are not fresh drawn. It doesn't refresh the cell's UI.
Note that if settingTableView has any subview like UIButton etc it has the latest value, i can use that as workaround but the only problem is when is select this row again Selection has old value that overlaps new value on selecting the row.
I will appreciate any suggestion or sample code using will be great help.
Thanks a ton
Amit Singh
Use [tableView reloadData]; in your viewWillAppear method.
or use [tableView reloadData]; in viewDidAppear method
The problem you are facing is perhaps due to portion of cell that is reusable and the one that is not reused. Check out the code you are writing inside the block of
if(cell==nil){}
components you have created inside block will not get recreated and others might be recreating causing the overlapping on the cell.
In my case, I had to use [self.tableView reloadData]; rather than [tableView reloadData]; in the viewWillAppear method.

How to auto-scroll UITableView?

I am trying to do something interesting.
I am pulling some JSON data and populating cells in a UITableView. How can I make the UITableView scroll ever second or so? I want to give the effect that as new data is coming in, the table is scrolling, so it is streaming.
Any ideas?
Yes, use scrollToRowAtIndexPath:atScrollPosition:animated:.
You could also use UIScrollView's scrollRectToVisible:animated: if you want to have more finegrained control and can calculate exactly what your scroll position should be in pixels. (UITableView is subclass of UIScrollView.)
But if you are just adding cells, sounds like you could also just use insertRowsAtIndexPaths:withRowAnimation:, this is also "interesting."
Just do this
[table reloadData];
NSIndexPath *myIP = [NSIndexPath indexPathForRow:[arrayIn count]-1 inSection:0] ;
[table scrollToRowAtIndexPath:myIP atScrollPosition:NULL animated:YES];
in anywhere where arrayIn is your array by which your table populate.
you can use uitableviews scrollToRowAtIndexPath to do this....heres a link reference
You can call this method whenever as youd like to scroll your tableview
And you can call performSelector:withObject:afterDelay: for the timer effect - although if you are really pulling in data every second, it's best to just reloadData as you go.