NSMenuItem with custom view does not update - objective-c

I have a NSMenuItem with a custom view. However, when I want to update the first row in the menu it add the content as it is in the xib file, not as I set it.
My code:
AppDelegate.m:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
_helper = [[Helper alloc] init];
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
[statusItem setMenu:self.statusMenu];
[statusItem setTitle:#"GravAccount"];
[statusItem setHighlightMode:YES];
_gravatarLoader = [[GravatarLoader alloc] initWithTarget:self andHandle:#selector(setGravatarImage:)];
// Get email address
_email = [_helper getEmailAddress];
if (_email != nil)
{
[_gravatarLoader loadEmail:_email withSize:50.0];
}
}
- (void)setGravatarImage:(NSImage*)image
{
NSLog(#"Image loaded!");
GravatarMenuItem *menuItem = [[GravatarMenuItem alloc] initWithNibName:#"GravatarMenuItem" bundle:nil];
[menuItem.label setTitle:_email];
[menuItem.imageView setImage:image];
NSLog(#"Email: %#", _email);
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:#"" action:nil keyEquivalent:#""];
[item setView:menuItem.view];
[self.statusMenu removeItemAtIndex:0];
[self.statusMenu insertItem:item atIndex:0];
}
GravatarMenuItem.h:
#import <Cocoa/Cocoa.h>
#interface GravatarMenuItem : NSViewController
#property (nonatomic, strong) IBOutlet NSImageView *imageView;
#property (nonatomic, strong) IBOutlet NSTextFieldCell *label;
#end
The outlets are linked in the XIB file on the file's owner.
This is the result:
Log:
2012-03-09 16:57:24.314 appName[51158:403] Image loaded!
2012-03-09 16:57:24.316 appName[51158:403] Email: Paul#******.se
Result:

When you do:
GravatarMenuItem *menuItem = [[GravatarMenuItem alloc] initWithNibName:#"GravatarMenuItem" bundle:nil];
It only creates the view controller. It doesn't actually load the view from the nib. When you access the properties, they are most likely nil as the view has not been loaded (and the connections have not been made).
If you update your code to the following, everything should work fine:
GravatarMenuItem *menuItem = [[GravatarMenuItem alloc] initWithNibName:#"GravatarMenuItem" bundle:nil];
[menuItem view]; // load the view from the nib
[menuItem.label setTitle:_email];
[menuItem.imageView setImage:image];

Related

Submenu item isn't clickable

I want a dynamically submenu. Now I tried this way:
#interface AppController()
#property(strong) Accounts * accView;
#property (weak) IBOutlet NSMenuItem *serverMenu;
#end
#implementation AppController
-(void)awakeFromNib {
_accView = [[Accounts alloc] initWithNibName:#"Accounts" bundle:nil];
[self.viewk addSubview:[_accView view]];
[[_accView view] setFrame:self.viewk.bounds];
NSMenuItem * testItem = [[NSMenuItem alloc] initWithTitle:#"Test" action:#selector(test:) keyEquivalent:#""];
[[_serverMenu submenu] addItem:testItem];
}
- (void)test:(id)test {
}
Then it get's added but I can't click on it. It's like this:
How can enable it?
You also need to assign a target to your NSMenuItem, like
[testItem setTarget:self];

How can I reuse a UIView and methods - DRY code in iOS

I have 2 methods that add the Previous, Next & Done toolbar above the iOS Keyboard and handle these actions. I'm looking for a way to code these methods once and reuse it across multiple UITableViewControllers. (DRY Code)
I find myself copy and pasting these methods into each UITableViewController. If I make a small change, I have to copy and pastes that change everywhere. The code below is just an example, I seem to be repeating myself a lot in my code.
Here's an example of the code I'd like to reuse:
- (void) createInputAccessoryView
{
_inputAccView = [[UIView alloc] initWithFrame:CGRectMake(10,0,310,42)];
UIToolbar *keyboardToolbar = [[UIToolbar alloc] init];
keyboardToolbar.barStyle = UIBarStyleBlackTranslucent;
[keyboardToolbar sizeToFit];
_segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Previous", #"Next", nil]];
[_segmentedControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[_segmentedControl addTarget:self action:#selector(nextPrevious:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *nextPrevButton = [[UIBarButtonItem alloc] initWithCustomView:_segmentedControl];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(resignKeyboard)];
NSArray *barItems = [NSArray arrayWithObjects:nextPrevButton, flexSpace, doneBtn, nil];
[keyboardToolbar setItems:barItems];
[_inputAccView addSubview:keyboardToolbar];
}
- (void) nextPrevious:(id) sender
{
switch(_activeTxtField.tag) {
case 1:
//Recipe Name
if (_segmentedControl.selectedSegmentIndex == 1){
[_descriptionTextField becomeFirstResponder];
_activeTxtField = _descriptionTextField;
}
break;
case 2:
//Recipe Description
if (_segmentedControl.selectedSegmentIndex == 0){
[_nameTextField becomeFirstResponder];
_activeTxtField = _nameTextField;
}
default:
break;
}
}
Create a custom UIView that defines the common input accessory view. Should include a definition of a delegate to allow the class using the accessory view to handle, for example, previous/next button taps as appropriate. Here's a header file example for a keyboard accessory view:
#import <UIKit/UIKit.h>
#class KeyboardAccessoryView;
#protocol KeyboardAccessoryViewDelegate <NSObject>
-(void)accessoryNext:(id)sender;
-(void)accessoryPrevious:(id)sender;
#end
#interface InputAccessoryView : UIView
#property (nonatomic, weak) id<KeyboardAccessoryViewDelegate> delegate;
#property (nonatomic, setter = enablePrevious:) BOOL previousEnabled;
#property (nonatomic, setter = enableNext:) BOOL nextEnabled;
-(id)initPreviousNextAccessory;
#end
Edit - showing details of use in a UIViewController.
The .h file:
#import <UIKit/UIKit.h>
#import "KeyboardAccessoryView.h"
#interface MyViewController : UIViewController <KeyboardAccessoryViewDelegate>
//...
#end
The .m file:
#import "MyViewController.h"
#interface MyViewController () {
KeyboardAccessoryView *inputAccessoryView;
}
#end
#implementation MyViewController
//...
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
inputAccessoryView = [[KeyboardAccessoryView alloc] initPreviousNextAccessory];
inputAccessoryView.delegate = self;
//...
}
-(void)accessoryNext:(id)sender{
// handle Next
}
-(void)accessoryPrevious:(id)sender{
// handle Previous
}
//...
#end

ios tabbar customization with images

i'm working in ios application i need to customize tabbar to be like this
First I created 5 viewcontrollers each one in navigation controller
then put them in tabbbarcontroller
I googled for this problem and I found solution
[self.tabBarItem setFinishedSelectedImage:<#(UIImage *)#> withFinishedUnselectedImage:<#(UIImage *)#>]
but it is for iOS 5, I need solution for both iOS 4 and iOS 5.
For customizing tab bar in ios4 is not available with code for that you need to make us custom tab bar for that you can refer this Que.
How to Customize the tabbarcontroller
or you also can do like simple logic with making full tab bar image like this
here i have made one image view on appdel did finish method and done like this in the app.
self.imgV.frame=CGRectMake(0, 431, 320, 49);
[self.tabbarcontroller.view addSubview:self.imgV];
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
NSUInteger index=[[tabBarController viewControllers] indexOfObject:viewController];
NSString *deviceType = [UIDevice currentDevice].model;
NSLog(#"Device%#",deviceType);
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad){
// self.imgV.frame=CGRectMake(0, 975, 768, 49);
//[self.tabbarcontroller.view addSubview:self.imgV];
switch (index) {
case 0:
self.imgV.image=[UIImage imageNamed:#"reservation_tab~iPad.png"];
break;
case 1:
self.imgV.image=[UIImage imageNamed:#"place_order_tab~iPad.png"];
break;
case 2:
self.imgV.image=[UIImage imageNamed:#"location_tab~iPad.png"];
break;
case 3:
self.imgV.image=[UIImage imageNamed:#"favorite_tab~iPad.png"];
break;
case 4:
self.imgV.image=[UIImage imageNamed:#"signature_dishes_tab~iPad.png"];
break;
case 5:
self.imgV.image=[UIImage imageNamed:#"history_tab~iPad.png"];
break;
case 6:
self.imgV.image=[UIImage imageNamed:#"contact_us_tab~iPad.png"];
break;
default:
break;
}
}
else{
switch (index) {
case 0:
self.imgV.image=[UIImage imageNamed:#"reservation_tab.png"];
break;
case 1:
self.imgV.image=[UIImage imageNamed:#"place_order_tab.png"];
break;
case 2:
self.imgV.image=[UIImage imageNamed:#"location_tab.png"];
break;
case 3:
self.imgV.image=[UIImage imageNamed:#"favorite_tab.png"];
break;
case 4:
self.imgV.image=[UIImage imageNamed:#"gallery_tab.png"];
break;
default:
break;
}
}
return YES;
}
In the AppDelegate.m file, add the following code. In that piece of code, we are creating four views and adding them to a Tab Controller. These views are empty for now because we don’t need any content in them for the purposes of this project.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UITabBarController *tabController = [[UITabBarController alloc] init];
UIViewController *viewController1 = [[UIViewController alloc] init];
UIViewController *viewController2 = [[UIViewController alloc] init];
UIViewController *viewController3 = [[UIViewController alloc] init];
UIViewController *viewController4 = [[UIViewController alloc] init];
tabController.viewControllers = [NSArray arrayWithObjects:viewController1,
viewController2,
viewController3,
viewController4, nil];
self.window.rootViewController = tabController;
[self.window makeKeyAndVisible];
return YES;
}
You can see a good tutorial here
try this
paste it .h file
#import <UIKit/UIKit.h>
#class MapViewController,MenuViewController;
#interface UITabBar (ColorExtensions)
- (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur;
#end
#interface UITabBarItem (Private)
#property(retain, nonatomic) UIImage *selectedImage;
- (void)_updateView;
#end
#interface SegmentedControlExampleAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow * window;
UINavigationController * navigationController;
NSMutableArray *breads;
NSMutableArray *categorys;
NSMutableArray *collections;
NSString *databaseName;
NSString *databasePath;
MapViewController *mapViewController;
MenuViewController *wvTutorial;
}
#property (nonatomic, retain) IBOutlet UIWindow * window;
#property (nonatomic, retain) UINavigationController * navigationController;
#property (nonatomic,retain) NSMutableArray *breads;
#property (nonatomic,retain) NSMutableArray *categorys;
#property (nonatomic,retain) NSMutableArray *collections;
#property (nonatomic, retain) UITabBarController *tabBarController;
#property (nonatomic, retain) MenuViewController *wvTutorial;
#end
In .m file
#import "SegmentedControlExampleAppDelegate.h"
#import "SegmentManagingViewController.h"
#import "sqlite3.h"
#import "AtoZHomePageViewController.h"
#import "CategoryViewHomePage.h"
#import "CollectionsListHomePageViewController.h"
#import "AboutUs.h"
#import "StoreLocatorViewController.h"
#import "UINavigationBar+CustomImage.h"
#import "MenuViewController.h"
#implementation UITabBar (ColorExtensions)
- (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur
{
CGColorRef cgColor = [color CGColor];
CGColorRef cgShadowColor = [shadowColor CGColor];
for (UITabBarItem *item in [self items])
if ([item respondsToSelector:#selector(selectedImage)] &&
[item respondsToSelector:#selector(setSelectedImage:)] &&
[item respondsToSelector:#selector(_updateView)])
{
CGRect contextRect;
contextRect.origin.x = 0.0f;
contextRect.origin.y = 0.0f;
contextRect.size = [[item selectedImage] size];
// Retrieve source image and begin image context
UIImage *itemImage = [item image];
CGSize itemImageSize = [itemImage size];
CGPoint itemImagePosition;
itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) / 2);
UIGraphicsBeginImageContext(contextRect.size);
CGContextRef c = UIGraphicsGetCurrentContext();
// Setup shadow
CGContextSetShadowWithColor(c, shadowOffset, shadowBlur, cgShadowColor);
// Setup transparency layer and clip to mask
CGContextBeginTransparencyLayer(c, NULL);
CGContextScaleCTM(c, 1.0, -1.0);
CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [itemImage CGImage]);
// Fill and end the transparency layer
CGContextSetFillColorWithColor(c, cgColor);
contextRect.size.height = -contextRect.size.height;
CGContextFillRect(c, contextRect);
CGContextEndTransparencyLayer(c);
// Set selected image and end context
[item setSelectedImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
// Update the view
[item _updateView];
}
}
#end
#implementation SegmentedControlExampleAppDelegate
#synthesize window,tabBarController, navigationController,breads,categorys,collections,wvTutorial;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
databaseName = #"ProductsConnect_Master.sqlite";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
self.tabBarController = [[UITabBarController alloc] init];
UIViewController *viewController = [[AboutUs alloc] initWithNibName:#"AboutUs" bundle:nil];
UIViewController *viewController2 = [[StoreLocatorViewController alloc] initWithNibName:#"StoreLocatorViewController" bundle:nil];
//UIViewController *viewController3 = [[MenuViewController alloc] initWithNibName:#"MenuViewController" bundle:nil];
self.wvTutorial = [[MenuViewController alloc]initWithNibName:#"MenuViewController" bundle:nil];
SegmentManagingViewController * segmentManagingViewController = [[SegmentManagingViewController alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:segmentManagingViewController];
tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController,viewController ,viewController2,wvTutorial , nil];
[[UITabBar appearance]
setTintColor: [UIColor colorWithRed:120.0f/255.0f green:69.0f/255.0f blue:50.0f/255.0f alpha:1.0f]];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor colorWithRed:255.0f/255.0f green:252.0f/255.0f blue:235.0f/255.0f alpha:1.0f]];
//[[UITabBar appearance]
// setBackgroundColor: [UIColor colorWithRed:255.0f/255.0f green:252.0f/255.0f blue:235.0f/255.0f alpha:0.8f]];
navigationController.title = NSLocalizedString(#"HomePage", #"HomePage");
navigationController.tabBarItem.image = [UIImage imageNamed:#"logoSmall"];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
UIImage *navImage = [UIImage imageNamed:#"logoSmall.png"];
// self.navigationItem.setImage: navImage;
[[navigationController navigationBar] performSelectorInBackground:#selector(setBackgroundImage:) withObject:navImage];
// UIImage *navImage = [UIImage imageNamed:#"logoSmall.png"];
//[[navigationController navigationBar] performSelectorInBackground:#selector(setBackgroundImage:) withObject:navImage];
[self.window addSubview:tabBarController.view];
[segmentManagingViewController release];
//[window addSubview:self.navigationController.view];
[window makeKeyAndVisible];
return YES;
}
i have used this code working fine for me.

Transparent UITableView on top of several UIViewController and OpenGLView (Cocos2D)

Here is my code :
// View Controller with navigation bar
InAppPurchaseViewController *purchaseViewController = [[InAppPurchaseViewController alloc] init];
purchaseViewController.title = #"Magasin";
purchaseViewController.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissViewController:)] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:purchaseViewController] autorelease];
// Add `purchaseViewcontroller` TO container AND container ON openGLView
UIViewController *container = [[UIViewController alloc] init];
[container setView:[[CCDirector sharedDirector] openGLView]];
[container setModalTransitionStyle: UIModalTransitionStyleCoverVertical];
[container presentViewController:navController animated:YES completion:nil];
The UITableView is in purchaseViewController.
I was thinking of using [UIColor clearColor], BUT whatever I use it on I get a BLACK background on my UITableView. The cells get unselectable and unslidable (apart from the elements that are into the cells)
EDIT : The appdelegate
Here is the .h
#class AudioEngine;
#class RootViewController;
#class Score;
#interface AppDelegate : NSObject <UIApplicationDelegate, GameCenterManagerDelegate>
#property int CurrentPackage;
#property int CurrentScore;
#property int CurrentHighScore;
#property BOOL SoundShouldPlay;
#property BOOL PauseScreenUp;
#property(nonatomic, retain) AudioEngine *CustomAudioEngine;
#property(nonatomic, retain) GameCenterManager *CustomGameCenterManager;
#property(nonatomic, retain) UIWindow *window;
#property(nonatomic, readonly) RootViewController *ViewController;
#property(nonatomic, retain) NSString* CurrentLeaderBoard;
#property(nonatomic, retain) NSMutableArray *TenLastScoresArray;
+(AppDelegate *)get;
-(void)connectToGameCenter;
-(void)addScoreToLastScore:(Score*)score;
And the method did finish launching
-(void)applicationDidFinishLaunching:(UIApplication*)application
{
CC_DIRECTOR_INIT();
self.CurrentLeaderBoard = kLeaderboardID;
[[SKPaymentQueue defaultQueue] addTransactionObserver:[InAppPurchaseSingleton sharedHelper]];
[AudioEngine preloadBackgroundMusic];
[AudioEngine playBackgroundMusic:3];
self.SoundShouldPlay = YES;
[SceneManager goSplash];
}
Instead of presenting the view controller on container:
UIViewController *container = [[UIViewController alloc] init];
...
[container presentViewController:navController animated:YES completion:nil];
what should work is presenting it on the root view controller that the cocos2D template created for you. It is normally accessible through the app delegate:
UIViewController *rootViewController = (UIViewController*)[(YOURAPPDELEGATE*)[[UIApplication sharedApplication] delegate] viewController];
[rootViewController presentViewController:navController animated:YES completion:nil];
viewController is an ivar that the cocos2D default template add to the application delegate class. It is normally private, so you will need to define an accessor:
#property (nonatomic, readonly) RootViewController *viewController; //-- .h file
#synthesize viewController; //-- .m file
Hope this helps.
EDIT:
Based on what I have in my app delegate, I think you could try and instantiate the RootViewController like this:
CC_DIRECTOR_INIT
ViewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
ViewController.wantsFullScreenLayout = YES;
[ViewController setView:[[CCDirector sharedDirector] openGLView]];
...

UISwitch returns NULL?

I have a UISwitch that returns (null) for some reason. Below is my code:
AddAlbumViewController:
// .h
IBOutlet UISwitch *photostreamSwitch;
#property (nonatomic, retain) IBOutlet UISwitch *photostreamSwitch;
// .m
#synthesize photostreamSwitch;
photostreamSwitch = [[UISwitch alloc] init];
NSLog(#"photostreamSwitch: %#", photostreamSwitch); // returns a not-null value
SecondViewController:
//.m
- (IBAction)createAlbum:(id)sender {
AddAlbumViewController *addAlbumViewController = [[AddAlbumViewController alloc] initWithNibName:#"AddAlbum" bundle:[NSBundle mainBundle]];
NSLog(#"Test Switch: %#",addAlbumViewController.photostreamSwitch); // returns null
[addAlbumViewController release];
}
I think I have everything set up right. If this helps, AddAlbumViewController is inside a UINavigationController and SecondViewController contains the UINavigationController.
The view controller is created but its view (i.e. its nib) is not loaded yet, therefore the property isn't connected yet. You can force the nib to load by accessing the view member of the controller:
- (IBAction)createAlbum:(id)sender {
AddAlbumViewController *addAlbumViewController = [[AddAlbumViewController alloc] initWithNibName:#"AddAlbum" bundle:[NSBundle mainBundle]];
UIView* tempView = addAlbumViewController.view;
NSLog(#"Test Switch: %#",addAlbumViewController.photostreamSwitch); // no longer null
[addAlbumViewController release];
}