How can I copy menu items in Xcode? - objective-c

So I'm making a web browsing app in Xcode for OS X, and right now I am working on history. I have a menu called history in my MainMenu.xib, and I was wondering if it would be possible to add a menu item (through coding) to that every time the user loads a new page. Any help would be great.

Something like this should work:
- (void)addHistoryItemWithTitle:(NSString *)title URL:(NSURL *)historyURL
NSMenuItem *menuItem = [[[NSMenuItem alloc] initWithTitle:title action:#selector(goToHistoryItem:) keyEquivalent:#""] autorelease];
menuItem.representedObject = historyURL;
//Note: You would normally have an outlet for your History menu or use
// itemWithTag:, so that it works in localized versions of your app.
NSMenuItem *historyMenuItem = [[NSApp mainMenu] itemWithTitle:#"History"];
[[historyMenuItem submenu] addItem:menuItem];
}
In your action you could then retrieve the URL (or some other object) that you set as the representedObject before:
- (void)goToHistoryItem:(id)sender
{
NSURL *historyURL = [sender representedObject];
NSLog(#"history item selected: %#", historyURL);
}

Related

NSMenuItem's not selectable after opening window

I'm having an issue very similar to this thread.
I am programatically creating a NSMenu and adding my items. One selection of an item it shows a window. This works as intended. However, when I close the window I can no longer select any of the options in the menu.
AppDelegate.m
- (void)createMenu {
NSMenu *statusMenu = [[NSMenu alloc] initWithTitle:#""];
NSMenuItem *historyItem = [[NSMenuItem alloc] initWithTitle:#"History" action:#selector(onHistory:) keyEquivalent:#""];
[statusMenu addItem:historyItem];
NSImage *statusImage = [NSImage imageNamed:#"icon.png"];
[_item setImage:statusImage];
[_item setMenu:statusMenu];
}
- (void)onHistory:(id)sender {
OBHistoryWindowController *historyWindowController = [[OBHistoryWindowController alloc] initWithWindowNibName:#"OBHistoryWindowController"];
historyWindowController.managedContext = self.managedObjectContext;
[historyWindowController showWindow];
}
OBHistoryWindowController.m
- (void)showWindow {
[NSApp runModalForWindow:self.window];
}
I'm guessing I need to somehow on close of the window give focus back to the menu but I can't for the life of me figure out how.
It sounds like you haven't stopped the modal loop. As the docs for runModalForWindow: say, "You can exit the modal loop by calling the stopModal, stopModalWithCode:, or abortModal methods from your modal window code."

add/hide UITabBarItem

I have a UITabBarController and would like to add a tab, with the ability to make it disappear. I added 2 tabs with XCode. You can add a third tab by program?
I know a command like:
[self setViewControllers: [NSArray arrayWithObjects: x1, nil] animated: NO];
You can retrieve the array that uses XCode to add a third view?
thanks
I can not load the view with the code. I created a view controller from the storyboard, when I try to load it from code I get a black screen, use this code:
ViewControllerA *x1 = [[ViewControllerA alloc] init];
[self setViewControllers:[NSArray arrayWithObjects: x1, nil] animated:NO];
Yes, if you use [UITabViewController setViewControllers: animated:] you can add in an array containing the two previous view controllers plus the new third one.
For example, you'd probably want to do it something like this:
// assuming you've set an IBOutlet to your tab bar controller
NSArray * currentSetOfViewControllers = [appTabBarController viewControllers];
if((currentSetOfViewControllers == NULL) || [currentSetOfViewControllers count] == 0))
{
NSLog( #"I don't see any view controllers; is my tab bar controller outlet set properly?")
} else {
NSMutableArray newSetOfViewControllers = [[NSMutableArray alloc] initWithArray: currentSetOfViewControllers];
if(newSetOfViewControllers)
{
ViewControllerA *x1 = [[ViewControllerA alloc] init];
if(x1)
{
[newSetOfViewControllers addObject: x1];
[appTabBarController setViewControllers: newSetOfViewControllers];
// release our alloc'd mutable array only if you do not have ARC turned on
[newSetOfViewControllers release];
}
}
}
You'd probably also want to give your new view controller an associated tab bar item with a title and an image. Check out [UITabBarItem initWithTitle: image: tag:].
I've linked the Apple documentation for you which I hope would help!
create a custom tab bar in delegate so create a view just like a tab bar and set 1 image view on view and 3 button (1 button set hidden) add this view in tab bar controller after that when u require 3rd button enable third button

Opening a new UIViewController when a link on a UIWebView is clicked

I found this thread which matches my problem: Clicking a link in UIWebView pushes onto the NavigationView stack
However, the following situations are different:
Instead of using a navigationController, I am using a View Based application to manually switch to different viewcontroller when corresponding buttons are pressed.
Rather than using links I am using onClick method to detect when a user clicks on something on a UIWebView and trying to open a new ViewController with a new UIWebView.
Will the same code work or do i have to make some changes?
You will have to do some modifications
1st:
when onClick, you will have to redirect your current page to a new location
This location for example will be MYLocation://GoThere
2nd:
Update the shouldStartLoadWithRequest
-(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
//Check if special link
if ( [ urlString isEqualToString: #"MYLocation://GoThere" ] ) {
//Here present the new view controller
MyViewController *controller = [[MyViewController alloc] init];
[self presentViewController:controller animated:YES];
return NO;
}
return YES;
}
I think you may use the shouldStartLoadWithRequest as Omar posted.
If the new viewcontroller has a webviewcontroller, then you should pass the url (or even the request) to the new viewcontroller to show the clicked URL.

UIImagePickerController - tapping the Album TableView or Selecting Album causes table to go blank? iOS5

I'm trying to reproduce a Similar Media Picker that is like the one in Pages. Within a UIPopoverController There is a UISegmentedControl that selects different media Types. One of the SegmentedControls I have is Labeled Images. I want to be able to select that Segment and have the view below present the ImagePicker.
I'm Close. I have a few issues. When presenting the VC, I get:
I get the Following in the Debugger:
UIStatusBarStyleBlackTranslucent is not available on this device. Not sure where that is coming from. I've tried with and without:
imagePicker.modalInPopover = YES;
imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
Though I still cannot get it to work Right. It Presents just fine. I see the UISegmentedControl I see my other Media Pages, I click the Image segment and I see the ImagePicker, Title is 'Photos' Has a Cancel Button I need to get rid of, and shows the two Albums I have on the device.
If I tap anywhere in the TableView (on an album or not), the two Albums go away. The NavBar and Cancel button are still there, though no Albums anymore. Tapping an Album Highlights the Row, though does not show the Images within the Album.
The other odd part of my code is that the Delegate for the Image Picker is the VC that Presented the UIPopoverController. Not sure if that plays into it. When I do hit the Cancel Button, I get:
-[PLUILibraryViewController performSelector:withObject:withObject:]: message sent to deallocated instance
Here is my Code to present the Picker.
- (void) setupImagePicker {
IoScreenEditorViewController * ioScreenEditorViewController = (IoScreenEditorViewController *)[UIAppDelegate.ioMainViewController currentViewController];
ioScreenEditorViewController.elementSelectedFromList = [elementsForPage objectAtIndex:0];
// Show an image picker to allow the user to choose a new photo.
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = ioScreenEditorViewController;
imagePicker.allowsEditing = NO;
NSArray * ourMediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, nil];
[imagePicker setMediaTypes: ourMediaTypes];
[ourMediaTypes release];
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
// imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
} else {
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[imagePicker.view setFrame:CGRectMake(0,0, 340, 500)]; // just for testing
//imagePicker.modalInPopover = YES;
//imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.view addSubview:imagePicker.view];
[imagePicker release];
}
I changed the class type that the Picker was being called from to a UIViewController and then altered the presentation code to look like this:
imagePicker.modalInPopover = YES;
imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:imagePicker animated:NO completion:^{ }];
I still get the Cancel Button, though the Image Picker does seem to be working like it should.
Although I was also as of yet unable to hide the Cancel button of the picker, I would suggest you revise how you are presenting it.
As an effort to get help from the community of iOS developers about this, I've made a sample project, please go and download it. In the project you can see that I am using view controller containment in order to get the picker on screen.
This may perhaps be a better way for you do do this too?
https://bitbucket.org/danielphillips/image-picker-demo

Save preference to show or hide NSStatusItem

I've got an application which runs as a normal app but also has a NSStausItem.
I wanted to implement the ability to set in the preferences a checkbox and when this checkbox is turned on the status item should be shown, but when the checkbox is off the status item should be removed or be invisible.
I found someone facing a similar problem in a forum here: How do you toggle the status item in the menubar on and off using a checkbox?
But the problem I have with this solution is that it does not work as expected. So I make this checkbox and all works fine, but when I open the application a second time the app does not recognize the choice I took at the first run. This is because the checkbox isn't bound to a BOOL or something, the checkbox only has an IBAction, which removes or adds the status item at runtime.
So my question is: how can I make a checkbox in the preferences which allows me to choose whether the status item should show up or not.
Ok actually i tried the following i copied the from the post i gave you the link
In AppDelegate.h :
NSStatusItem *item;
NSMenu *menu;
IBOutlet NSButton myStatusItemCheckbox;
and then in the Delegate.m :
- (BOOL)createStatusItem
{
NSStatusBar *bar = [NSStatusBar systemStatusBar];
//Replace NSVariableStatusItemLength with NSSquareStatusItemLength if you
//want the item to be square
item = [bar statusItemWithLength:NSVariableStatusItemLength];
if(!item)
return NO;
//As noted in the docs, the item must be retained as the receiver does not
//retain the item, so otherwise will be deallocated
[item retain];
//Set the properties of the item
[item setTitle:#"MenuItem"];
[item setHighlightMode:YES];
//If you want a menu to be shown when the user clicks on the item
[item setMenu:menu]; //Assuming 'menu' is a pointer to an NSMenu instance
return YES;
}
- (void)removeStatusItem
{
NSStatusBar *bar = [NSStatusBar systemStatusBar];
[bar removeStatusItem:item];
[item release];
}
- (IBAction)toggleStatusItem:(id)sender
{
BOOL checked = [sender state];
if(checked) {
BOOL createItem = [self createStatusItem];
if(!createItem) {
//Throw an error
[sender setState:NO];
}
}
else
[self removeStatusItem];
}
then in the IBaction i added this one :
[[NSUserDefaults standardUserDefaults] setInteger:[sender state]
forKey:#"MyApp_ShouldShowStatusItem"];
and in my awakefromnib i added this one : `
NSInteger statusItemState = [[NSUserDefaults standardUserDefaults] integerForKey:#"MyApp_ShouldShowStatusItem"];
[myStatusItemCheckbox setState:statusItemState];
Then in the interface builder i created a new checkbox connected it with "myStatusItemCheckbox" and added an IBaction also i clicked on the bindings inspector and set in the value the following bind to : NSUserDefaultController and as ModelKeyPath i set: MyApp_ShouldShowStatusItem.
Unfortunately this doesnt work at all what am i doing wrong ?
What you need to do is to use the User Defaults system. It makes it very easy to save and load preferences.
In the button's action, you will save its state:
- (IBAction)toggleStatusItem:(id)sender {
// Your existing code...
// A button's state is actually an NSInteger, not a BOOL, but
// you can save it that way if you prefer
[[NSUserDefaults standardUserDefaults] setInteger:[sender state]
forKey:#"MyApp_ShouldShowStatusItem"];
}
and in your app delegate's (or another appropriate object) awakeFromNib, you will read that value back out of the user defaults:
NSInteger statusItemState = [[NSUserDefaults standardUserDefaults] integerForKey:#"MyApp_ShouldShowStatusItem"];
[myStatusItemCheckbox setState:statusItemState];
and then make sure to call removeStatusItem if neccessary.
This procedure will apply to almost any preference you might want to save.