iPad Popover -[UIPopoverController initWithContentViewController: must not be called with `nil` - objective-c

I'm still working my way around the iOS SDK and I have another probably easy one for you.
I'm getting the following error when attempting to present a popover:
CoreAnimation: ignoring exception: -[UIPopoverController initWithContentViewController: must not be called with nil.
I thought I had put in code to deal with this, although apparently not. Anyway, code is below. Any thoughts on this would be great. Cheers!
if(popoverController == nil)
{
NSLog(#"is nil");
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverDownload];
}
popoverController.delegate = self;
[popoverController presentPopoverFromRect:CGRectMake(0,0,400,200) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
UPDATE
I guess I'm not initialising popoverDownload correctly/at all.
In my .h file
PopoverDownloadViewController *popoverDownload;
#property (nonatomic,retain) PopoverDownloadViewController *popoverDownload;
UPDATE WITH ANSWER
And it was as easy as...
PopoverDownloadViewController *popoverDownload = [[PopoverDownloadViewController alloc] init];

Just to mark this answer closed. I needed to initialise the popover using the following code...
PopoverDownloadViewController *popoverDownload = [[PopoverDownloadViewController alloc] init];
Thanks to omz for the hints in the right direction.

Related

UIRefreshControl without UITableViewController not calling selector

I have a UIViewController that has a UITableView as a subview. I am trying to add a pull-to-refresh on the table.
Following some examples and discussions that I found here, I have the UIRefresh showing but it never calls the selector. I am not getting notified that the pull action happened.
I cannot use a UITableViewController as my main controller as I need to add a fixed button at the bottom of the screen.
I have the feeling I am missing something out that hopefully is obvious to someone else.
#interface ActivityViewController ()<UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate>
#end
- (void)viewDidLoad{
[super viewDidLoad];
_myTableView.delegate = self;
_myTableView.dataSource = self;
_tableViewController = [UITableViewController new];
_tableViewController.tableView = _myTableView;
[self addChildViewController:_tableViewController]; // Not sure this is necessary
_refreshControl = [UIRefreshControl new];
[_refreshControl addTarget:self action:#selector(loadMoreData) forControlEvents:UIControlEventValueChanged];
_tableViewController.refreshControl = _refreshControl;
}
- (void)loadMoreData{
NSLog(#"loadMoreData");
}
Ok this is now working. But I am not sure why!! I kinda left it for a bit, changed other things that needed doing and then tested once more last night and it was working. I admit I am a bit confused. I used the code below from this answer given in earlier posts here as I did a few days ago. So thank you for the time and input. It works perfect now, as expected.
// Refresh control
UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.myTableView;
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(loadMoreData) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;
You should instantiate your tableviewcontroller with
[UITableViewController alloc] initWithStyle:(UITableViewStyle)
using new does an alloc init but you should use a designated initializer

MFMailComposeViewController dismisses right away

The situation is the MFMailComposeViewController was going to be presented. I saw it was presented half-way done, but then it got dismissed.
This is the error:
_serviceViewControllerReady:error: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "The operation couldn’t be completed. (_UIViewServiceInterfaceErrorDomain error 3.)"
This is my source code to present the MFMailComposeViewController:
-(void) MailExecute {
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:NSLocalizedString(#"Check this new look", #"")];
[mailViewController setMessageBody: #"my new look" isHTML:YES];
[self presentModalViewController:mailViewController animated:YES];
[mailViewController release];
}
else
{
UIAlertView *alertInternal = [[UIAlertView alloc]
initWithTitle: NSLocalizedString(#"Notification", #"")
message: NSLocalizedString(#"You have not configured your e-mail client.", #"")
delegate: nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil];
[alertInternal show];
[alertInternal release];
}
}
The weird point is that sometimes it happens, sometimes it doesn't.
Please help me on this! I spend almost 1 working day to resolve this but no succeed.
This problem can occur when displaying a remote view controller -- a view controller run in another process -- as indicated by the UIViewService reference in the error message.
I've had this problem when displaying an SKStoreProductViewController, which is also a remote view controller. I'm not sure what the root cause is; the only thing that seemed to trigger it for me was presenting the view controller repeatedly.
For the SKStoreProductViewController I was able to check for this error in the completion block of the loadProductWithParameters:completionBlock: method. Does the MFMailComposeViewControllerDelegate give you a callback with an error about this? It may be that all you can do is listen for this error and show an error message to the user.
We should both probably file an apple radar about this.
Your code looks correct, and as stated the error message strongly suggests this has something to do with UIView proper (not MFMail specifically). The problem almost surely lies somewhere elsewhere within your code, and might be challenging to troubleshoot.
Some things to look for:
Other animations or view controller transitions/dismissals happening simultaneously or incorrectly (possibly like this)
Release/retain issues, of course
If none of that seems like the fix, try commenting-out everything else happening in the view controller that calls this method and see if it works then.
If you still can't get it working, present the simplest version you can of failing code so we can troubleshoot further. :)
Do you have anything in your viewDidDisappear: or viewWillDisappear methods that would dismiss a view controller?
If not, can you post more of your code for the ViewController that presents the MFMailComposeViewController?
I know this is the late reply, but may be help some other.
Just now face the same problem, By resetting the simulator work fine for me for this same issue. Let me know if this helps.
After I stored the MFMailComposeViewController in a strong property of my class instead of a local variable I could not reproduce the self-dismissing behaviour any more.
The issue for me was an incorrect argument when calling the attachment function. If you are having this issue with an email attachment I suggest following the solution found in this thread, as follows:
NSString *path = [self getDatabaseFilePath];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:#"application/x-sqlite3" fileName:[path lastPathComponent]];
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc]init];
if ([MFMailComposeViewController canSendMail])
{
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:[NSArray arrayWithObject:#"support#kapsie.com"] ];
[mailComposer setSubject:#"Kapsie App Contact Support"];
[mailComposer setMessageBody:#"Type Your Feedback message here" isHTML:NO];
[self presentViewController:mailComposer animated:YES completion:nil];
}
Use above code and check it on device.
Use of modelViewController is deprecated in iOS 6 ,
use
[self presentViewController:mailView animated:YES completion:nil];
I face the same problem and the solution was:
I delete the overall application appearence related code like
[[UILabel appearance]setText:#""]
and replace with the code
[[UILabel appearanceWhenContainedIn:[self class], nil] setText:#""];
Now it is working fine so be carefull on overall application appearence changes: it might be navigationbar appearance, so and so

Two UIPopovers in One View

I am trying to put two different UIPopovers in one view. I'm fairly new to objective-c, and programming in general, so instead of doing the smart, efficient method of having one popover and changing it's contents depending on how it is called, I just used the stupid, simple method of just creating two views, two delegates, two popovers etc... I don't know if that's why I'm having a problem, or if it's for some other reason.
So here's the problem. In the viewdidload of the view where the popovers appear, I have this code:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
optionsViewController =[[OptionsViewController alloc]init];
optionsViewController.delegate = self;
popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
popoverController.popoverContentSize = CGSizeMake(320, 216);
[popoverController setDelegate:self];
newCurrencyViewController =[[newCurrencyViewController alloc]init];
newCurrencyViewController.delegate = self;
newCurrencyPopoverController = [[UIPopoverController alloc] initWithContentViewController:newCurrencyViewController];
newCurrencyPopoverController.popoverContentSize = CGSizeMake(320, 216);
[newCurrencyPopoverController setDelegate:self];
}
Obviously optionsViewController is the vc that appears inside popover 1 (with popover controller called "popoverController"), and newCurrencyViewController is the vc that appears inside popover 2 (with popover controller called "newCurrencyPopoverController").
Every time the view loads, the app crashes with a SIGABRT error, and the console says:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController initWithContentViewController:] must not be called with `nil`.'
Also, there's a warning saying "instance method -alloc not found (return type defaults to id)" for the line that
saysnewCurrencyViewController =[[newCurrencyViewController alloc]init];
My first thought was that I had misspelled the name of a file somewhere, since I think the problem is that it isn't finding the file called newCurrencyPopoverController, but I've checked everything and can't find any misspellings or anything. Any ideas?
Thanks very much!
LUKE
You are calling methods alloc + init of your variable newCurrencyViewController but you should call them to the class of that variable!
Line with bug:
newCurrencyViewController =[[newCurrencyViewController alloc]init];
The result of this line will be newCurrencyViewController == nil. And when you will try to init UIPopoverController with that view it will crash as you described.
If variable newCurrencyViewController is of class, for example, CurrencyViewController then you should replace that line with this one:
newCurrencyViewController =[[CurrencyViewController alloc] init];
you dont have an object to call alloc and init on when you are calling newCurrenceViewController.
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
optionsViewController =[[OptionsViewController alloc]init];
optionsViewController.delegate = self;
popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
popoverController.popoverContentSize = CGSizeMake(320, 216);
[popoverController setDelegate:self];
//Here is your problem---------------------------------------------
newCurrencyViewController =[[newCurrencyViewController alloc]init];
//-----------------------------------------------------------------
newCurrencyViewController.delegate = self;
newCurrencyPopoverController = [[UIPopoverController alloc] initWithContentViewController:newCurrencyViewController];
newCurrencyPopoverController.popoverContentSize = CGSizeMake(320, 216);
[newCurrencyPopoverController setDelegate:self];
}
you probably want something more like
newCurrencyViewController = [[UICurrencyViewController alloc] init];
Or w/e the name of your custom view controller is

UITabbarcontroller in IOS5 throws UIViewControllerHierarchyInconsistency exception

I have the following code for the UITabbarcontroller:
NSMutableArray *arr = [[NSMutableArray alloc] init];
tabBarController = [[UITabBarController alloc] init];
FirstViewController *firstview = [[FirstViewController alloc] init];
[tabBarControllerViews addObject:firstview];
[firstview release];
SecondViewController *secondview = [[SecondViewController alloc] init];
[tabBarControllerViews addObject:secondview];
[secondview release];
[tabBarController setViewControllers:arr animated:YES];
[arr release];
self.view = tabBarController.view;
This code runs fine on IOS4. I tried it on IOS5 beta and get the following error when tapping on a UITabbarItem:
*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency',
reason: 'child view controller:<FirstViewController: 0x6e03be0> should have parent view
controller:<MainViewController: 0x6816d20> but actual parent is:<UITabBarController: 0x6b0c110>'
replace:
self.view = tabBarController.view;
with:
[self.view addSubview:tabBarController.view];
This will also be backwards compatible with IOS3&4.
Had the same pattern (and problem) in my code. Joe's solution didn't work for me. Looking at the snippet, I'm guessing that you derive a class from UIViewController to allow you to customize something.
The thing to do here, and it is quite simple, is to derive from UITabBarController rather than UIViewController, don't create tabBarController, and anywhere you reference tabBarController, substitute self.
5 minutes and you're no longer throwing the inconsistency exception and you remain backwards compatible with iOS 4. You can still do all of your customization in your derived class (monkeying with the nav controller, etc).
If you have built a complex derivation of UIViewController you need to use, this could be more work.
One small gotcha - if you override LoadView, you'll find that it gets called during the init for the UITabBarController. Makes it hard to set members prior to LoadView, so you may need to split up your initialization.
Good luck!
You cannot push or present a UITabbarViewController. Is your First View Controller a UITabBarController ?
I struggled with the same problem.
When you create a new Master-Detail Application(without story board), you can see this codes below from AppDelegate.m.
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
"BE NOT DEPENDENT ON MainWindow"
Just start from your own ViewController and set it to delegate.
And don't forget to unlink view from MainWindow.xib else the view will called 2 times.

How do I use UIImagePickerController just to display the camera and not take a picture?

I'd like to know how to open the camera inside of a pre-defined frame (not the entire screen). When the view loads, I have a box, and inside it, I want to display what the camera sees. I don't want to snap a picture, just basically use the camera as a viewfinder. I have searched this site and have not yet found what I'm looking for. Please help.
Thanks!
Thomas
Update 1:
Here is what I have tried so far.
1.) I added UIImageView to my xib.
2.) Connect the following outlet to the UIImageView in IB
IBOutlet UIImageView *cameraWindow;
3.) I put the following code in viewWillAppear
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
NSLog(#"viewWillAppear ran");
}
But this method does not run, as evident by the absence of NSLog statement from my console. Please help!
Thanks,
Thomas
Update 2:
OK I got it to run by putting the code in viewDidLoad but my camera still doesn't show up...any suggestions? Anyone....? I've been reading the UIImagePickerController class reference, but am kinda unsure how to make sense of it. I'm still learning iPhone, so it's a bit of a struggle. Please help!
- (void)viewDidLoad
{
[super viewDidLoad];
// Create a bool variable "camera" and call isSourceTypeAvailable to see if camera exists on device
BOOL camera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
// If there is a camera, then display the world throught the viewfinder
if(camera)
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// Since I'm not actually taking a picture, is a delegate function necessary?
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
NSLog(#"Camera is available");
}
// Otherwise, do nothing.
else
NSLog(#"No camera available");
}
Thanks!
Thomas
Update 3:
A-HA! Found this on the Apple Class Reference.
Discussion
The delegate receives notifications
when the user picks an image or movie,
or exits the picker interface. The
delegate also decides when to dismiss
the picker interface, so you must
provide a delegate to use a picker. If
this property is nil, the picker is
dismissed immediately if you try to
show it.
Gonna play around with the delegate now. Then I'm going to read on wtf a delegate is. Backwards? Whatever :-p
Update 4:
The two delegate functions for the class are
– imagePickerController:didFinishPickingMediaWithInfo:
– imagePickerControllerDidCancel:
and since I don't actually want to pick an image or give the user the option to cancel, I am just defining the methods. They should never run though....I think.
add
[picker
dismissModelViewControllerAnimated:YES];
to delegate method bodies.
It will dismiss the view.