Is there a way to troubleshoot not receiving the NavBarDelegate callbacks? I tried in a test project to just do:
[self.navigationController.navigationBar setDelegate:self];
in viewDidLoad and I did receive the callbacks for:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item {
NSLog(#"%s", __FUNCTION__);
return YES;
}
- (void)navigationBar:(UINavigationBar *)navigationBar didPushItem:(UINavigationItem *)item {
NSLog(#"%s", __FUNCTION__);
}
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
NSLog(#"%s", __FUNCTION__);
return YES;
}
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item {
NSLog(#"%s", __FUNCTION__);
}
I did check that my ViewController conforms to this protocol in the interface .
In viewWillAppear:, I check if my class conforms to the protocol with:
if ([self conformsToProtocol:#protocol(UINavigationBarDelegate)]) {
NSLog(#"yes I conform");
}
And I do get the NSLog message saying my class conforms, but I do not get the callbacks. As it works in a test project, and it doesn't work here, I'm trying to figure out other ways to troubleshoot this. Any thoughts? Thanks.
I am leaving this for future anyone who will encounter this issue:
You need to place these <UINavigationBarDelegate> protocol methods inside your Navigation Controller's class, not inside a view controller's class you are working on.
In my case I just have a class NavigationController (subclass of UINavigationController), singleton instance of which: sharedNavigationController works for my entire app. I have set it to conform <UINavigationBarDelegate> protocol and declared these methods in it. All worked fine since then.
Related
i've got a little problem with my custom UITabBarController class. My UICustomTabBarController is a subclass of UITabBarController. In my didSelectItem event I implemented the following code:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
[self showActivityIndicator];
}
I my showActivityIndicator method I add a activity indicator to my current view. It works just fine.
Now i would like to remove the activity indicator when the current view will disappear.
i found the following events:
-(void)viewDidDisappear:(BOOL)animated {
NSLog(#"hello");
}
-(void)viewWillDisappear:(BOOL)animated {
NSLog(#"hello");
}
-(void)viewWillAppear:(BOOL)animated {
NSLog(#"hello");
}
-(void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
NSLog(#"hello");
}
Unfortunately none of them are working. They are not being called. Am I doing anything wrong?
Thanks for your help!
Is the delegate property for UITabBar is set in the .h file ? ?
i.e. <UITabBarDelegate,UITabBarControllerDelegate>
im kinda new to iOS.
I know that a void method i.e
-(void) pressed {
}
can be called this way:
[self pressed];
and viewDidAppear
can be called something like this:
[self viewDidAppear:YES];
I was wandering on how to do it in this method below, or how to re-Call it:
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return [images count];
}
You shouldn't call -(void)viewDidAppear:(BOOL)animated, it's part of the UIViewController lifecycle and it will be called automatically. As for the other one:
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return [images count];
}
I never used iCarousel, but it seems to be a method from the Data source, and, as such, shouldn't be called directly as well.
That may me data source method... It is called from a controller.
//And it may be called in the controller as below where delegate is object of some class
iCarousel *iCarouselObj;
if(delegate && [delegate respondsToSelector:#selector(numberOfItemsInCarousel:)])
int items = [delegate numberOfItemsInCarousel:iCarouselObj];
//The below code is just to tell you how to call a method with arguments
iCarousel *iCarouselObj;
int items = [self numberOfItemsInCarousel:iCarouselObj];
Have two actionsheet buttons and one modalviewcontroller on mainviewcontroller in application. Now for two actionsheet buttons and for modalviewcontroller, can i have multiple dismissviewdidfinish method for each
-(void)dismissViewDidFinish:(ModalViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
-(void)dismissViewDidFinish:(Devanagari *)controller1;
{
[self dismissViewControllerAnimated:completion];
}
-(void)dismissViewDidFinish:(English *)controller2;
{
[self dismissViewControllerAnimated:YES];
}
Cause if i add these three methods on mainviewcontroller i get red warning message duplicate declaration of method dismissviewdidfinish.
Any ideas how to solve this kind of situation.
You cannot have the same name for more than 1 method. Use a single dismissViewDidFinish:(UIViewController *)viewController method and then check to see which viewController finished:
- (void)dismissViewDidFinish:(UIViewController *)viewController {
//check to see what kind of class viewController is
//or use tags by setting the viewcontroller.view.tag when creating it
}
Ok -- this one is weird. I have a singleton class that loads information from an XML file. I am using a delegate definition as follows (I define the delegate in a separate header file to make life easier):
#protocol ResourceClassDelegate <NSObject>
#optional
- (void)picturesDidStartLoading;
- (void)picturesDidFinishLoading;
#end
In the resource file, the delegate is defined correctly (I believe):
#property (assign) id<ResourceClassDelegate> delegate;
When using the delegate, the code in the resource class is as follows:
-(void)refreshPiecesOfHistoryWithOperation {
NSLog(#"Operation Started");
if ([delegate respondsToSelector:#selector(picturesDidStartLoading)])
[delegate picturesDidStartLoading];
self.picturePacks = [HistoryXMLParser loadPicturePacks];
[self.allPiecesOfHistory removeAllObjects];
// now lets put all of them in one big file...
for (PicturePack *pp in self.picturePacks) {
for (int ct = 0; ct < [[pp piecesOfHistory] count] ; ct++) {
[self.allPiecesOfHistory addObject:(PieceOfHistory *)[[pp piecesOfHistory] objectAtIndex:ct]];
}
}
NSLog(#"Operation Ended");
if ([delegate respondsToSelector:#selector(picturesDidFinishLoading)])
[delegate picturesDidFinishLoading];
}
Now... in the class that is listening to the delegate, it is assigned:
- (void)viewDidLoad {
[super viewDidLoad];
// now for the part that makes the loading all happen...
[[ResourceClass sharedResourceClass] setDelegate:self];
}
And in the listening class, the methods are defined....
#pragma mark ResourceClassDelegate
-(void)picturesDidStartLoading {
if (loadingActivity == nil)
loadingActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.view addSubview:loadingActivity];
[loadingActivity setCenter:[self.view center]];
[loadingActivity startAnimating];
}
-(void)picturesDidFinishLoading {
if (loadingActivity != nil) {
[loadingActivity stopAnimating];
[loadingActivity removeFromSuperview];
}
[self.tableView reloadData];
}
Now for the problem... every single time, in the listening class, the method (void)picturesDidFinishLoading is called. The method (void)picturesDidStartLoading never is called.
When I debug the code, in the resource class, the line
if ([delegate respondsToSelector:#selector(picturesDidStartLoading)])
[delegate picturesDidStartLoading];
never reaches the delegate method call - even if I remove the if statement. The line
if ([delegate respondsToSelector:#selector(picturesDidFinishLoading)])
[delegate picturesDidFinishLoading];
is always called.
any ideas?
Ok -- I figured it out....
The delegate was nil during the first call. The reason it is nil is because the function using the delegate was called in the source during the init method. The init method was not complete when the first test of the delegate was performed. At this time the delegate was nil because it is not instantiated until the the init method completes. The reason the second test of the delegate worked is because I submitted the process using an NSOperationQueue.
To fix the problem I have to move things around a bit... it's all about the timing!
Well now that was fun....
That's weird, try to remove #optional in the protocol declaration, and see if you get some warnings.
Try to print a log inside the method as well, other than that it looks fine.
My view controller is not responding to didRotateFromInterfaceOrientation, despite that I have added following in my code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
[self.popOver dismissPopoverAnimated:NO];
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
... My Custom Code...
}
}
Am I doing something wrong here?
If you can't inherit from UIViewController (which is unfortunate), you can use this:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
Then register to start receiving UIDeviceOrientationDidChangeNotification notifications.
If your UIViewController is a child in some root view then IB does not add it as a child controller to the root controller by default. The easiest way to address this is to modify your root controller:
- (void)viewDidLoad
{
[super viewDidLoad];
[self addChildViewController:(UIViewController*) self.yourChildController];
}
This should do the trick. Now your child controller will be receiving both:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
and
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
messages.
I think the real answer here (more accurately the answer to the linked question) is that you need to call
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
in your subclass implementation of the didRotateFromInterfaceOrientation method. For example:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
// Then your code...
}
This is not mentioned in the apple documentation but caused some serious and unexplained problems for me when omitted...