iPhone: Trouble reading badge value from uitabbaritem - iphone

I'm trying to figure out programmatically if a particular tab bar item in my app has a badge.
While I'm debugging, visually, I can plainly see that it does. But when I run this code in the viewController in question:
UITabBarItem* thisVCsTabBarItem = self.tabBarItem;
NSString* badgeValue = thisVCsTabBarItem.badgeValue;
...badgeValue is nil. And when I inspect thisVCsTabBarItem in the debugger, its _badgeValue member is nil.
What's going on here? Should I be doing something differently in trying to read this value from the tab bar item?
Thanks.

Looking at some code where I use the UITabBarItem badgeValue property, I see that self.tabBarItem.badgeValue returns nil while self.navigationController.tabBarItem.badgeValue returns the correct value. Could that be it?
The thing is that the auto-completion actually gives me tabBarItem after self. Easy to make a mistake because of that.

I do something like this for a Downloads tab:
for (UITabBarItem* item in self.tabBarController.tabBar.items) {
if (item.tag == 3) {
if (downloadCount > 0) {
item.badgeValue = [NSString stringWithFormat: #"%d", downloadCount];
} else {
item.badgeValue = nil;
}
}
}
I don't think you are supposed to access the tabBarItem directly. It is better find your item in the tabBarController's items array.

Related

push from a side bar menu to another view controller in ios

I use in my application, the side bar menu like in facebook, so I have different cells in this menu, what I want is to when click on a cell push me to another view controller. I face a problem here which is: the menu is a table view which I don't have it in storyboard, I use some classes from this site:github
and I've stucked here, in my application I use a storyboard, but this menu is programmed with code, and doesn't have a view in stroyboard,
in the didSelectRowAtIndexPath method: I use like this
for(int j=0; j< 9 ; j++)
{
if(indexPath.row == j)
{
DetailsSidebarViewController *essayView = [[DetailsSidebarViewController alloc] init];
essayView.detailItem = [jsonResults objectAtIndex:j];
NSLog(#"%#=%d",essayView.detailItem,j);
}
}
and I create a DetailsSidebarViewController as the new view controller when I push from menu item. in this class, I create a method to configure the view, and just I echo the result:
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
NSLog(#" %# ", self.detailItem);
}
}
the result is true like I want, but I want to push to another view controller, in fact nothing is happened when I click on an item into the menu.
How can I create the new view controller in storyboard? if the menu has not a storyboard, and how can I connect them with segues?
In fact, I am blue with it, please help!!
You should make an instance of the App Delegate class in the Side Menu view controller, and push it from there. You must have a reference to the Side Menu View and a reference to the Center View! Import your App Delegate into the Side Menu controller, and in the didSelectRowAtIndexPath, use:
DetailsSidebarViewController *essayView = [[DetailsSidebarViewController alloc] init];
essayView.detailItem = [jsonResults objectAtIndex:indexPath.row]; // note that you don't need the for loop to know what object you need
AppDelegate* myAppDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[myAppDelegate.sideMenuViewController toggleSideMenu]; // the idea here is that you have to close the side menu, i.e. it must dissapear
[myAppDelegate.centerViewController.navigationController pushViewController:essayView animated:YES];
This is all the code you need.
If I may, as a piece of advice, use Mike Frederik's MFSideMenu instead of the library you're using. In my opinion, it has a more simple and a more straightforward implementation, just look into the README file, everything is explained pretty simple, and it has exactly the code you need!
Hope this helps, good luck!

iOS - incorrect badge value retrieved from tab

I'm trying to retrieve the value displaying for a specified tab. It was working before and it stopped for some reason? The int current_badge = line on the code below is where the badge value is fetched and returns zeros no matter what the badge value actually is. I'm in a viewcontroller segued off of a uitabcontroller. Anyone have any thoughts on what I'm doing wrong?
UPDATE: It appears to be because I'm in a viewcontroller off of a tab controller. Move the same code into a tab viewcontroller and it works fine. Is there a better way to determine the badge value in a tabcontroller when segued out of it?
-(void)badgeUpdate:(int)tab:(int)dayspan
{
// getting the current badge amount
int current_badge = [[[super.tabBarController.viewControllers objectAtIndex:tab] tabBarItem].badgeValue intValue];
// testing for badge level
if (current_badge > 0)
{
// testing for updates on tab for dayspan or longer
int updates_waiting = [self updatesWaitingCheck:tab:dayspan];
if (updates_waiting > 0)
{
// setting new badge level on tab
[[[[[self tabBarController] viewControllers] objectAtIndex:tab] tabBarItem] setBadgeValue:[NSString stringWithFormat:#"%d", updates_waiting]];
}
else
{
// turning off badge display
[[[[[self tabBarController] viewControllers] objectAtIndex:tab] tabBarItem] setBadgeValue:nil];
}
}
}
The controller for that tab is likely being deallocated when you switch away. I would suggest moving the logic to determine the current count out of the view layer, and into a higher level controller that persists across all tabs. Otherwise, you'll run into the problem you're seeing.
Most of the time, if you're looking for a data value in a view object, rather than in a controller or model somewhere, you're working against the framework and you'll run into problems like this.

FPPopover UITableView return value

i don't know if anyone is using this open source library for replacing UIPopovercontroller for an iPhone.
i'm trying to deploy the FPPopover into my project, everything is working like i want, but the problem is that i'm not able to return any value to my ViewController.
i'm trying this in didSelectRowAtIndexPath
myParentViewController *parentController =(myParentViewController*)self.parentViewController;
but the problem is that self.parentViewController is (null)
i have also another problem, how can i dismiss the FPPopoverController from within didSelectRowAtIndexPath.
I dismissed the view by adding a popoverView property to the table view controller that is popping up (in this case ATableViewController), and then assigning the FPPopoverViewController to that property. Like this:
ATableViewController *aTableViewController = [[ATableViewController alloc] init];
FPPopoverController *aPopoverController = [[FPPopoverController alloc] initWithViewController:aTableViewController];
aPopoverController.delegate = aTableViewController;
aTableViewController.popoverView = aPopoverController;
Then in didSelectRowAtIndexPath of aTableViewController you can just call:
[self.popoverView dismissPopoverAnimated:YES];
If you are trying to return values to the "parent"...since the parentViewController property is null here, you can just make your own property for it (let's call it "parentView"). So when setting up the above you would use:
aTableViewController.parentView = self;
Then you can access any of the properties of the parentView and return values from the aTableViewController that popped up. A bit of a workaround, but that's what I did...hope it helps!

iOS - Navigation Title Not Updating

What I'm doing with this bit of code is grabbing an image sequence, grabbing it's name. Then setting the view's title as the sequences name playing the sequence then setting the title back to the old title.
Problem is the title doesn't seem to be changing on the navigation bar. The NSLogs are outputting the correct values though.
I remember having this issue before and solving it with some "refresh" method.
Here is the pertinent code.
-(void)playSequence
{
if (([animatorViewController isAnimating] == FALSE) && (btnDisable == FALSE))
{
Sequence *tempSequence;
tempSequence = [fullStepList objectAtIndex:lastPlayedSequence];
self.title = [NSString stringWithFormat:#"Assembly - %#", tempSequence.subName];
NSLog(self.title);
[self startAnimator:tempSequence.imageNameScheme forNumFrames:tempSequence.numberOfFrames playInReverse:FALSE];
tempSequence = nil;
tempSequence = [fullStepList objectAtIndex:queuedSequence];
self.title = [NSString stringWithFormat:#"Assembly - %#", tempSequence.subName];
NSLog(self.title);
tempSequence = nil;
}
}
EDIT: This method of changing the title is working else where in this class. The problem seems to come in when trying to set it twice that is causing the issue.
EDIT2: It's actually running both title changes one after another... Fact that it was setting it back to previous was throwing me off.
A navigation item may contains four things: leftBarButtonItem, rightBarButtonItem, title, and titleView. When you need to change the title you should assign your title to navigationItem's title property, not to your view's title property. So it would look like:
self.navigationItem.title = [NSString stringWithFormat:#"Assembly - %#", tempSequence.subName];
self.title points to your viewControllers title which don't shows up in the navigationBar.
The title won't appear to update until after the main run loop executes. Unless -startAnimator:forNumFrames: invokes the main run loop to execute before it returns, you won't see the change.
If you are hosting the UINavigationController inside another view, you need to do this:
self.yourNavigationController.title = #"title";
instead of
self.title = #"blah"
Otherwise you are just changing the title of the view hosting the view navigator. Just a guess.
I recently found myself in a similar situation. My view's title was comprised of a label with an NSMutableAttributedString. Calling [self reloadInputViews] whenever I updated my title worked for me.
The dreaded P.E.B.K.A.C. error was the cause of this confusion. It's actually running both title changes one after another... Fact that it was setting it back to previous was throwing me off.

How to add a badge to a UITabBar that is customizable?

I am adding a badge to my UITabBarController's UITabBar as such:
UITabBarItem *tbi = (UITabBarItem *)[stTabBarController.tabBar.items objectAtIndex:1];
tbi.badgeValue = #"2";
However, my UITabBarController is customizeable, so the index may change. How can I make sure the badge gets applied to the correct UITabBarItem?
One suggestion you might consider is setting a tag on each tab bar item. You can do this in Interface Builder or when you create the item by code. You can then loop through the view controllers in the tab bar controller looking for the one with the tab bar item you are interested in. For example:
// #define MyTabBarItemTag 999
for (UIViewController *viewController in stTabBarController.viewControllers) {
if (viewController.tabBarItem.tag == MyTabBarItemTag) {
viewController.tabBarItem.badgeValue = #"2";
}
}
UITabBarItem *tbi = (UITabBarItem *)self.tabController.selectedViewController.tabBarItem;
tbi.badgeValue = #"New";
Also works.
Swift version:
self.tabBarController?.selectedViewController?.tabBarItem.badgeValue="12";
I'd use an NSMutableDictionary property on the class that owns the tab bar controller, associating tab names with positions, and a method to retrieve by name:
-(UITabBarItem*)getTabByName:(NSString*)tabName {
return [stTabBarController.tabBar.items objectAtIndex:[[tabDict valueForKey:tabName] intValue]];
}
Initialize the dictionary in your setup code for each tab, since you know the tab index at that time:
[tabDict setValue:[stTabBarController.tabBar.items objectAtIndex:1] forKey:#"myTabName"];
Keep a reference to the tab bar item that you want to modify.
EDIT as a response to your code request:
I believe that there is a single place in your app where you update the badges on the tab bar items. Just add an array of tab bar items (or separate tab bar items) as a member(s) of that class (+ properties if needed) and update the items directly without fetching from the current tab bar items list ((UITabBarItem *)[stTabBarController.tabBar.items objectAtIndex:1];).
For instance, if you decide to keep references to the tab bar items directly (without an array) then the code might look like that:
// Put the next code right after initiating the tab bar and/or after adding new tab bar items to it...
self.newsTabBarItem = (UITabBarItem *)[stTabBarController.tabBar.items objectAtIndex:1];
self.friendsTabBarItem = (UITabBarItem *)[stTabBarController.tabBar.items objectAtIndex:2];
// etc.