I'll be really grateful for any help with this - i've been trying to figure out how to change tabs on a tabbarcontroller from within a nested UITABLEVIEW as in RayWenderlich.com's tutorial on a pulse like scroller http://www.raywenderlich.com/4723/how-to-make-an-interface-with-horizontal-tables-like-the-pulse-news-app-part-2 but am getting really stuck. I am using storyboards and xcode 4.4
I'm completely new to xcode as of a few weeks so I apologise if this is a newbie question. I have got the nested horizontal tableviews working fine as per the image in the link above but I want to use the images to switch to a new tab but can't - I think this is because the tableview is nested so I can't find the right reference to the tabbarcontroller in the hierarchy.
if I use ArticleListViewController.m didselect where the tutorial included comments seem to suggest to insertion navigation code will generate an NSLog output and change tabs ok but only using a tiny thin strip above the images (I discovered this by accident) but nothing happens with the images.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller
//THIS SELECTS WHEN CLICK THINSTRIP JUST ABOVE BUTTONS
NSLog(#"ARTICLELISTVIEWCONTROLLER check didSelect: %u", self.tabBarController.selectedIndex);
self.tabBarController.selectedIndex = 2;
}
the following code within HorizontaTableCell.m more appropriately generates an NSLog output when I click on the actual images but I can't figure out the tabbarcontroller reference that allows me to change tabs.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//the following line just generates an Error as follows: Property tabBarController not found on object of type 'HorizontalTableCell *'
self.tabBarController.selectedIndex = 2;
NSLog(#"HORIZONTALTABLECELL DIDSELECT");
}
Ive looked and looked for a way round this but can't figure it out. Found a mention of using appdelegate but not sure how to do this. can't post storyboard image as new user but has a tabbarcontroller with 4 navigation controllers coming out - the first is the ArticleListViewController menu and each of the others are viewcontrollers - one I hope to put a webview that loads a link/local page depending on the menu selected and the others for an about screen and an additional currently blank screen.
Please help!
thanks!
I'm guessing you have the tabBarController as a property in your app delegate?
You can reach your app delegate with:
[[UIApplication sharedApplication] delegate]
Cast that to your app delegate class and the compiler will not warn you for reaching at the tab bar controller. Like this:
((YourAppDelegate *) [[UIApplication sharedApplication] delegate]).tabBarController.selectedIndex = 2;
As for the tableview delegate method, ArticleListViewController sounds like the place where you'd want that. The cells should just be dumb views with minor presentation logic at most. If it is not getting called, make sure you've set it up as a delegate for the table view properly (in interface builder if you followed that tutorial you linked to).
Related
I am trying to create push segue from view. Maybe image would be best for describing:
I started from sample ECSlidingViewController project (BasicMenu) and I am trying to expand first ViewController (Home) to another ViewController. I get it and I can go from selected row in tableView to the controller. But when I am in controller and I tap on Back I am at different screen from first one (it's blank screen with button at upper left). I guess I must set something more to get this working but I don't know what. Thanks
Updated:
Code from first view controller to go to next view controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Find the selected cell in the usual way
UITableViewCell *cell = [self.searchResultsTableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"selectedSegue" sender:cell];
}
I found that the problem is with code in method didSelectRowAtIndexPath. When I removed it. The segue is performed well and I go to other view controller and when I tap on top left button I get back where I was. It's okay.
So I guess the real problem was with sender in performSegueWithIdentifier.
But I need send to new controller some information about selected row. So I used this answer.
I'm new in iOS and I'm working with Storyboards.
I have an application with some views.
My rootViewController (1) is a UINavigationController that connects to other views. At one point in the application (2), I include a component (SWRevealViewController, Facebook Side Menu Style) that is an instance of UINavigationController, so I have two UINavigationControllers nested within each other. I want to remove or change the first UINavigationController by the new one (2), and just have only one. All views are accessed via custom segues.
Detailed Image Here
I think the solution is to change the rootViewController before loading the view (2), and set the second UINavigationController as the main of the application.
Detailed Image Here
I tried to solve it accessing by:
[UIApplication delegate].window.rootViewController = myController;
but I only have nil or a empty window.
I read many post that the solution could be in my AppDelegate in the method
- (void) applicationDidFinishLaunching: (UIApplication *) application I can't understand how to apply it to my structure, because that method is called when the application is launched.
I think that my workflow application is wrong.Any feedback or help is welcome!
Thanks in advance.
It's fine to change the root view controller from another controller, but your code is wrong. It should be:
[UIApplication sharedApplication].delegate.window.rootViewController = myController;
If you're doing this action from a controller whose view is currently on screen, you can do it this way instead:
self.view.window.rootViewController = myController;
This should work as long as myController has been properly instantiated.
You could possibly remove (1) or off load it into another view controller that is hidden and once the user goes back to a point where you want (1) back you can load it back in. This could be done in the - (void) applicationDidFinishLaunching: (UIApplication *) application.
I have a Master/Detail view which opens a popover view via storyboard segue. There is an add button on the navigation bar of the Master view controller which works fine.
I added an editing mode where the same popover is invoked by selecting a table cell in edit mode. It fails from the [self performSegueWithIdentifier:#"addQuery" sender:self]; statement. The viewDidLoad in the popover is invoked, but after that the exception is thrown.
I am not invoking presentPopoverFromBarButtonItem - it seems to be coming from the performSegueWithIdentifier.
There is no question that the Master View Controller has a window - a table cell for that view was clicked to start the whole process that is failing.
The popover is the beginning of a navigation controller sequence, which may be part of the problem. Everything is working fine when it really is invoked by the button, just trying to programmatically invoke it is failing.
I have tried changing the "sender" for the performSegueWithIdentifier to no avail.
I suspect the problem has to do with the segue not being invoked by a button, and I do not know how to fake that out.
Any ideas?
There appear to be some bugs in how ipad popover segue's work - see Wayne Hartman's blog post
A simple test revealed that viewWillAppear is being called after viewDidLoad.
I think I understand the problem... havent' worked out the solution yet.
The order in which the methods were called are...
[initiate segue]
viewDidLoad
prepareForSegue
viewWillAppear
I moved my initialization code to the viewWillAppear method - and it worked.
In general, I feel it may be a good idea to initialize within viewWillAppear instead of viewDidLoad anyway.
I have a similar issue:
I am using UIDocumentInteractionController to open a kaynote document in Kaynote app. I was using same code:
[docController presentOpenInMenuFromBarButtonItem:_actionBarButtonItem animated:YES];
Code above was opening popover from actiobBarButtonItem with options what app I would like to use to open my file. If I same thing from DetailViewController I get same error message as author of this thread: "Popovers cannot be presented from a view which does not have a window"
And I was able to find a quick solution for my issue . I am not sure if it will be relevant to yours. Instead of using "presentOpenInMenuFromBarButtonItem" I used "presentOpenInMenuFromRect" and thats it. You just need to define right place for popover to apear
I'm having a problem getting a UISearchDisplay's text value to be set programatically on load of the view by another view and my question is have I overcomplicated my problem and missed something or am I on the right track of thinking.
Here's the situation: I have a UITabBarController as my root view, there are 2 tabs, both have a UINavigationController setup so I can push views as needed.
Tab 1 has a UITableViewController which is populated with a list of categories.
Tab 2 has a MapView in it's main view but I have done a custom UINavigationItem view to put various buttons and a UISearchDisplay on the rightBarButtonitem area.
The mapview layout and custom navigation item are stored in the same nib as two separate view objects. In Tab 2's viewDidLoad(), I initialise the rightBarButtonItem programatically with:
UIBarButtonItem *btnItem = [[UIBarButtonItem alloc] initWithCustomView:buttonBar];
self.navigationItem.rightBarButtonItem = btnItem;
[btnItem release];
Everything fires up, buttonBar is wired up to an IBOutlet as searchWhat and I can talk to this object from within the mapview's controller class.
If the user is in Tab 1 and taps a cell, I want it to switch to Tab 2 and populate the searchWhat.text and then execute the search code as if someone had typed in the search themselves.
What i'm having trouble with is the order of load and populate on a view.
I can access the 2nd tab from the 1st without any problem and get it to appear with something like:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Quick Category cell tapped at row %d", indexPath.row);
self.tabBarController.selectedIndex = 1; // change to the search view controller
//[self.tabBarController.selectedViewController viewDidAppear:YES];
UINavigationController *nav = (UINavigationController *)self.tabBarController.selectedViewController;
SearchViewController *srch = [nav.viewControllers objectAtIndex:0];
//NSLog(#"%#", [srch description]);
[srch queueSearchByType:kSearchTypeQuickCategories withData:[catList objectAtIndex:indexPath.row]];
[srch viewDidAppear:YES];
}
Don't worry about catList and SearchViewController, they exist and this bit works to switch tabs.
Here's the problem though, if the user starts the application and selects an item in tab 1, tab 2 appears but the values of the search display text don't get set - because viewDidLoad and viewDidAppear are called in another thread so the execution of queueSearchByType:withData: gets called while the view is still loading and setting up.
If the user selects tab 2 (therefore initialising the subview) and then selects tab 1 and an item, it can populate the search display text.
I can't just change the order of the tabs so that tab2 is first and therefore loads it's subviews to the navigation bar as the project specification is category search first.
Have I missed something very simple? What I need to do is wait for the second tab to fully appear before calling queueSearchByType:withData: - is there a way to do this?
At the moment, i've implemented a queue the search, check for a queue search approach, this seems to be a bit long winded.
Ok, I don't like answering my own question but it appears my fears were right, basically if you want a UINavigationItem that is a custom view (ie, to put a search bar and various other buttons up on the nav controller) and be able to switch to and populate them from another tab on a tab bar controller, then you need to put the subview in it's own class which is a subclass of UIViewController and then make delegation your friend (which it already is), i've provided an example in case anybody needs to repeat it which i've put on my blog HERE.
http://www.jamesrbrindle.com/developer/ios-developer/howto-add-a-custom-uinavigationitem-to-a-uinavigationcontroller-with-delegation.htm
If anyone disagrees and thinks this can be simpler, please let me know or rate this post
which method will be called when i switch between tabs in tabBarController
i know at first time it will call viewDidLoad method ,i want to know is there any method that come in action when i switch to a particular tab (second time or third time ) .
regards
You can use the UITabBarControllerDelegate method tabBarController:didSelectViewController::
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
//do something
}
The method viewWillDisappear: is triggered each time you are about to leave the current view controller (and hence the current tab) and viewWillAppear: is triggered each time a view is about to be displayed.
A full reference for these methods can be found in the UIViewController docs.
This is pretty old, but it does come up on Google and is linked to from another answer. So, I thought I'd update it.
If your UITableBarController is displaying a UIViewController (i.e. its view) then you have to check the ViewController methods that fire when a view disappears and appears. You could use viewWillDisappear to find out if your view is about to be switched away from, and viewWillAppear to test if your view just got switched back to. Notice, the TabBarController typically keeps the ViewControllers loaded, just their views are moved out and in. The problem with using the TabBarDelegate method is that you need to know the name of your viewController, which makes that a dependency. Change the name and it will probably break with xcode's poor ability to rename Class String representations. Avoid it. Besides you don't want a bunch of conditional junk checking to see if your tabbar just loaded a particular tab unless you cannot avoid it. The other thing to notice is that if a particular tab presents a TableViewController you may have to resort to other techniques if you need data in the cells to change in response to being switched away from. I'm using willMoveToWindow:(UIWindow *)newWindow to get notified in the UITableViewCell case when the view goes away. There's probably a better way.