I have a simple 3 page app, I can go from page 1 to page 2 swiping left.
However, when I am on page 2, I need to add the ability to go to either page 1 swiping right, or page 3 swiping left, but it just keeps crashing.
I suspect it may be a memory release issue, but I wonder if you could be so kind as to check the code below for any glaring errors?
Many thanks,
- (void)viewDidLoad {
UISwipeGestureRecognizer *swipeLeftRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[swipeLeftRight setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft )];
[self.view addGestureRecognizer:swipeLeftRight];
[UISwipeGestureRecognizer release];
}
- (IBAction)swipeLeftDetected:(UISwipeGestureRecognizer *)sender {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
Page3ViewController *UIViewController =
[[Page3ViewController alloc] initWithNibName:#"Page3ViewController~ipad" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
[Page2ViewController release];
}else{
Page3ViewController *UIViewController =
[[Page3ViewController alloc] initWithNibName:#"Page3ViewController" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
[Page2ViewController release];
}
}
- (IBAction)swipeRightDetected:(UISwipeGestureRecognizer *)sender {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
ViewController *UIViewController =
[[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
[Page2ViewController release];
}else{
ViewController *UIViewController =
[[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
ViewController *VC = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[self presentModalViewController:VC animated:YES];
[Page2ViewController release];
}
}
EDIT:
You need to implement a method called handleGesture: since that's the action you're passing in to the gesture recognizer.
Fixed, I found an older post by a person called rptwsthi, I used some of that to fix it;
Changed the viewDidLoad {
UISwipeGestureRecognizer *rightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(rightSwipeHandle:)];
rightRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[rightRecognizer setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:rightRecognizer];
[rightRecognizer release];
//........towards left Gesture recogniser for swiping.....//
UISwipeGestureRecognizer *leftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(leftSwipeHandle:)];
leftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[leftRecognizer setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:leftRecognizer];
[leftRecognizer release];
And using this to switch the pages;
- (void)rightSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
//Do moving
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
ViewController *UIViewController =
[[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
[Page2ViewController release];
}else{
ViewController *UIViewController =
[[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
ViewController *VC = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[self presentModalViewController:VC animated:YES];
[Page2ViewController release];
}
}
- (void)leftSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
// do moving
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
Page3ViewController *UIViewController =
[[Page3ViewController alloc] initWithNibName:#"Page3ViewController~ipad" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
}else{
Page3ViewController *UIViewController =
[[Page3ViewController alloc] initWithNibName:#"Page3ViewController" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
}
}
Not sure how neat it is in a true coders view, but it works, sometimes you just gotta go with what works right! :)
Related
When i click on back button then Im loading a particular view.But to that particular view I have to add a tabbarController.How can i do it..?When i try to add it doesnot get added..Couldnot understand y ?
-(IBAction)switchtofirst {
AppViewController *first=[[AppViewController alloc] initWithNibName:#"AppViewController" bundle:nil];
Login *second=[[Login alloc]initWithNibName:#"Login" bundle:nil];
second.title=#"Login";
NSArray *viewArray=[[NSArray alloc] initWithObjects: first,second,nil];
tabBarController=[[UITabBarController alloc] init];
[tabBarController setViewControllers:viewArray animated:NO];
AppViewController *gp=[AppViewController alloc];
[gp.view addSubview:tabBarController.view];
[self presentModalViewController:gp animated:NO];
[gp release];
}
Try something like this:
-(IBAction)switchtofirst {
AppViewController *first = [[AppViewController alloc] initWithNibName:#"AppViewController" bundle:nil];
Login *second=[[Login alloc]initWithNibName:#"Login" bundle:nil];
second.title=#"Login";
NSArray *viewArray= [NSArray arrayWithObjects:first, second, nil];
tabBarController=[[UITabBarController alloc] init];
[tabBarController setViewControllers:viewArray animated:NO];
[self presentViewController:tabBarController animated:YES completion:nil];
}
I need to access to parentViewController after presentMoalViewController.
This is my method that I call in the firstViewController to view the secondViewController:
- (void)viewData {
SecondViewController *viewCtrl = [self.storyboard instantiateViewControllerWithIdentifier:#"select_data"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewCtrl];
navigationController.navigationBar.barStyle = UIBarStyleBlack;
UIBarButtonItem *saveButton = [[[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:viewCtrl action:#selector(saveData)] autorelease];
viewCtrl.navigationItem.rightBarButtonItem = salvaButton;
UIBarButtonItem *undoButton = [[[UIBarButtonItem alloc] initWithTitle:#"Undo" style:UIBarButtonItemStyleBordered target:viewCtrl action:#selector(backView)] autorelease];
viewCtrl.navigationItem.leftBarButtonItem = annullaButton;
[self presentModalViewController:navigationController animated:YES];
}
When I click on saveButton, I try to access to parentViewController in this way, but it not work:
- (void) saveData {
FirstViewController *parentView = (FirstViewController*)[[self navigationController] presentingViewController];
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
It would be much better if you used a delegate/protocol in your second viewController that the first viewController could set itself as. You can find more info here Pass data back to the previous controller or simply doing a search. This design pattern is used virtually everywhere in iOS programming.
The big advantage is that then your second viewController becomes independent of whoever presented it, and can be easily reused. The technical term would be 'decoupling'.
Last time I did this I used notifications:
[[NSNotificationCenter defaultCenter] postNotificationName:#"saveData" object:dataString];
in your parent vc view didload:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(saveDataNow:) name:#"saveData" object:nil];
For navigationController you can declare a property called something like myController, then you have to initiate your navigationController like this:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewCtrl];
navigationController.navigationBar.barStyle = UIBarStyleBlack;
navigationController.myController = self;
UIBarButtonItem *saveButton = [[[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:viewCtrl action:#selector(saveData)] autorelease];
viewCtrl.navigationItem.rightBarButtonItem = salvaButton;
UIBarButtonItem *undoButton = [[[UIBarButtonItem alloc] initWithTitle:#"Undo" style:UIBarButtonItemStyleBordered target:viewCtrl action:#selector(backView)] autorelease];
viewCtrl.navigationItem.leftBarButtonItem = annullaButton;
[self presentModalViewController:navigationController animated:YES];
In your parentViewController Class you declare your Method
- (void) saveData {
FirstViewController *parentView = (FirstViewController*)[[self navigationController] presentingViewController];
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
In your navigationController you can then call [myController saveData];
This should work, if you have any questions, feel free to ask!
You can access your parent view controller using following-
- (void) saveData {
NSMutableArray *activeControllerArray = [self.navigationController.viewControllers mutableCopy];
FirstViewController *parentView;
for(int i = 0, i <[activeControllerArray count], i++) {
if([[activeControllerArray objectAtIndex:i] isKindOfClass:[FirstViewController class]) {
parentView= [activeViewController objectAtIndex:i];
break;
}
}
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
I have a UIImagePickerController, and while it's loading, I want to display a disclaimer in a modalView.
- (void) viewDidLoad
{
self.picker = [[UIImagePickerController alloc] init];
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
self.picker.delegate = self;
[self presentModalViewController:self.picker animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
DisclaimerController* disclaimer = [[DisclaimerController alloc] init]; // Loads the Xib inside the init method
UINavigationController* controller = [[UINavigationController alloc] initWithRootViewController:disclaimer];
[self.navigationController presentModalViewController:controller animated:YES];
}
But it doesn't shows up.
And I don't want to dismiss the picker while the disclaimer is showing or show it later, because there are some treatments that takes some time and the time the user reads the disclaimer would prevent him to wait too long after closing the disclaimer.
I would solve it using an AlertView.
But if you prefer using your method maybe this will do the trick
Try this:
- (void) showModalDisclaimer {
DisclaimerController* disclaimer = [[DisclaimerController alloc] init];
// Loads the Xib inside the init method
UINavigationController* controller = [[UINavigationController alloc]
initWithRootViewController:disclaimer];
[self.picker presentModalViewController:controller animated:YES];
// notice self.picker
}
- (void) viewDidLoad
{
self.picker = [[UIImagePickerController alloc] init];
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
self.picker.delegate = self;
[self presentModalViewController:self.picker animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO
withAnimation:UIStatusBarAnimationNone];
[self performSelector:#selector(showModalDisclaimer) withObject:nil afterDelay:0.1];
}
I'm using presentModalViewController to go from view controller to view controller. Right now the animations are up and down when it goes from one view to another. Can I change it to right and left? I did not see any settings for this in the method presentModalViewController
Ted
Try this before presenting the modal vc:
[sampleViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
// or..
// [sampleViewController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
// or..
// [sampleViewController setModalTransitionStyle:UIModalTransitionStylePartialCurl];
See the modalTransitionStyle Property of a UIViewController - Here are the Reference docs
You can make convenience methods for all styles like so (from Modal View Controller Example):
- (IBAction)showDefault:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[self presentModalViewController:sampleView animated:YES];
}
- (IBAction)showFlip:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[sampleView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:sampleView animated:YES];
}
- (IBAction)showDissolve:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:sampleView animated:YES];
}
- (IBAction)showCurl:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[sampleView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
[self presentModalViewController:sampleView animated:YES];
}
I have this code to present a popover:
- (UIPopoverController *)favoritesPopover
{
if (!favoritesPopover)
{
FavoritesViewController *fvc = [[FavoritesViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:fvc];
[fvc release];
favoritesPopover = [[UIPopoverController alloc] initWithContentViewController:navController];
[navController release];
favoritesPopover.delegate = self;
}
return favoritesPopover;
}
- (IBAction)toggleFavorites:(id)sender
{
if (!self.favoritesPopover.popoverVisible)
[self.favoritesPopoverpresentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
else
[self.favoritesPopover dismissPopoverAnimated:YES];
}
Now when didSelectRow is called in FavoritesViewController, I want the popover to be dismissed. I tried [self dismissPopoverAnimated: YES]; but that isn't recognized.
You need to get a reference to the popoverController in your FavoritesViewController. Setup a popoverController property in FavoritesViewController and then you should be able to dismiss it in the didSelectRow method.