I have to navigate to next screen on button click using segue,but the condition is i call a web service ,if the result from web service is SUCCESS it should navigate else stay in the loginscreen. But using the below code it simply navigates ..
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"loginbutton"])
{
[self.sharedController setLoginDetailsDyanamic1:_strUsername.text password:_strPassword.text delegate:self];
if ([[dictresult objectForKey:#"Response"] isEqual: #"Success"])
{
DashBoardViewController *obj = [[DashBoardViewController alloc]init];
[self.navigationController pushViewController:obj animated:YES];
}
}
}
//delegates
-(void)controllerDidFinishLoadingWithResult:(id)result;
{
dictresult = result;
NSLog(#" result ----- :%#",dictresult);
NSLog(#" result of key----- :%#",[dictresult objectForKey:#"Response"]);
// if ([[result objectForKey:#"Response"] isEqual: #"Success"])
// {
// DashBoardViewController *obj = [[DashBoardViewController alloc]init];
// [self.navigationController pushViewController:obj animated:YES];
//
// }
}
-(void)controllerDidFailLoadingWithError:(NSError*)error;
{}
The result that i get in -(void)controllerDidFinishLoadingWithResult:(id)result is:
result ----- :{
Response = Success;
Token = 2e8c0ef66a5ac15b8f61da080c26d056218a6172;
errorCode = 0; }
How do i manage this? I have wired my button with the next view.
You have to set a Segue Identity on your storyboard then use this line of code to Segue to the next view controller.
[self performSegueWithIdentifier:#"SegueIdentity" sender:self];
Related
There are five controllers here, AViewController, BViewController, CViewController,DViewController,EViewController,controllers here,
A present---> B
B present---> C
C push--->D
D push--->E
Now, if I want to go back from EViewController to AViewController in one step, what code should I write?
[self.navigationController popToRootViewControllerAnimated:animated];
1) Getting the desirable ViewController as Below
for (id controller in [self.navigationController viewControllers])
{
if ([controller isKindOfClass:[AViewController class]])
{
[self.navigationController popToViewController:controller animated:YES];
break;
}
}
2) Here you have A,B,C,D,E Controllers. means A would be on 1 Position so what can you do
you can hard wired the Index as Below
[self.navigationController popToViewController:[[self.navigationController viewControllers] objectAtIndex:0] animated:YES];
3) Pop to the first viewController or rootViewController
[self.navigationController popToRootViewControllerAnimated:animated];
Use unwind segues.
In AViewController add bellow code
-(IBAction)prepareForUnwind:(UIStoryboardSegue *)segue {
}
Go to User Interface of EViewController and Ctrl-drag from the button (you want set action) to the “Exit” outlet, you will see a modal popup.
You can do it recursively with generic solution. First of all you should have reference to A's navigation controller and then you should write recursive method to get active navigation controller like :`
-(UINavigationController*)getActiveNavigationController : (UINavigationController*)navigationController {
if ([navigationController.presentedViewController isKindOfClass:[AViewController class]]) {
return [self getActiveNavigationController:(UINavigationController*)((AViewController*)navigationController.presentedViewController)
];
}
if ((UINavigationController*)navigationController.presentedViewController == nil) {
return navigationController;
}
return [self getActiveNavigationController:(UINavigationController*)navigationController.presentedViewController];
}
`
After that you should write method like
-(void)getInitialScreen:(UINavigationController*)AViewControllerNavigationController {
if ([AViewControllerNavigationController.presentedViewController isKindOfClass:[AViewController class]]) {
return;
}
UINavigationController *navigation = [self getActiveNavigationController:AViewControllerNavigationController];
[navigation dismissViewControllerAnimated:YES completion:^{
[self getInitialScreen:AViewControllerNavigationController];
}];
}
finally after you wrote those 2 methods. You can call them like below and you can always get AViewController
[self getInitialScreen:AViewControlelrnavigationcontroller];
[AViewControlelrnavigationcontroller popToRootViewControllerAnimated:YES];
I know the question is repeated, but requirement is little different so posting here. I know how to pass value from one ViewController to other by defining property to hold the value passed from first ViewController. I am attaching the ScreenShot for better understanding. What I did is embed a UIPageViewControllerinto NavigationController(SwipeBetweenViewController). From UIPageViewController calling UIViewController(ProfileViewController) programmatically. After clicking LOG IN button, getting some response, storing it in a variable. Now what I have to do is pass that variable to ProfileViewController.I have defined a property in ProfileViewController.h, imported ProfileViewController.h into LoginViewController.m. I am passing data directly between LoginViewController to ProfileViewController, should it be passed from UiPageViewController. Here is the code, I have tried but its not working. Execution control remains on the same page, no navigation.
ProfileViewController.h
#interface KKProfileViewController : UIViewController
#property(copy, nonatomic) NSString *userEmailId;
#end
LoginViewController.m
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if (error) {
// Handle error
}
else {
NSError *tempError;
NSDictionary* response=(NSDictionary*)[NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&tempError];
NSString *loginResponse =response[#"message"];
_emailId =response[#"email"];
if ([loginResponse isEqualToString:#"Welcome"])
{
[self passLoginDataForward];
[self performSegueWithIdentifier:#"loginSuccess" sender:self];
}
else
{
//code for error alert
}
NSLog(#"Response is :%#", response);
}
}
-(void)passLoginDataForward
{
ProfileViewController *viewControllerProfile =[self.storyboard instantiateViewControllerWithIdentifier:#"profileViewController"];
viewControllerProfile.userEmailId = _emailId;
NSLog(#"user Email %#", viewControllerProfile.userEmailId);
[self.navigationController pushViewController:viewControllerProfile animated:YES];
}
SwipeViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
self.navigationBar.translucent = YES;
firstVC = [self.storyboard instantiateViewControllerWithIdentifier:#"profileViewController"];
secondVC = [self.storyboard instantiateViewControllerWithIdentifier:#"dashboardViewController"];
thirdVC = [self.storyboard instantiateViewControllerWithIdentifier:#"newsViewController"];
viewControllerArray = [[NSMutableArray alloc]init];
viewControllerArray = #[firstVC,secondVC,thirdVC];
self.currentPageIndex = 0;
self.isPageScrollingFlag = NO;
self.hasAppearedFlag = NO;
}
-(void)setupPageViewController
{
pageController = (UIPageViewController*)self.topViewController;
pageController.delegate = self;
pageController.dataSource = self;
[pageController setViewControllers:#[[viewControllerArray objectAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
[self syncScrollView];
}
The problem is because your login view controller may not have a navigation controller and you are trying to push view controller. Nothing will happen in this case.
If you want to push the page view controller to login views navigation stack, embed your login view controller in a navigation controller(Select login view controller Editor>Ember>Navigation controller) And add a segue to pageviewcontroller(directly from login view controller, not from any button). Add an identifier for the segue(say yourSegueID) Then implement the following method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"yourSegueID"]) {
UIPageViewController *pageViewController = [segue destinationViewController];
ProfileViewController *viewControllerProfile =[self.storyboard instantiateViewControllerWithIdentifier:#"profileViewController"];
viewControllerProfile.userEmailId = _emailId;
[pageViewController setViewControllers:#[viewControllerProfile] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}
}
Then call
[self performSegueWithIdentifier:#"yourSegueID" sender:nil];
Second option
If you want to create new navigation stack, as in your current storyboard implementation, make the segue from login view controller to navigation controller a present modal segue then change following line in prepareForSegue
UIPageViewController *pageViewController = [segue destinationViewController];
to
UINavigationController *navController = [segue destinationViewController];
UIPageViewController *pageViewController = navController.viewControllers[0];
Update
Updating as per your new code for swipeviewcontroller
In this case, You have to add email property in swipe view controller too. Then set it in prepare for segue method. Then set profile view controllers property in the swipe view controller viewdidload
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if (error)
{
// Handle error
}
else
{
NSError *tempError;
NSDictionary* response=(NSDictionary*)[NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&tempError];
NSString *loginResponse =response[#"message"];
_emailId =response[#"email"];
///////////////////////
//set your Email in nsuserdefaults
[NSUserDefaults standardUserDefaults][setObject:_emailId forKey:#"email"];
[[NSUserDefaults standardUserDefaults]synchronize];
///////////////////////
if ([loginResponse isEqualToString:#"Welcome"])
{
[self passLoginDataForward];
}
else
{
//code for error alert
}
NSLog(#"Response is :%#", response);
}
}
-(void)passLoginDataForward
{
ProfileViewController *viewControllerProfile =[self.storyboard instantiateViewControllerWithIdentifier:#"profileViewController"];
[self.navigationController pushViewController:viewControllerProfile animated:YES];
}
Get Value in ProfileViewController.m
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
userEmailId = [[NSUserDefaults standardUserDefaults]objectForKey:#"email"];
}
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
YourViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"identifier"];
vc.something = something;
[self.navigationController pushViewController:vc animated:YES];
Use this instead of self.storyboard.
When I try to receive data from detail view controller, the master view controller is not added a new cell. I want to update the table view in master view controller based on the array in the detail view-controller. Also cancel button is not work more than one time
This is the master view controller code for save and cancel button.
(void)detailControllerSaved:(DetailViewController *)controller {
if ([self.presentedViewController isEqual:controller]) {
[self.moviesToDisplay addObject:controller.detailItem];
[self dismissViewControllerAnimated:YES
completion:nil];
// it's a modal view
} else {
// it's a navigation view
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
self.moviesToDisplay[indexPath.row] = controller.detailItem;
[self.navigationController popViewControllerAnimated:YES];
}
[self.tableView reloadData];
}
(void)detailControllerCanceled:(DetailViewController *)controller {
if ([self.presentedViewController isEqual:controller]) {
// it's a modal view
[self dismissViewControllerAnimated:YES
completion:nil];
} else {
// it's a navigation view
[self.navigationController popViewControllerAnimated:YES];
}
}
This is my array list
(void) loadSampleContent {
NSArray *movies = #[
[Films movieWithGenre:#"Comedy" title:#"LittleMan " date:#"2006" rate:#"7.5"],
self.moviesToDisplay = [[NSMutableArray alloc] initWithArray:movies];
}
and this is the code in the detail view controller
(void)viewWillAppear:(BOOL)animated {
if(self.detailItem) {
self.movieTitle.text = self.detailItem.movieTitle;
self.genreField.text = self.detailItem.movieGenre;
self.movieRate.text = self.detailItem.movieRate;
self.yearOfMovie.text = self.detailItem.movieDate;
}
}
(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
(IBAction)Save:(id)sender {
self.detailItem =
[Films movieWithGenre:self.genreField.text title:self.movieTitle.text date:self.yearOfMovie.text rate:self.movieRate.text];
[self.delegate detailControllerSaved:self];
}
(IBAction)cancel:(id)sender {
[self.delegate detailControllerCanceled:self];
}
I think you missed reload table after received data from Detail viewcontroller. Try add reload tableview in mastercontroller in this code:
if ([self.presentedViewController isEqual:controller]) {
[self.moviesToDisplay addObject:controller.detailItem];
[self dismissViewControllerAnimated:YES
completion:nil];
// it's a modal view
}
Hope this help!
I do it with code:
NSArray *viewControllersFromStack = [self.navigationController viewControllers];
NSMutableArray *viewControllersFromStackMutable = [NSMutableArray arrayWithArray:viewControllersFromStack];
NSMutableArray *viewControllersToRemove = [[NSMutableArray alloc]init];
for (UIViewController *currentVC in viewControllersFromStack)
{
if ([currentVC isKindOfClass:[TalksViewController class]])
{
[viewControllersToRemove addObject:currentVC];
if (viewControllersToRemove.count == 2)
{
UIViewController *oneVCtoRemove = [viewControllersToRemove objectAtIndex:0];
[viewControllersFromStackMutable removeObject:oneVCtoRemove];
[self.navigationController setViewControllers:viewControllersFromStackMutable];
}
}
}
Problem is that I have reference to removed VC's in navigation Item. How to fix it?
When you want to remove a view from the navigation stack you can simply just call this method on the navigation bar to pop the view from the stack:
[self.navigationController popViewControllerAnimated:YES];
To pop an external view use
for(UIViewController *currentVC in viewControllersFromStack)
{
if([currentVC isKindOfClass:[TalksViewController class]])
{
[currentVC.navigationController popViewControllerAnimated:YES];
}
}
The above answer is correct.
I have 'A' as rootview controller. 'B to F' are other view controllers. From 'F', if I wanted to go directly to 'A', it is as under.
[self.navigationController popToRootViewControllerAnimated:YES];
BUT if I wanted to jump to 'B' then the code in answer is helpful. I only changed the array of view controllers to run reverse with 'reverseObjectEnumerator' and Animated to NO with 'popViewControllerAnimated:NO'. the Code is as under
NSArray *viewControllersFromStack = [self.navigationController viewControllers];
for(UIViewController *currentVC in [viewControllersFromStack reverseObjectEnumerator])
{
if(![currentVC isKindOfClass:[A class]] && ![currentVC isKindOfClass:[B class]])
{
[currentVC.navigationController popViewControllerAnimated:NO];
}
}
I create Login page include (username & password & login button)
I want when to fill text field username and password if right user and password go on another page else if to be wrong give me one alert.
this is my code:
#import "Detail.h"
#implementation ViewController
{
NSString *name;
}
#synthesize Username,Password;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)Login:(id)sender {
NSString *a = [[NSString alloc]initWithFormat:#"http://192.168.1.102/mamal/login.php?u=%#&p=%#",Username.text,Password.text];
NSString *url = [[NSString alloc]initWithContentsOfURL:[NSURL URLWithString:a]];
NSLog(#"%#",url);
if ([url isEqualToString:#"0"]) //this is wrong user & password
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"ERROR" message:#"WRONG" delegate:nil cancelButtonTitle:#"Dissmis" otherButtonTitles: nil];
[alert show];
}
else
{
name = #"Mohammad";
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([name isEqualToString:#"Mohammad"] , [[segue identifier] isEqualToString:#"Segue"]) {
Detail *det = segue.destinationViewController;
}
}
but dosent work!!! I want only right user & password go on next page
You have to make triggerless segue to perform this operation. Make triggerless segue from storyboard and fire it when your username and password is right.
To create a triggerless segue, start control+dragging the segue from the containing view controller icon in the scene dock at the bottom of the scene. Drag to the destination scene like normal, and pick the segue type. Select the segue, and in the inspector, choose a segue identifier.
Then call the method [self performSegueWithIdentifier:#"Identifier" sender:nil];
when your condition is true
If you want to use segues I think you are missing the call to actually perform the segue after the line where you set the name
name = #"Mohammed"
[self performSegueWithIdentifier:#"mySegue" sender:self]
Being "mySegue" the identifier of your segue in storyboard.
And then, you probably want to send the new View Controller the name.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"mySegue"]) {
Detail *det = segue.destinationViewController;
det.name = name;
}
}
Here AuditViewController is segue name
you need to call class like this in storyboard
[self performSegueWithIdentifier:#"AuditViewController" sender:self];
Edit
Check Condition
- (IBAction)Login:(id)sender {
NSString *a = [[NSString alloc]initWithFormat:#"http://192.168.1.102/mamal/login.php?u=%#&p=%#",Username.text,Password.text];
NSString *url = [[NSString alloc]initWithContentsOfURL:[NSURL URLWithString:a]];
NSLog(#"%#",url);
if ([url isEqualToString:#"0"]) //this is wrong user & password
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"ERROR" message:#"WRONG" delegate:nil cancelButtonTitle:#"Dissmis" otherButtonTitles: nil];
[alert show];
}
else
{
name = #"Mohammad";
if([name isEqualToString:#"Mohammad"])
[self performSegueWithIdentifier:#"Segue" sender:self];
//else
//NSLog(#"Can not Login");
}
}
prepareForSegue method call
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"Segue"])
{
Detail *det = segue.destinationViewController;
}
}