First time app launch PageView - ios

I Have an UIPageView as first time welcome view, with a little help of appcoda.
The middle view is the PageContentViewController and the last the RootViewController is called PageViewController.
Now I want to connect it with the NSUserDefault, which i did in the regulair first screen Controller:
- (void)Loadview_afterdelay
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:#"firstRun"])
{
PageViewController *intro = [[PageViewController alloc] initWithNibName:nil bundle:nil];
intro.modalTransitionStyle = UIModalTransitionStyleCoverVertical ;
[self presentModalViewController:intro animated:YES];
[defaults setObject:[NSDate date] forKey:#"firstRun"];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
And in the ViewDidLoad of my RootViewController in the app:
[self performSelector:#selector(Loadview_afterdelay) withObject:nil afterDelay:0.5];
I know that the PageViewController is the screen where I need to go.
When I try to do this the above way I get a crash:
-[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
I'm not sure what I'm doing wrong.

Related

How to open an existing viewcontroller in ios

I need to open existing viewcontroller from AppDelegate while receiving push notification. Currently i am opening new one every time so issue is that it is called viewDidLoad every time and all variable are reinitialized again and again.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSUserDefaults standardUserDefaults] setObject:#"Yes" forKey:#"Got Message"];
[[NSUserDefaults standardUserDefaults] setObject:userInfo forKey:#"message"];
[[NSUserDefaults standardUserDefaults]synchronize];
HomeViewController* room = [[HomeViewController alloc] init];
[self.window.rootViewController presentViewController:room
animated:NO
completion:nil];
}
Try to do so:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSUserDefaults standardUserDefaults] setObject:#"Yes" forKey:#"Got Message"];
[[NSUserDefaults standardUserDefaults] setObject:userInfo forKey:#"message"];
[[NSUserDefaults standardUserDefaults]synchronize];
[self.window.rootViewController presentViewController:self.room
animated:NO
completion:nil];
}
- (UIViewController *)room {
if (_room == NULL) {
_room = [[HomeViewController alloc] init];
}
return _room;
}
Then you can reuse your view controller (However, it will exposure the view controller in your AppDelegate, which may be a taste in clean code).
Since you want to use a existing view controller, why do you use the code HomeViewController* room = [[HomeViewController alloc] init];?
Follow your goal, my suggestion is use a property to retain the existing view controller, just like:
#property (strong, nonatomic) UIViewController *existingViewController;
and you
[self.window.rootViewController presentViewController:existingViewController
animated:NO
completion:nil];
You can get UINavigationController in AppDelegate meethod
UIViewController *yourViewController = //your view controller to show after push
UINavigationController *navController = self.window.rootViewController;
[navController popToViewController:yourViewController animated:YES]

Pop to viewcontroller Editing Text

I have a ViewcontrollerA as a form filling page and to perform a calculation I push a new viewcontrollerB now when I pop to ViewcontrollerA the existing contents are cleared
My code is
In viewcontroller A
JS_skill *skill_VC = [[JS_skill alloc] initWithNibName:#"JS_skill" bundle:nil];
[[self navigationController] pushViewController:skill_VC animated:NO];
In viewcontroller B
[self.navigationController popViewControllerAnimated:YES];
A quick option would be to save the values of the textfields in userDefaults before you push the viewcontroller. Then when you return to the viewController in viewWillAppear set the textfields back to what you have in userDefaults:
//Just before you push the viewController:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:#"Example Name" forKey:#"nameTextField"];
[defaults setValue:#"Example Surname" forKey:#"surnnameTextField"];
//In ViewWillAppear:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
textField.text = [defaults valueForKey:#"nameTextField"];
surnameField.text = [defaults valueForKey:#"surnnameTextField"];

How to launch a different viewController on the second launch

Here the code I have under the viewController.m
This code will run when a user selects a viewController
-(void)switchViews {
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [mainStory instantiateViewControllerWithIdentifier:schoolName];
[self presentModalViewController:vc animated:YES];
NSUserDefaults *defaultViewController = [NSUserDefaults standardUserDefaults];
[defaultViewController setObject:nil forKey:#"save"];
[defaultViewController synchronize];
}
This code will run on the second time the app is launched
-(void)loadNewView {
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
NSUserDefaults *newUserDefault = [NSUserDefaults standardUserDefaults];
NSString *newVC = [NSString stringWithFormat:#"save", schoolName];
UIViewController *newViewController = [mainStory instantiateViewControllerWithIdentifier:newVC];
[self presentModalViewController:newViewController animated:YES];
}
Keeping in mind that schoolNameis a string
How can I run [self loadNewView] under the viewDidLoad but running it on the second time the app is launched?
You should do something like
id value = [[NSUserDefaults standardUserDefaults] objectForKey:#"save"];
if (value) {
UIViewController *vc = [mainStory instantiateViewControllerWithIdentifier:value];
[self presentModalViewController:vc animated:YES];
} else {
// first time logic
}
in your AppDelegate or wherever you have your navigation logic. You should not have that logic in viewDidLoad.
-(void)viewDidLoad {
[super viewDidLoad];
NSString *launchCount = #"LaunchCount";
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSInteger count;
if([userDefaults objectForKey:launchCount]) {
count = [userDefaults integerForKey:launchCount];
}
else {
count = 0;
}
count++; //increment the launch count
[userDefaults setObject:[NSNumber numberWithInt:count] forKey:launchCount];
[userDefaults synchronize];
if([userDefaults integerForKey:launchCount] >= 2) {
// Do your thang
}
}
on ViewDidLoad function do something like this
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedFirst"])
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"HasLauncheFirst"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self switchViews];
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:No forKey:#"HasLauncheFirst"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self loadNewView];
}

NSUserDefaults Saving only last entered data

I am saving Textfield text using NSUserDefaults on button click in ViewController2
My code is
ButtonClick()
{
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:keyWordField.text forKey:#"Keywords"];
[userDefaults synchronize];
}
Then ViewDidLoad method i am Retrieving like this
-(void)viewDidLoad
{
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[keyWordArray addObject:[userDefaults objectForKey:#"Keywords"]];
[userDefaults synchronize];
}
Here i am assigning this keyWordArray to tableview
like cell.textlabel.text =[keyWordArray objectAtIndex:indexPath.row];
First i entered text(First) in textfield and click button it is showing in table like
First
Second time i entered text (second) in textfield and click button it is showing table like
First
Second
Here everything working fine. The problem is when i come to viewController2 from ViewController1. It is showing last entered value only
like
Second
what going wrong here?
Try This
- (IBAction)buttonclick:(id)sender {
[keyWordArray addObject:keyWordField.text];
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:keyWordArray forKey:#"Keywords"];
[userDefaults synchronize];
[selt.tableView reload]; //reload the table every time a new text is added
}
-(void)viewDidLoad {
if([[NSUserDefaults standardUserDefaults] objectForKey:#"Keywords"]==nil){
keyWordArray = [[NSMutableArray alloc] init];
}
else{
keyWordArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"Keywords"];
}
}
Try this,
- (IBAction)buttonclick:(id)sender {
[keyWordArray addObject:keyWordField.text];
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:keyWordArray forKey:#"Keywords"];
[userDefaults synchronize];
}
and
-(void)viewDidLoad
{
NSArray *array = [[NSUserDefaults standardUserDefaults] objectForKey:#"Keywords"];
if (!array) {
keyWordArray = [[NSMutableArray alloc] init];
} else {
keyWordArray = [NSMutableArray arrayWithArray:nameArray];
}
}
Since you are overriding your
[userDefaults setObject:keyWordField.text forKey:#"Keywords"];
every then and there your every object in the array will be referring to your [userDefaults setObject:keyWordField.text forKey:#"Keywords"]; object thats y the problem comes
Because if you are navigate to another viewController. since the your user default value save in second only.
After pop to back through viewDidLoad is loaded. so far its have second string only save in User Default.
that way it display second only.
You code is overwrite the last value and remove previous values from NSUserDefault. You have to use array to stored all value and you have save array into NSUserDefault.
NSMutableArray *aryDataDefault = [[NSUserDefaults standardUserDefaults] valueForKey:#"YourKey"];
[aryDataDefault addObject:textfield.text];
[[NSUserDefaults standardUserDefaults] setObject:aryDataDefault forKey:#"YourKey"];
[[NSUserDefaults standardUserDefaults] synchronize];

Warning: Attempt to present UINavigationController on ViewController whose view is not in the window hierarchy

I'm working on an ios app and I'm new to it. So, I'm getting this error. What I'm trying to do is when a user first registers on the app, their username is stored locally on the phone using NSUserdefault.
Now if they close the app and reopen it the app goes through the first view controller and in the viewdidload method it checks if the length of the USUserdefault is greater than zero and if yes go to the main activity by perform a segue call. However I get that error when I run it.
This is what I did on my storyboard.
This is the code in the firstviewcontroller
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; NSString *user = [prefs stringForKey:#"userName"];
if(user.length>0){
NSLog(#"Going straight to main %s", "Yes");
[self performSegueWithIdentifier:#"startMain" sender:self];
}
}
All you have to do is move the method to viewDidAppear:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; NSString *user = [prefs stringForKey:#"userName"];
if(user.length>0){
NSLog(#"Going straight to main %s", "Yes");
[self performSegueWithIdentifier:#"startMain" sender:self];
}
}

Resources