The main controller is a tabBarController; one of the tabs is navigationController, then in that navigationController is a UItableView with searchDisplayController.
SearchBar is in UItableView.
However, I dont' know what I have changed (I should use snapCapture next time....). My searchBar is gone.
What I mean gone is that after my compilation, I cannot find the seaerchBar in my tab. (It is okay before I am changing sth; coz I have changed a lot, I cannot load back anymore)
I have printed a log like,
[self.searchDisplayController description]
But it is NULL.
Can sbd suggest me some directions for me to check? Thanks
In each Tab you need to add only one navigation controller, inside that you need to add either viewcontroller or tableview controller or search display viewcontroller.
You need add the objects in the above way, i dont think you have added in this format, from the image you have provided, there is only one tab in that you have added 3 navigation controllers..
I found my fault it is.
Should be
#interface ThirdViewController : ***UIViewController***
NOT
#interface ThirdViewController : ***UITableViewController***
UIViewController Class Inherits from UIResponder : NSObject
UITableViewCell Class Inherits from UIView : UIResponder : NSObject
I think that is why for tableview, I cannot show the search bar. So, in my case, I hope can help others do not make any not necessary changes, like me ##
And please do use snapCap
Related
I recently changed my app structure to include a UINavigationController as base for my hierarchy and I had its root viewController implement the UINavigationControllerDelegate protocol in order to implement custom segues.
My viewController implements navigationController:animationControllerForOperation:fromViewController:toViewController:.
My problem is two-fold:
The navigationController.delegate methods are not being called.
The navigationBar is not called in the views being pushed via storyboardSegues of type show.
The prepareForSegue:sender: function is being called.
This is my UI:
Turns out that UIStoryboardSegues I added before I added the UINavigationController to my hierarchy are still interpreted as modal segues. Probably this is set during creation.
The problem was solved by deleting and re-adding the segues in question, with the relevant information (identifier, class...) transferred to the new instance.
If you have the same problem, when you set Top Par to inferred in your segued viewController you will see no navigationBar showing.
After replacing the segues the Top Bar showed again as normal.
Edit:
I posted the question together with this answer, since there was no post on SO covering this issue. self-answer
In order to get my custom menu up and running, I've ended up using a UITabBarController and need to change the view displayed programmatically, vs the standard tabbed menu on screen.
Everything is working as expected except on thing. I am attempting to use:
[self setSelectedIndex:index];
This code is inside my UITabBarController subclass in a custom delegate method. (This is so I can programmatically adjust the view when interacting with my menu). However, while this code is called, it doesn't do anything?
Does it HAVE to be called from one of the tabbed views? I was hoping to run it from inside the TabBarController to avoid repeating the code in each tabbed sub controller.
UPDATE:
Just found that using [self setSelectedIndex:index]; works fine in viewDidLoad. But when it is called inside the delegate method, it doesn't change view. It is using the right index number and getting called, but not doing anything from that method.
Also, it seems the tab controller is a different object when I log self in viewDidLoad vs my delegate method. So why would I be loosing the reference to the original controller?
It's just a UITabBarController in a container in another view controller.
Delegate Code:
#Interface
#protocol SLMenuDelegate <NSObject>
#required -(void)menuDidChangeViewToIndex:(NSInteger)index;
#end
#property (nonatomic, assign) id<SLMenuDelegate>menuDelegate;
#Implementation
#synthesize menuDelegate;
self.menuDelegate = [self.storyboard instantiateViewControllerWithIdentifier:#"TabBarViewController"];
[menuDelegate menuDidChangeViewToIndex:[self.menuItemButtons indexOfObject:sender]];
UITabBarController
-(void)menuDidChangeViewToIndex:(NSInteger)index
{
[self setSelectedIndex:index];
}
Setting breakpoints and running NSLogs and there is no question that the method gets called and all code runs.
Try using delayed performance:
dispatch_async(dispatch_get_main_queue(), ^{
[self setSelectedIndex:index];
});
I didn't manage to find a solution to the exact issue, but I found an equally good way of resolving my issue simply.
I stopped using a delegate to send my button tap message and change the view. Instead I did the following:
SLTabBarViewController *tabBar = [self.childViewControllers objectAtIndex:0];
[tabBar setSelectedIndex:[self.menuItemButtons indexOfObject:sender]];
This gets the embedded tab bar controller and I simply directly change the view from the original view controller from which the button tap comes from.
It may not be an intelligent solution, but its a simple and functional one which doesn't create any problems.
I have a view that I want to reuse in different situations. It is a user view that, when touched, will have the viewcontroller push a user detail viewcontroller.
So basically I have a view that can any number of superviews until the viewcontroller. I want that view to be able to notify whatever viewcontroller that is currently being displayed to push the user detail view.
Is there a way besides using NSNotificationCenter to do this? Is NSNotificationCenter my best option? I've tried to put in a protocol/delegate, but that isn't working out for me.
Thanks!
------------------------Response to a comment----------------
I would like to have it so it is dynamic. That is partially my problem. I will use this view throughout my code and when I make updates/changes, I don't want to have to change the actual user view to make things work
An example would be adding this user view on the following hierarchy: viewcontroller->tableview->tableviewcell->userview. But then I'd also like to add it like this: viewcontroller->userview.
navigationController.topViewController may be helpful in this case. Or if your app is using a single navigation stack, you could handle this notification in the appDelegate
#interface AppDelegate
#property (nonatomic, strong) UINavigationController *nav;
...
[nav pushViewController:userVC animated:YES];
I think it does make sense to use an NSNotification in this case. Per MVC, the UIView handling the touch event should not need to know much about the View Controller hierarchy it lives in. Notifications handle that issue.
I am thinking that I will subclass a UINavigationController and register for my NSNotification there, then i won't have to worry about registering on each UIViewController in my app. I'll leave this answer here for a bit without checking it as the answer to see what kind of side effects this might have.
I have two questions about this one. First, I have the navigation controller successfully put in the storyboard and is linked with the tabs and is working how I would want it to. Except for one thing. When I try to add a code such as this
[self.navigationController popToViewController:vc animated:YES]
I get an error Property 'navigationController' not found on object of type 'AppDelegate *'
Is this because I put it in the wrong place? Or becasue its a tabbar application and something aint right.
It sounds like you're trying to make a call to your navigation controller from your AppDelegate. Unless you've specifically setup your AppDelegate to work with your navigation controller (it'd need to be a subclass of UIViewController), you'll get an error because there is no Navigation Controller on your AppDelegate class (by default). Therefore, when you make that call - the navigation controller can't be found. Notice how your AppDelegate is a subclass of UIResponder, not UIViewController:
#interface AppDelegate : UIResponder <UIApplicationDelegate>
Instead, create and / or connect your navigation controller to a UIViewController subclass - then you can make calls like this from your subclass:
[self.navigationController popToViewController:vc animated:YES];
To create and setup a Navigation Controller, follow these steps (may vary if you aren't using storyboards).
Create a new UINavigationController Obj-C subclass. In the Xcode menu bar, select File > New, or press CMD+N. Name your class and set its superclass as UINavigationController:
Note that you don't absolutely need an entirely new class! You can use an existing class that is a subclass of UIViewController - as long as the navigationController property is available.
Add your navigation controller from the objects library in Xcode and set it up the way you need it.
Select the NavigationController in your Storyboard, then open the Utilities Panel, and select the Identity Inspector Tab. Set the Custom Class name to the name of your UIViewController or UINavigationController subclass:
From your class you'll be able to use the navigationController property, among hundreds of others relating to the View Controller. Remember that the AppDelegate is really a place for setting up your app and handling app events (ex. app closing, app backgrounding, app opening).
This may be an easy answer for someone.
I first built an a navigation app that had a table loaded from SQLite. The rootViewController (UITableViewController) is loaded from the mainWindow.xib . I added the search and scope functions, and push a detailed view (UIViewController) from a row selection just fine, and can navigate back and forth to and from the table and filtered results, search, with scoping different searches. All is good, no errors, crashes, or warnings.
Now I have tried to add a tabBar interface on top of the rootViewController...after 2 days I have got the TabBarController to display (I was trying to implement it directly on the RootviewController, but found I had to implement it in the mainWindow) and I can select different views (xib) from the tab bar. I have one tab that has no view assigned to it in IB, and I can see the RootViewController load as it did before as the first screen in this tab view, even though RootViewController is not assigned in the tab.
The problem is I cannot click on a row in the table when it loads this way. Alternatively if I create a tab, calling the RootViewController, I get the search bar on the top, but the table is empty. I feel this is somehow due to my appDelegate loading the rootViewController, and me not knowing how to get it to "load" or "reload" into the tab, or something like this. I tried creating a separate "search.xib" that was identical to the original mainWindow before adding the tab bar, then trying to load that in the TabItem, so it called the appDelegate first, but no cigar: crash. I verified the search.xib works fine, as I put it as the info.plist "Main nib file base name", and this loads fine and works as before this BS of adding a tabBarController...
I would start pasting code, but not sure what someone would need to know what is missing or wrong. I do call [self.tableView reloadData] in -(void)viewDidLoad, in RootViewController.m but it is not helping this problem at all.
Can anyone help?
Mac OS X is version 10.5.8, and I am using XCode 3.1.4.
// Create and configure the main view controller.
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
rootViewController.violinMakers = violinMakers;
[violinMakers release];
// Add create and configure the navigation controller.
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navController = navigationController;
[navigationController release];
// Configure and show the window, Override point for customization after app launch
[window addSubview:[navController view]];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
Thanks for trying to help!
The last section above appears to be where I should get the RootViewController to be on top of the stack, but not sure how.
// <AppName>AppDelegate.h
#interface <AppName>AppDelegate: NSObject <UIApplicationDelegate,
UITabBarControllerDelegate, UINavigationControllerDelegate>{
UIWindow *window;
UINavigationController *navController;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Ben - I do realize what you are saying about the rootViewController being behind the tabBarController. I just don't know how to set the tabBar as the main view, and the navController as a tab of it. I will look at the tutorial you mention and see if that helps explain it. Thanks Ben!
09-10-14 update
Some progress!
I now have the view in the tab with the with the NavBar at the top. I know it is coming from the correct .xib file as the title and the search can now be clicked on, and the scope buttons are the correct names. .... but as before, if I got to this stage or even close, the table information is not loaded into this tab(all cells are blank). How do I get my table to load properly in this cell? I know it is loading on launch, as if there is no view assigned at all to this window, I can see the table n Nav, but cannot click on it.(So close, yet so far away). I now have the tab set up correctly, but the table is not loading properly... rrrr
I have the typical
[self.tableView reloadData];
in the viewController.m in the method:
- (void)viewWillAppear:(BOOL)animated
and in
- (void)viewDidAppear:(BOOL)animated
and in
- (void)viewDidLoad
and tried it some other methods as well, but it is not reloading the table info when I select the tab.
Any ideas on how to reload this table in the TabBar view properly ?
I did find a good tutorial on tabBars that went a bit further than some others in explaining with IB. Twillo Embed Nav in a Tab Tutorial
It would appear that you're adding your tab bar controller on TOP of your table controller. It's not clear where you set up tabBarController, but you should only be adding ONE view to your window (in the third-to-last and second-to-last lines you are adding two).
The basic premise for Navigation and TabBar controllers is that your Tab Bar controller is the primary, and you'll add the Navigation controller as one of its tabs. Then, add the tabBarController.view to your window. Which ever tab is selected will be the visible one.
There's a tutorial posted on the web on this subject.
Basically here is what I have found for those of you with the same problem.
It is not easy, or really suggested by Apple it instantiate a tab bar later in a program. Yes it can be done, but now I would suggest a different method. I found a modal view controller works just a good as a tabBar, abeit smaller, but takes less real-estate, because it can be placed in the navigation bar. If you are planning an app with tabs, start with a tab based app and then customize it, don't try to change the navigation structure later, which is the underlying issue. Secondly I have found Apple's documentation on Interface Builder less than satisfactory. Everyone seams confused and it's implementation limits the actual final product cusomization, not making it easier. Not to mention more confusing on "wiring" all the elements together in it. That really sucks, and I took 2 weeks in trying various methods to make it work. It is not impossible, just incredibly unintuitive, and a mistake on my part to change paddles half way down stream. Look at the alternatives to the way you want to give access to the information, and I think you will find better ways like the modal view to accomplish this, or by simple buttons with IB actions to access different views or further information.
Happy Programming!
Kirk