I am making IntroScreens for iOS app, Every thing is perfect but when I click next button it shows NSInvalidArgumentException error
pageContentViewController
- (IBAction)nextButtonTapped:(id)sender {
switch (self.pageIndex) {
case 0:
case 1:
pageViewController = ((PageViewController *)self.parentViewController);
[pageViewController forward:self.pageIndex];
break;
case 2:
[self performSegueWithIdentifier:#"LoginScreen" sender:nil];
break;
default:
break;
}
}
PageViewController
-(void)forward:(NSUInteger)index{
[self.pageViewController setViewControllers:#[[self viewControllerAtIndexArabic:index +1]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
reason: '-[UIPageViewController forward:]: unrecognized selector sent to instance 0x7fb2cf009600
The issue it with the following code block
pageViewController = ((PageViewController *)self.parentViewController);
I guess you have set your pageviewcontroller in storyboard which is an instance of UIPageViewController but in the code you are trying to access PageViewController ( which I guess is a third party controller ).
So you must change the class of your UIPageViewController in storyboard to PageViewController.
Related
In my app, I have a second view controller for another screen. This view controller has a close button that dimisses the view controller. On pressing this close button, the app crashes. It crashes with the following error:
*** Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'preferredInterfaceOrientationForPresentation must return a supported interface orientation!'
This is the method I use to close the view controller, in the second view controller's .m
- (IBAction)done {
[self dismissViewControllerAnimated:YES completion:nil];
//[self dismissModalViewControllerAnimated:YES];
}
The crash occurs at [self dismissViewControllerAnimated:YES completion:nil];
The second view controller is presented using this method in my main view controller:
-(IBAction)switchViews {
[self presentViewController:secondView animated:YES completion:nil];
//[self presentModalViewController:secondView animated:YES];
}
Code related to rotation in main view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskPortrait;
}
I haven't been able to resolve this issue. I've looked up that error and tried various solutions, but nothing has worked. Why is this crash happening? What am I doing wrong?
If you need more information, please let me know.
You are returning the wrong thing. The value it expects is UIInterfaceOrientationPortrait, but you're returning UIInterfaceOrientationMaskPortrait. Note the Mask part.
I have the main view controller and when the viewDidLoad the user is validated on login via Parse and Facebook:
if ([PFUser currentUser] == nil && [FBSDKAccessToken currentAccessToken] == nil) {
WelcomeViewController *welcomeController = [self.storyboard instantiateViewControllerWithIdentifier:#"Welcome"];
[self presentViewController:welcomeController animated:YES completion:nil];
}
When I try to push data from the welcome view controller I use self.presentingViewController:
MainFeedTableViewController *mc = (MainFeedTableViewController *)self.presentingViewController;
mc.username = self.fbUsername;
BUT
the compiler sees it as UINavigationController:
-[UINavigationController setUsername:]: unrecognized selector sent to instance 0x7f92b9009a00.
How is that possible when I am presenting with self of the MainFeedTableViewController?
When you call the [self presentViewController:welcomeController animated:YES completion:nil]; The presentation is done via UINavigationController (I am assuming you have a navigation controller in your application). What it does is presents the view inside its Navigation hierarchy you can use the following to get the MainFeedTableViewController if your MainFeedTableViewController is the first view in Hierarchy
MainFeedTableViewController * viewController = (MainFeedTableViewController*)[self.navigationController.viewControllers objectAtIndex:0];
If its not the first one and you want to use relative positioning you can do something like this
MainFeedTableViewController * viewController = (MainFeedTableViewController*)[self.navigationController.viewControllers objectAtIndex:
[self.navigationController.viewControllers indexOfObject:self ]- 1];
Which will first find the Index of self (WelcomeViewController) and then find the view in UINavigationController views array a view which is just behind this one.
I write code in IB action to check condition to switch view controller in same story board but if I touch button it go to black screen
this is my code
-(IBAction)Buyvoyage{
if (ck==1) {
NSLog(#"brought IAP");
VoyageplayViewController *voy = [[VoyageplayViewController alloc]init];
[self presentViewController:voy animated:YES completion:NULL];
}
}
try replacing
[self presentViewController:voy animated:YES completion:NULL];
with
** [self presentViewController:voy animated:YES completion:nil];**
However, i would prefer you to use seuge by following below steps.
1. Create segue from each UIButton to the corresponding UIViewControllers, set Segue identifier in IB by selecting the segue(s) you just created e.g. if you have 2 button then set identifier of the Segue "TestSegue1" and "TestSegue2" respectively.
2. Now create an IBaction for UIButton from which you want to navigate, and put below code in that IBAction
3. Remember to set Tag property in IB of all the UIButton(s) you want to perform navigation on as per your requirement
// When any of my buttons is pressed, push the next UIViewController using performSeugeWithIdentifier method
- (IBAction)buttonPressed:(UIButton*)sender
{
if (sender.tag==1) {
[self performSegueWithIdentifier:#"TestSegue1" sender:sender];
}
else if(sender.tag==2)
[self performSegueWithIdentifier:#"TestSegue2" sender:sender];
}
Or Use storyboard identifier to present your viewcontroller using below code
- (IBAction)buttonPressed:(UIButton*)sender
{
//Get StoryBoard Identifier using
UIStoryboard *storyboard = [self storyboard];
if(ck==1) {
VoyageplayViewController *voyVC = [storyboard instantiateViewControllerWithIdentifier:#"Voyage"];
[voyVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:voyVC animated:YES];
}
}
don't forget to set ViewController StoryBoard Id in StoryBoard -> identity inspector
I have an issue with MFMailComposeViewController when trying to implement from an NSObject class.
I have used MFMailComposeViewController numerous times without issue, but always within a View Controller.
However, in this case, I make a call to an NSObject Class which will run, whilst the user is normally on one ViewController. However, this code is run from a number of View Controllers, hence the use of the NSObject, and my need to allow the composer to present over ANY view controller.
The issue is that when complete, it needs to throw up an email composer, and I am unable to get this to work. Instead, it never launches the Mail Composer view.
I have the delegate in place, code follows, and the delegate is set within the .h.
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
if([MFMailComposeViewController canSendMail]){
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:toRecipents];
[[mc navigationBar] setTintColor: [UIColor whiteColor]]; // Text color
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
// NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
// NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
// NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
// NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self dismissViewControllerAnimated:YES completion:NULL];
}
I have also tried to shift the code to AppDelegate, and use a notification from the NSObject class to fire the composer, however, using this method I find that the composer WILL display over a pushed VC, but if a modal view is currently displaying, it does NOT display the composer.
Finally, I tried adding an entirely separate view controller, adding the mail composer to it, and adding this via AppDelegate, but this too will only display over a pushed VC, and not a modal VC.
My thinking is that I need to find the 'top' of the navigation stack, in order to display the composer above this, but I am not 100% sure.
I would welcome comments from anyone who is able to throw any light on how I can achieve this, as I feel sure it must be possible, as I AM able to add the MailController to a modal view if the code is within the View Controller itself, but clearly this would mean I would need to add such said code to multiple VC's, which, whilst I could, seems to be an odd way to have to proceed.
Thanks all!
I thought I would come back and answer this!
The MFMailComposeViewController must be launched within a ViewController. This is by design.
I am using a storyboard to switch between views. Pretty simple, until I try to add ECSlidingViewController.
If I add the above slide menu to the first view I call using this:
self.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Main"];
If I set #"Main" to #"Speakers", the view loads just fine. I get the slide menu and everything. #"Main" also loads just fine.
However, if I load #"Main" first like in the code above, then switch views to the one I've designated "Speakers", it crashes as soon as I try to call the slide menu with this code:
if(![self.slidingViewController.underLeftViewController isKindOfClass:[MenuViewController class]]) {
self.slidingViewController.underLeftViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Menu"];
}
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
I get a crash stating: * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
I have tried switching views numerous ways.
I've tried:
SpeakersView *second= [self.storyboard instantiateViewControllerWithIdentifier:#"Speakers"];
[self presentViewController:second animated:YES completion:nil];
I've tried:
SpeakersView *svc = [self.storyboard instantiateViewControllerWithIdentifier:#"Speakers"];
[self presentViewController:svc animated:YES completion:nil];
Each one works just fine if I don't call up the slide menu, but each causes a crash when I do add the slide gesture.
Ideas?
Okay, I figured it out. After a long, arduous experience, I figured it out.
So I've got numerous files (.m and .h for each):
InitViewController
MenuViewController
MainViewController
SpeakersView
The objective was to switch from MainViewController using a button not on the slide menu to SpeakersView, but doing it directly caused the slide menu to be null, as was pointed out by Phillip Mills.
Instead, I put this in InitViewController.h, right underneath #Interface:
#property (nonatomic, retain) NSString *location;
Then this under #implementation in InitViewController.m:
#synthesize location;
I originally had this under ViewDidLoad in InitViewController.m:
self.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Main"];
I changed it to this:
if([location length] == 0){location = #"Main";}
self.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:location];
That way if the variable was empty, it defaulted to #"Main".
Then in MainView.m, where I execute the code after pressing the button, I have this:
InitViewController *ini;
ini = [self.storyboard instantiateViewControllerWithIdentifier:#"Init"];
ini.location = #"Speakers";
And voilĂ , the view switches just fine to Speakers. More accurately, it switches to InitViewController which automatically switches to Speakers or whatever I set location to.
Thanks to everyone for your help.