UITableView reloads data, when pushing a new viewController - ios

I have the following VC hierarchy: ParentViewController -> Navigation Controller(child VC) -> ViewController(with UITableView).
I am meeting the following issue:
In UITableViewDelegate.didSelectRowAtIndexPath, the app is pushing a new ViewController on the stack. The problem is that at this stage, the table view is automatically reloaded, without any explicit call to reloadData. This fact creates several issues, for example on return to the screen(with Back button) the table view is scrolled at the beginning instead of being focused on the selected row.
Could you please help me find why is it doing like so, is it a bug, or how to fix the issue?
UPDATE: I have just tested the same case on iOS 7.1 and there is no issue like that, I mean pushing a viewController, than poping back to the viewController containing the UITableView does not loose focus of the selected row.

hope this could help you.
My solution is to use navigationviewcontroller delegate, save selection when will push another one, and set back when pop back.
My sample code(I have set table view controller as delegate)
static NSIndexPath* path = nil;
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (viewController == self)
{
[self.tableView reloadData];
[self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
path = self.tableView.indexPathForSelectedRow;
}

Related

EGOPhotoViewer and NavigationController

I'm having a problem with EGOPhotoView library in my iOS app, and I hope someone of you can help me.
My app uses a NavigationController, but does not display the NavigationBar, because the navigation is managed my some custom control. The problem is when I show an image gallery with the EGOPhotoView library, which shows a NavigationBar appearing on tap: when I pop the EGOPhotoViewController, the NavigationBar is still displayed, but I don't want.
Can someone help me to fix this problem?
Thanks
You can set one of your classes (probably your app delegate) to be the navigation controller's delegate. Then, when the EGOPhotoViewController is popped, you can hide the navigation bar. E.g.
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
if ([navigationController.topViewController isKindOfClass:[EGOPhotoViewController class]])
{
[navigationController setNavigationBarHidden:YES animated:YES];
}
}

iOS - NavigationBar showing on child controller, hidden on parent controller

I have implemented a custom version of a search form that behaves a lot like a UISearchBar with a scope bar (but is actually pieced together programatically for UI reasons). The screen loads with a TextField, you tap in the TextField and the navigation bar animates up off the screen, the text field moves up and a segmented control appears for filtering results.
Anyway, that all works, but when I tap on one of the search results my code pushes a new ViewController. The problem is that new controller gets pushed without a navigation bar (because I used [[self navigationController] setNavigationBarHidden:YES animated:YES] when switching to the search state).
I can show the navigation bar as the new ViewController gets pushed, or even animate it in as the transition to the new ViewController appears - but all those solutions look clunky. I want it to work as if you were using a UISearchBar (actually more like the email app) in that the restored navigation bar appears to just slide in from the right as if it's part of the child view controller.
I'm hoping there'll be a simple fix... thanks
For anyone that comes to this, the solution is to make your controller the delegate of the UINavigationController, then show or hide the nav bar in your delegate methods.
Your controller needs to implement the protocol:
#interface MYSearchController() <UINavigationControllerDelegate>
Then in -(void)viewDidLoad assign your controller as the delegate:
[self navigationController].delegate = self;
Finally, implement a method like this:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if(viewController == self)
{
if(_searchState && ![self navigationController].navigationBarHidden)
{
[[self navigationController] setNavigationBarHidden:YES animated:YES];
}
}
else
{
if([self navigationController].navigationBarHidden)
{
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
}
}

Alter view when detail view pushed iOS

I have a view with a custom bar at the bottom of the screen. When a collection view cell is pressed, it loads a detail view, and I can go back.
This all works great; however, I have a plus button displayed on the custom bar, and I would like for the plus button to disappear only when the detail view shows up, and then come back when you hit the back button.
So far I have used the delegate method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// Your code to update the parent view
}
The problem is this fires when the detail view is loaded and popped as well. Any idea on how to accomplish this? Thanks!
I assume mainView and detailView are viewControllers. In mainView's viewWillAppear method
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//get reference of plus button here
btnPlus.hidden = NO;
}
In detailView's viewWillAppear method
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//get reference of plus button here
btnPlus.hidden = YES;
}

UITabBarController temporarily missing item title and image in More Navigation Controller

"Has this ever happened to you?"
(Note: The following is ARC-friendly code, hence no autorelease call or retain/release pairs.)
#pragma mark - UIViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
// "We interrupt this designated initializer to go do our own thing ..."
return [self init];
}
#pragma mark - NSObject
- (id)init {
// Why hello there, superclass designated initializer.
if ((self = [super initWithNibName:#"YourNibHere" bundle:nil])) {
// We're in a nav controller, so set the title.
self.navigationItem.title = #"Item Title";
// "Someone set up us the tab bar!"
[self setTabBarItem:[[UITabBarItem alloc] initWithTitle:#"Item Title" image:[UIImage imageNamed:#"itemIcon.png"] tag:itemTag]];
}
return self;
}
So ... this is the top UIViewController in a UINavigationController, which in turn is in a UITabBarController at some index. The classic turducken of Cocoa view controllers, if you will.
You tap the tab bar item, context changes to the top UIViewController, and life is wonderful.
Ahh, but what if you want to programmatically switch to this from a view controller under a different (tab bar) index?
Seems easy enough. Just use -selectedViewController: and pass in the UINavigationController (not the UIViewController) you want to switch to. "Mostly harmless."
This works every time ... except I run into a really annoying quirk whenever that UINavigationController is tucked away beneath the infamous More navigation controller (used by iOS when there are more than five tab bar items in play).
The quirk? When I tap the back button ("More") to pop the UIViewController (it's no longer topmost due to the More sitch, y'see), the imageView and textLabel in the table view cell identifying this tab bar item are missing! As in not there. Just an empty cell.
If I scroll the table view cell offscreen and back on, or otherwise move away from and back to the More navigation controller, then it appears. :(
Wha' happen? Inquiring minds want to know ...
I made a fix for this. It's not pretty but it's something.
Extend the UITabBarController:
- (void)viewDidLoad {
[super viewDidLoad];
self.moreNavigationController.delegate = self;
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
//Fix for not showing the selected item in the tableview.
if ([navigationController.topViewController isKindOfClass:NSClassFromString(#"UIMoreListController")]) {
[navigationController.topViewController.view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UITableView class]]) {
*stop = YES;
UITableView *tableView = (UITableView *)obj;
[tableView reloadData];
}
}];
}
}
This way the tableview will reloaded when it becomes visible. You'll see the cell appear in the transition but that's not a problem for me.

TTNavigator does not work when used in DDMenuController's leftController

so, I tried creating a project using this awesome DDMenuController and set a list menu controller in the left, with just datasource of three20's items, like this:
[section addObject:[TTTableTextItem itemWithText:#"Groups"
URL:#"tt://groups"]];
[section addObject:[TTTableTextItem itemWithText:#"Friends"
URL:#"tt://friends"]];
[section addObject:[TTTableTextItem itemWithText:#"Updates"
URL:#"tt://updates"]];
and these url's i set in the URL Map as Shared View Controllers.
The problem here is nothing happens when i tap on the cell which should basically just push to a specified view controller,
But when i tried setting my right controller the same controller with my left controller, it works.
I didnt notice that DDMenuController overided
(void)pushViewController:(UIViewController *)viewController
animated:(BOOL)animated
so i just add some codes to enable pushing in left view controller:
- (void)pushViewController:(UIViewController *)viewController
animated:(BOOL)animated {
//DDMenuController code here...
else {
[self showRootController:YES];
[super pushViewController:viewController animated:NO];
}
}

Resources