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!
Related
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.
I have a series of UIViewControllers in my app, and these are presented using a UINavigationController. The HOME ViewController calls pushViewController to get to the PROFILES ViewController. The PROFILES screen correctly shows the back button to HOME. Then selecting a button on PROFILES will take the user to the DETAIL ViewController. The DETAIL screen correctly shows the back button to PROFILES. But when I press the back button to PROFILES, I do indeed go back to the PROFILES screen but the navigation bar on that screen now shows the title HOME with no back button. In other words, it appears that IOS 8 has popped the ViewController once to go back from DETAIL to PROFILES, but has somehow popped the navigation bar items twice!
Any idea how I can fix this?
Apparently the solution outline can be found here:
UINavigationController and UINavigationBarDelegate.ShouldPopItem() with MonoTouch
In my solution, I just have all my view controllers extend CustomUINavigationController, which looks like this:
#import "CustomUINavigationController.h"
#import "IOSVersion.h"
#interface CustomUINavigationController ()
#end
#implementation CustomUINavigationController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.delegate=self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//
// The following two methods are the key to overriding the buggy behavior in IOS 8
// The first method is from here:
// https://stackoverflow.com/questions/6413595/uinavigationcontroller-and-uinavigationbardelegate-shouldpopitem-with-monotouc
//
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
NSLog(#"Inside shouldPopItem");
if (regularPop) {
NSLog(#"regularPop is TRUE");
} else {
NSLog(#"regularPop is FALSE");
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
if (regularPop) {
regularPop = FALSE;
return YES;
}
regularPop = TRUE;
[self popViewControllerAnimated:YES];
return NO;
} else {
return [super navigationBar:navigationBar shouldPopItem:item];
}
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
NSLog(#"Inside popViewControllerAnimated");
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.viewControllers];
int cnt=(int)[viewControllers count];
NSLog(#"Inside popViewControllerAnimated, cnt is %d",cnt);
UIViewController *vc=[viewControllers objectAtIndex:cnt-2];
if (regularPop) self.desiredVC=vc;
[self popToViewController:vc animated:animated];
return vc;
} else {
return [super popViewControllerAnimated:animated];
}
}
- (UIViewController *)manualpopViewControllerAnimated:(BOOL)animated {
NSLog(#"Inside manualpopViewControllerAnimated");
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
regularPop=TRUE;
return [self popViewControllerAnimated:animated];
} else {
return [super popViewControllerAnimated:animated];
}
}
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animated {
NSLog(#"Inside didShowViewController");
if (viewController==self.desiredVC) {
NSLog(#"Inside didShowViewController, found desiredVC");
regularPop = FALSE;
}
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
I want to transition to a view I made in the main.storyboard, when they enter the password correctly.
How do I do this?
I need it to pull up the view I already created. I want a transition in the code block -(void) unlock.
Code
//
// ViewController.m
// Login
//
// Created by Ben Rosen on 5/24/14.
// Copyright (c) 2014 Ben Rosen. All rights reserved.
//
#import "ViewController.h"
#import "UnlockedScreen.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)login:(id)sender
{
NSString *correctUser = #"money";
NSString *correctPassword = #"ilovemoney";
if ((usernameTextField.text == correctUser)==YES && (passwordTextField.text = correctPassword)==YES)
{
[self unlock];
}
}
-(void) unlock
{
// here should be the transition
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
#end
In you storyboard, go on your first view controller, press CTRL click on the viewController and release the mouse (and CTRL) on the destination view controller.
Now choose type of segue (push if you are in a navigationController otherwise modal) and choose an identifier on the inspector for this trigger.
In your code:
-(IBAction)login:(id)sender
{
NSString *correctUser = #"money";
NSString *correctPassword = #"ilovemoney";
if ([usernameTextField.text isEqualToString:correctUser] && [passwordTextField.text isEqualToString:correctPassword])
{
[self performSegueWithIdentifier:#"name" sender:sender];
}
}
As you see i changed your if statement..your compare was wrong.
[self unlock];
remove it and write this method
[self performSegueWithIdentifier:#"profileSegue" sender:self] ;
in the storyboard name to identifier(profileSegue) on the inspector
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"profileSegue"]) {
ProfileViewController *profileViewController = segue.destinationViewController;
profileViewController.isFromDealView = YES;
profileViewController.hidesBottomBarWhenPushed = YES;
}
Instantiate your viewController with the identifier you have provided for your viewController.
-(void) unlock
{
// here should be the transition
UIViewController *vc = [[UIStoryboard storyboardWithName:#"storyboardname" bundle:nil] instantiateViewControllerWithIdentifier:#"viewControllersID"];
[self presentViewController:vc animated:YES completion:nil];
}
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];
I'm using the library GKClass, its basically a custom imagePickerController class.
I'm having trouble passing data - the image to the next control view, while it was working with the simple imagePickerController its not working now, the ViewController doesn't get the data.
-(void)imagePicker:(GKImagePicker *)imagePicker pickedImage:(UIImage *)image
{
VCImageEditingViewController *ieVC = [[VCImageEditingViewController alloc]init];
ieVC.selectedIMG = image;
[self.imagePicker.imagePickerController dismissViewControllerAnimated:NO completion:nil];
[self performSegueWithIdentifier:#"imgrdy" sender:self];
}
and VCImageEditingViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.selectedIMG == nil) {
NSLog(#"no img set");
}
self.imageDisplayed.image = self.selectedIMG;
}
i tried it also in viewDidAppear and still nothing, the "picker" is working since iv tried :
-(void)imagePicker:(GKImagePicker *)imagePicker pickedImage:(UIImage *)image
{
[self.imagePicker.imagePickerController dismissViewControllerAnimated:NO completion:nil];
self.lastImageView.image = image;
}
It showed the image in the current view controller.
My guess is that the destination viewController is presented before the image is modified.
Would like some help here. Thank you.
Try this
-(void)imagePicker:(GKImagePicker *)imagePicker pickedImage:(UIImage *)image
{
[self.imagePicker.imagePickerController dismissViewControllerAnimated:NO completion:nil];
//pass image with peroformsegue
[self performSegueWithIdentifier:#"imgrdy" sender: image];
}
// In prepare segue method assign image to destination view controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"imgrdy"])
{
VCImageEditingViewController *ieVC=segue.destinationViewController;
ieVC.selectedIMG =(UIImage *) sender;
}
}