Overriding NSWindowController - objective-c

Got a small question, i'm busy creating an OSX application. In my first view (appdelegate) i got a login screen, but after the users logged in i want (flip the logincontroller (main.xib) to remove the login screen and open a new NSWindowcontroller.
What is the best way to do that? I tried;
Second = [[SecondController alloc] initWithWindowNibName:#"SecondController"];
[[Second window] makeFirstResponder:nil];
But now the second controller appears but the first controller stays. In iOS development i'm doing (want the same thing but than for OSX)
CategoriesViewController *tableController = [CategoriesViewController alloc];
tableController.managedObjectContext = [self managedObjectContext];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];

Carmin is correct but you could do
[Yourwindow close:nil];

Each window controller controls one window. You have two window controllers. You have two windows. iOS only displays one window at a time where OSX displays multiple windows at a time. You need to NSWindow-close the login window to make it disappear. You may also desire to release the login window if the NSWindow-releasedWhenClosed property is not set.

Related

FullScreen Loading View didn't work

I have been working on a fullscreen loading view for my apps, but it can't block any user interaction. The way I implement it is like this:
Create a singleton object - LoadingView
Call [LoadingView show] - add the loading view to [[[UIApplication sharedApplication] delegate] window]
So I want to ask :
Is my concept wrong?
Are there any method calls that can disable all user interaction to my apps?
Is there another better way to do this? (I prefer knowing about the principle inside than just using others' libraries)
Thanks
I use such way to block user interaction:
create UIView with window frame
set view's user interaction enabled to true
(optional) add UIActivityIndicator to view
add view to window subviews
when I need to show it I set hidden to NO and use bringSubviewToFront function to show loading view
when I don't need it I set hidden to YES and use sendSubviewToBack
id application = [[UIApplication sharedApplication] delegate];
UIView *loadingView = [[UIView alloc] initWithFrame:[[application window] frame]];
loadingView.userInteractionEnabled = YES;
loadingView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
[[application window] addSubview:loadingView];
Are you wanting to create a splash screen when the application starts? If so, all you need to do is add an image file called Default.png and/or Default#2x.png (for retina displays) to your project. This image will work as a splash screen for when the app launches.
You can also control the splash screen info.plist file.
Read more about the iOS launch screen here.

Why is my UIActionSheet hidden by my TabBarController?

I am having a problem correctly implementing a UIActionSheet in an iPad 5.1 (XCode 4.3) project. I can populate it correctly with all the items I need. The list is longer than the window, but the scrollbars automatically come up, etc. However, the cancel button (which I presume is supposed to be at the end) is coming up half hidden behind my tab bar. Shown below:
(sorry, SO won't let me post images yet)
Here is my storyboard setup:
The entry point is that Tab Bar Controller on the left, which goes to another Navigation Controller (center), which has the View Controller on the right as the root view.
http://i854.photobucket.com/albums/ab103/srVincentVega/ScreenShot2012-06-28at52713PM.png
I have tried presenting the UIActionSheet in all sorts of ways, but this odd behavior persists, and I can't figure out how to address it
- (IBAction)cmdReason:(id)sender
{
NSArray *reasons = [AppState getInspReasons];
UIActionSheet *action = [[UIActionSheet alloc]
initWithTitle:#"Reason for Inspection"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (NSString *rsn in reasons)
{
[action addButtonWithTitle:rsn];
}
[action showInView:self.view];
}
I have tried the various methods to show "action" - showFromTabBar, showFromToolbar, etc - I am VERY new to this development environment, so I am not up to speed yet on how these items interact at this level. Does anyone have a suggestion for how I can present this correctly?
I am sorry if this has already been asked elsewhere. I have spent all day trying bits of code from all over the web, including SO. I don't know if it's something to do with my storyboard layout, or what.
One further thing - when I rotate the emulator, the action sheet does redraw, but the bit at the end there gets wonky looking, like it can no longer figure out how to draw it.
Many thanks!
EDIT:
I have put together a very small project that demonstrates this exact behavior. I don't have a good way to host the zip file, so I put on google docs and shared it. The link is below. If you click on that, there should be a download option under file that will give you the original zip file.
https://docs.google.com/open?id=0B7IYvy9_c_NLaEFneGc5bzc2S2c
Seems like there is not a real solution for this. It looks like it's a limitation with UIActionSheet if you add that amount of button titles and present that from a tab bar.
Beside that, the proper way to display an UIActionSheet from a tab bar is to use
[action showFromTabBar:self.tabBarController.tabBar];
instead of
// Taken from your example project
AppDelegate *d = [[UIApplication sharedApplication] delegate];
UIWindow *w = d.window;
UIViewController *vc = w.rootViewController;
UITabBarController *c = (UITabBarController *)vc;
UITabBar *t = c.tabBar;
[action showFromTabBar:t];
I would think if you got a reference to the tab bar controller then you should be able to present it from that. You can try showing it from the main window but I would think you shouldn't rely on that.
[action showInView:[[UIApplication sharedApplication] keyWindow]];
Try this:
CGRect r = CGRectMake(x, y, w, h); //change values to fit location of button
[actionSheet showFromRect:r inView:self.view animated:YES];
I used it on one of my apps with the same problem and the dismiss button showed up ok.

UIDocumentInteractionController: "Open In" visible on iPhone but not on iPad - why?

For testing purposes I wrote two apps:
First one plays an MP3 file using UIDocumentInteractionController
Second one does nothing but registers for the file type "public.mp3"
If I deploy the apps to the iPhone Simulator, my MP3 player app shows a button on top "Open in 'MP3Test'". If I deploy to the iPad Simulator however, there is no button and no "Open In" menu either.
This has been tested with iOS5.
Can somebody explain if this is a bug or a feature and what the reason is behind it?
Depends upon where you are presenting it from.
If you are presenting it from somewhere around the middle of the screen or below, just present from the frame of the object that you are presenting from.
if that is on the navigation bar, try this:
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:#"License" ofType:#"pdf"];
UIDocumentInteractionController *controller = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
controller.delegate = self;
CGRect navRect = self.navigationController.navigationBar.frame;
navRect.size = CGSizeMake(1500.0f, 40.0f);
[controller presentOptionsMenuFromRect:navRect inView:self.view animated:YES];
The iPad has an affinity for popovers (see UIPopover), why it presents UIActionSheets in them. Facing a similar issue that you had, I had my UIDocumentInteractionController present itself from an UIBarButtonItem (resulting in a UIPopover presentation), rather than from the view itself (something that worked just fine on the iPhone):
Save a reference to the action button (I have mine in my navigation bar).
Use PresentOpenInMenu using the action button reference, rather than the View reference, resulting in a UIPopover-presentation.
Please note that the change does not effect the iPhone app - it behaves likes before, i.e. opens the OpenInMenu from the bottom of the screen just as it would, if you'd used the View reference to present it.
On iPad UIDocumentInteractionController appearing like Pop Up Try something like this
-(void)shareClick:(UIButton*)sender {
/*some code*/
CGRect rectFor appearing = [sender.superview convertRect:sender.frame toView:self.view];
[interactionController presentOptionsMenuFromRect:rect inView:self.view animated:YES];
}

Showing a different XIB/NIB in an iOS app

I have multiple nib (xib) files and I want the user to see a different one when they tap a button. What I am looking for:
- (IBAction)buttonTap {
//Code for showing a different nib goes here
}
I can't figure out how to do this. I can show a different view within the nib file just fine, but I can't get it to show a different nib. How do I show a different nib when the user taps a button?
Any help is appreciated! Thanks!
The way I handle switching between actual xib's, and I'm sure there are a multitude of ways to accomplish the same thing, is to have my App Delegate act as a routing center between my views.
I subscribe my App Delegate to recieve events from button presses for existing views. When it recieves a request to switch views, such as a button press, I do something like this:
- (void) showLogin
{
LoginViewController *loginViewController = [[LoginViewController alloc]
initWithNibName:#"LoginViewController" bundle:nil];
// Show
self.loginViewController = loginViewController;
[loginViewController release];
self.window.rootViewController = self.loginViewController;
}
I set my rootViewController to the view I am attempting to display. It doesn't release the old controller, but simply replaces the view being displayed. You can place more logic in to determine if it's already displayed, close out other views, etc. In most simplistic terms, this works for me.

iPhone 3.0 SDK: stacked presentModalViewController calls or in series?

Here's the scenario: if this is a user's first time logging into my web service, I present a modal login view. Upon success, the user may have multiple items in his/her account and must choose one of them before he/she can proceed with the rest of the app.
I want to put up another modal view with a picker so the user can make the choice.
All the examples I've seen of multiple modals presented are canned ones (like the email composer modal, with the people picker modal coming up over it), which is of no use because the code isn't available.
When I try putting up the login modal, then dismissing it, then presenting the picker, I get a recursion somewhere with a selector being sent to subviews being sent to subviews being sent to ....
Can anyone point me to some sample code?
I'm keeping a reference to the login view, so I figured I'd just pose the stack (well, two) modal views, then dismiss the login modal and they'd all go away (like the documentation says), but I can't seem to get this going.
Thanks in advance.
I have found that I could do this, but had to eliminate animation on the first dismiss, iff I was using animation on the 2nd presentModalViewController
ContactsViewController* controller = [[ContactsViewController alloc] ...
UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[self.navigationController presentModalViewController:navigationController animated:YES];
[controller release], controller = nil;
and then in my delegate method that is being called from the initial modal view
[self.navigationController dismissModalViewControllerAnimated:NO]; // dismiss without animation
[self.navigationController presentModalViewController:anotherViewController animated:YES];
This behavior was observed on OS 3.0.1.