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

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];
}

Related

IOS 7 open modal view not centered

I have a really weird issue after updating my XCode project to Xcode 5 and IOS 7.
My project is a iPad project which open views for editing in modal mode.
After update all my Modal views stop being centered after focus on a textfield (or any input field for that matter)
I open all modal views like this:
if ([[segue identifier] isEqualToString:#"add_log"]) {
MemberAddLogViewController *vc = [segue destinationViewController];
vc.selfDelegate = self;
vc.member = self.member;
}
And the seque is created with Style = Modal, Presentation = Default, Transation = Default.
If i run it on a IOS6 Simulator the modal view keeps centered, but if a run it on a IOS7 simulator it "snaps" to the left or right after focus is set in a input field with:
[self.subject becomeFirstResponder];
Anybody else having this issue?
-- UPDATE ---
After hours of this bug annoying me i tried to "redo" the viewcontroller class, and by accident i added the becomeFirstResponder into viewDidLoad and not viewDidAppear and it fixed the issue.
I had similar problem in iOS 7 in landscape mode when I was porting app from iOS6 to iOS7, my UITableViewController was centered but when method becomeFirstResponder was called in viewDidAppear and keyboard showed up the view was moving to the left or right side of the screen depending on rotation direction.
The solution was interesting, I had to run it in main thread:
- (void)viewDidAppear:(BOOL)animated {
dispatch_async(dispatch_get_main_queue(), ^{
[textField becomeFirstResponder];
});
}
and everything is working now. That may help somebody, I was looking for solution in google for few days and did not find any proper solution.

Overriding NSWindowController

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.

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.

presentModalViewController gives a black screen

In an alert view method I implemented the following (pretty standard) piece of code for popping a modal view:
else if (buttonIndex == 1) {
EmergencyPlanViewController *emergencyPlanView = [[[EmergencyPlanViewController alloc] init] autorelease];
[emergencyPlanView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:emergencyPlanView animated:YES];
}
Somehow it gives me a black screen as result. I can't find what is wrong here.
I created the window in my MainStoryBoard and customized the class of the viewcontroller in IB to EmergencyPlanViewController.
The viewDidLoad method of the emergencyPlanView is triggered but it looks like the view is not loaded. Anyone an idea what's wrong here?
EDIT:
To be clear, I am not using seperate xib-files in my project. I only use the storyboard
In the xib file, is your UIView set to the File Owner's view. That is probably the problem. Also if you just apply init, that will load the EmergencyPlanViewControllerinterface builder file with the same name:
EmergencyPlanViewController.xib
So make sure in that case that either:
The EmergencyPlanViewController nib is indeed: EmergencyPlanViewController.xib
or that you write instead of init: initWithNibName://whatever nib name here
I managed to fix the black screen issue when presenting a modal view controller by setting a background color to the view in Interface Builder. I noticed that by default the background color of the view is set to something like black/white (see picture attached), although it appears in white. I don't know exactly what does this mean or how it is responsible for showing a black screen, but setting a single color or texture fixed it. PS: I've faced this when migrating from iOS SDK 5 to 6.
ios6
Try this:-
EmergencyPlanViewController *emergencyPlanView=[[EmergencyPlanViewController alloc] initWithNibName:#"EmergencyPlanViewController" bundle:nil];
emergencyPlanView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.navigationController presentModalViewController:emergencyPlanView animated:YES];

MKMapView not allowing user interaction on Ipod Touch OS 3.1.3, works correctly on simulator 3.2 / 4.0

I have been coding and testing an app which uses a navigation controller, tab bar and table views together as shown in this tutorial video:
I have also coded a MapView page which shows custom annotations. This seems to work fine in every version of the simulator I have tried it on. This morning I have finally got the app running on my Ipod Touch which runs OS 3.1.3 - everything works as expected except the map does not seem to allow user interaction at all. I cannot tap on annotations, the current location or move and zoom at all.
I have been through all the settings in the Interface Builder for the mapview, and made sure that all the 'User Interaction', 'Allow Multitouch' boxes have been ticked. This doesn't seem to change anything.
Any help greatly appreciated.
The Mapview is put into the view as follows:
// Grab the maps view controller ready for loading
MapView *childController = [[MapView alloc] initWithNibName:#"MapView" bundle:nil];
childController.title = #"View on Map";
// Push the new view controller onto the stack
[self.navigationController pushViewController:childController animated:YES];
[childController release];
childController = nil;
I've also tried running the view in a modal view controller just to see what would happen. The view was shown and any interaction didnt seem to work - with the exception of a small section at the bottom where I made the view itself slightly shorter so it would fit in above the tab bar. This section seems to have another map underneath my view which DOES respond to user interaction. So there is a 1cm or so block which does move - my view seems to stay static on top of it, though.
The view underneath does not appear to have any annotations or the current user location.
Ok I've solved this one:
In the mapview.m file where I set up the view and load the annotations, within the viewDidLoad function I had the following code:
- (void)viewDidLoad {
// More code before this..
[mapView addAnnotations: eventPoints];
// This is causing the problems on the ipod touch.
// The view is added ON TOP of the first map..
//[self.view addSubview:mapView];
self.view = mapView;
// More code after this..
}
Where mapView is
IBOutlet MKMapView *mapView;
Adding a subview on top of the current view didn't want to work. Actually setting the view to be the new updated view with annotations seems to work fine. It's still strange that the simulator would work and not the device in the first place though.
Hope this helps someone.