0

I have such a problem: my application in background thread looking for new user messages on the server every second and if there is a new incoming message - app notifies user about it. (this logic for the message look up I have implemented in the app delegate).I have 9 views in the app each with a navigation bar and i want to display a label with new messages counter on this navigation bar (just an integer counter of new unread messages). The problem I don't know how to create a label and connect it with an app delegate. Here is an image of what I want: enter image description here

In the label there are 13 new messages for the user.And this button must be on all the 9 app's views.

First my idea was to create a UILabel in the AppDelegate file and then create UIBarButtonItem with customView. But how can I add this button on the navigation bar of each view in my application? (I also have other buttons on the navigationBar)

May be this question is little fuzzy but I hope experts will understand it.I really need a help with this.

MainstreamDeveloper00
  • 8,436
  • 15
  • 56
  • 102
  • Create a SuperViewController with this label as a property and make your 9 views inherit from it? – pmk Feb 04 '13 at 16:05
  • each navigation bar has to have different messages or they have to display the exact same message that you fetched in app delegate ? – SpaceDust__ Feb 04 '13 at 16:08
  • @pmk Can you explain it in more details? This label I must add on the bar, but if i write [barButtonItem initWithCustomView: label]. Will it display dynamic content which can change every second? – MainstreamDeveloper00 Feb 04 '13 at 16:09
  • @SpaceDust Each bar must display a label with new messages counter (counting happens in the appDelegate). – MainstreamDeveloper00 Feb 04 '13 at 16:10
  • @HarryCater your question is little bit confusing, it needs more explanation, so lets say I am in view 5 a new message arrived in to your app delegate , what happens then? what does counter do its just an integer? – SpaceDust__ Feb 04 '13 at 16:20
  • @SpaceDust Yes. It is just an integer counter." I am in view 5 a new message arrived in to your app delegate" then in the label appears number one and so on. If the user read this messages counter decrements. And the label just show counter integer value – MainstreamDeveloper00 Feb 04 '13 at 16:25

2 Answers2

2

If I understood your question right, One option is Singleton Design Pattern look at here for details.

So with singleton you will set a global instance then call it when you need it.

Right click your code and add a Objective-c class name it SingletonClass, make it sub class of NSObject

below example is integer change it to a string or any type if you want,

in your SingletonClass.h n your SingletonClass.h

#import <Foundation/Foundation.h>

@interface SingletonClass : NSObject

@property int thisIsCounter;

+ (SingletonClass *)sharedInstance;

@end

in your SingletonClass.m

#import "SingletonClass.h"


@implementation SingletonClass

@synthesize thisIsCounter=_thisIsCounter;

+ (SingletonClass *)sharedInstance
{
    static SingletonClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[SingletonClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

- (id)init {
    if (self = [super init]) {

        // set a singleton managed object , variable in your case
        _thisIsCounter=self.thisIsCounter;

    }
    return self;
}

@end

and import your singletonclass in your desired class in your case its all classes

#import "SingletonClass.h"
//in your app delegate when you fetch data increase singleton variable or decrease it if you want , basically you have a global variable that you can use in your all classes
-(IBAction)plus 
{

    SingletonClass *sharedInstance = [SingletonClass sharedInstance];
    sharedInstance.thisIsCounter =sharedInstance.thisIsCounter + 1;
}

Code is not tested , improved it as needed.

//Look at me now!!!!!

Above will set your global instance, now to call this in your viewcontroller every second (this is tricky because you may need to use main thread and it will get disturbed with UI events) you need :

How update a label periodically on iOS (every second)?

UILabel text not being updated

- (void)viewDidLoad
{
    [super viewDidLoad];
NSTimer* timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(updateLabel) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
-(void) updateLabel
{
   SingletonClass *sharedInstance = [SingletonClass sharedInstance];
   self.button.text= sharedInstance.thisIsCounter;

}
Community
  • 1
  • 1
SpaceDust__
  • 4,844
  • 4
  • 43
  • 82
  • Thanks.It's a great answer.And I'm glad you understand my question. But can you please explain these lines: dispatch_once(&onceToken, ^{ sharedInstance = [[SingletonClass alloc] init]; // Do any other initialisation stuff here }); return sharedInstance; – MainstreamDeveloper00 Feb 04 '13 at 17:24
  • The way we ensure that it’s only created once is by using the dispatch_once method from Grand Central Dispatch (GCD). This is thread safe and handled entirely by the OS for you so that you don’t have to worry about it at all. `// Do any other initialisation stuff here`, is just a comment so if you want to change safe thread to manual you should do some stuff there, thats entirely a new question. – SpaceDust__ Feb 04 '13 at 17:36
0

Correct me if I'm wrong, but I understand it like this:

Your AppDelegate Managess 9 ViewControllers. Each has its own NavigationBar. You Want every NavBar to have a UILabel with different text in it, the text comes from your AppDelegate.

My idea to achieve this would be to Create a new subclass from UIViewController, lets name it MySuperViewController: Header:

@interface MySuperViewController : UIViewController{
    UILabel *headerLabel;
}
@property(nonatomic, retain)UILabel *headerLabel;
@end

Implementation:

@implementation MySuperViewController
@synthesize headerLabel;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame, 44)];
        headerLabel.backgroundColor = [UIColor clearColor];
        headerLabel.numberOfLines = 2;
        headerLabel.font = [UIFont boldSystemFontOfSize: 14.0f];
        headerLabel.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
        headerLabel.textAlignment = UITextAlignmentCenter;
        headerLabel.textColor = [UIColor whiteColor];
        headerLabel.text = @"whatever";
        self.navigationItem.titleView = label;
    }
return self;
}
@end

Now you make your 9 Views (I hope thy are ViewControllers) inherit From your new class MySuperViewController:

#import "MySuperViewController.h"
@class MySuperViewController;

@interface YourView1 : MySuperViewController{ } and so on...

From your AppDelegate you now can access each of yourViewControllers headerLabel and set its text to whatever you like.

Note this code is not tested, so there might be mistakes in it.

EDIT: I just saw your update with the picture, of course you can do the same thing with your button.

Hope it helps!

pmk
  • 1,897
  • 2
  • 21
  • 34