NSUserDefault work only one time in Keyboard Extension in iOS8 - nsuserdefaults

I have a options that let user choose background color of Keyboard with Keyboard extension with XCode beta 1.
I can save and load from NSUserDefault. But Only one time. after i changed value twice and test with UITextField (Even iOS Built in App). It doesn't work and not change background color.
However when i quit app and reopen , that changed value is working and background color is changing.
Here is my code that save data to NSUserDefault.
self.defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.mycompany.keyboard"];
- (void)savePreferences
{
[self.defaults setBool:self.redColorSwitch.on forKey:#"redColor"];
[self.defaults synchronize];
}
and load code is
self.defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.mycompany.keyboard"];
if([self.defaults boolForKey:#"redColor"])
{
self.myKeyboard.backgroundColor = [UIColor redColor];
}
else
{
self.myKeyboard.backgroundColor = [UIColor blackColor];
}
Is there any wrong in my codes?

Related

iOS: How to hide a UITextField on settings change?

I have a settings screen in which I set the units for the app. The user can go from the main screen to the settings screen and after selecting the desired unit, the settings screen is dismissed.
When the user returns to the main screen, I want to hide and show two UITextField.
I tried the following code in viewDidLoad and viewDidAppear but doesn't work:
textBox1.hidden = YES;
textBox2.hidden = NO;
This may be trivial but any help is appreciated. Thanks.
UPDATE:
I have connected the 'Settings' screen with Sugue using push and dismiss the settings screen using [self.navigationController popViewControllerAnimated:YES]; which leads the user back to main screen. Now, I need to refresh the screen controls based on the settings and it's not working
first:
shouldn't it be
self.textBox1 = YES; // or [self.textBox1 setHidden:YES];
self.textBox2 = NO; // or [self.textBox2 setHidden:NO];
Second:
make sure that outlets are not null
NSLog("textBox1 = %#" , self.textBox1);
Third:
Try some code like this
int64_t delayInSeconds = 15.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
self.textBox1.hidden = YES;
self.textBox2.hidden = NO ;
});
Do this in your viewWillAppear or DidAppear. Then in 15 seconds you will see the changes if everything is wired correctly.
Set the following bools to yes or no (in the settings screen).
BOOL hideTextBox1;
BOOL hideTextBox2;
Save the variable (in the settings screen):
NSString *hideTextBox1String;
NSString *hideTextBox2String;
if(hideTextBox1 == YES){
hideTextBox1String = #"YES"
}else{
hideTextBox1String = nil
}
if(hideTextBox2 == YES){
hideTextBox2String = #"YES"
}else{
hideTextBox2String = nil
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:hideTextBox2String forKey:#"hideTextBox2"];
[defaults setObject:hideTextBox1String forKey:#"hideTextBox1"];
[defaults synchronize];
Retrieve it in the first viewcontroller:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *hideBox1 = [defaults objectForKey:#"hideTextBox1"];
NSString *hideBox2 = [defaults objectForKey:#"hideTextBox2"];
if(hideBox1 != nil){
textBox1.hidden = YES;
}else{
textBox1.hidden = NO;
}
if(hideBox2 != nil){
textBox2.hidden = YES;
}else{
textBox2.hidden = NO;
}
This will make the change permanent untill you change back. Guess that's what youre looking for.
Since setting the text does not work either I am guessing your IBOutlets may be messed up. To re-do them do the following:
First go into your Storyboard & zoom into the view controller that your working on
Control + Click your UITextView or UITextField, you will see a similar menu:
You can see that I have an IBOutlet set named txtCaseID
If you see an outlet set like I do, go ahead and click the X to remove it
To re-add this outlet, open up the Assistance Editor to view the Storyboard & your .h
Control + Click & Drag from your textBox in your Storyboard to the IBOutlet you made previously in your .h like so:
Make sure to do this for both textBoxes.
Let me know if you need any other help--
thank you for taking time.. I just realized the my code for reading the value for the boolean key from NSUserDefaults was in viewDidLoad which only gets called once :)
I moved that line of code to viewWillAppear and everything works as expected!

Multiple Images for iOS app's Background

I have seen different apps that the image will change each time the app is opened on the view background. How is this accomplished?
It sounds like what you are seeing is the cached screenshot the iOS system is making of your app just before it puts it into the background.
This is handled automatically, and you do have the opportunity to intercept this.
Check out this answer, you can put an image over your app just as it's entering the background, this will be cached and used to relaunch the app.
add background_0.png, background_1.png, background_2.png, background_3.png etc to your project.
#define max_image_number 3
Add the following to your viewDidLoad method:
-(void)viewDidLoad {
[super viewDidLoad];
[self updatedBackgroundImage];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateBackgroundImage) name:UIApplicationWillEnterForegroundNotification object:nil];
}
-(void) updateBackgroundImage{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults integerForKey:#"imageNumber"]) {
[defaults setInteger:0 forKey:#"imageNumber"];
}
int i = [defaults integerForKey:#"imageNumber"];
myUIimageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"background_%d.png",i]];
i++;
if (i > max_image_number) {
[defaults setInteger:0 forKey:#"imageNumber"];
}else{
[defaults setInteger:i forKey:#"imageNumber"];
}
...
}
The above will update the image when the viewController is first loaded and also when it returns from running in the background. I assume this is what was missing for you :).
Remember to stop listening for the notification in the viewDidUnload method and you should be set.
Looking at the screenshots in the App Store of the application you mention, it looks like there's just a UIImageView at the back of the view hierarchy for the main menu. You can change this by assigning a UIImage object to its image property.
Suppose you want to change one or more view's background images, depending on the application launch.
Save an int x = 0 into NSUserDefaults. On each application launch increment it by 1. When you are to present a view, check that int and set a background image like this:
switch(x%3){// %3 just to make it a bit random
case 0://set this image;
break;
case 1://set that image
break;
//and so on
}

Dont want to restart the app when changing language

I use this line of code to change the language in my app
[[NSUserDefaults standardUserDefaults]
setObject:[NSArray arrayWithObjects:#"en", #"fr", nil]
forKey:#"AppleLanguages"];
Changes won't take place before the user restarts the app.
Do the user really need to restart the app before the changes will take place,
or is it possible to just reload the view controllers in some way to make the app change its language immediately.
write below method in your appDelegate class
+(void)GetLangKey:(NSString *)Langkey
{
NSString *tmpstr=[NSString stringWithFormat:#"%#",[[NSBundle mainBundle]pathForResource:#"LanguageResources" ofType:#"bundle"]];
tmpstr =[tmpstr stringByAppendingString:#"/"];
tmpstr=[tmpstr stringByAppendingString:Langkey];
tmpstr =[tmpstr stringByAppendingString:#".lproj"];
// NSLog(#"%#",tmpstr);
myLocalizedBundle=[NSBundle bundleWithPath:tmpstr];
}
and call this method when your language change
if([language isEqualToString:#"English"])
{
[app_obj GetLangKey:#"en"];
}
else
{
[app_obj GetLangKey:#"fr"];
}

How to reload image in UIButton in applicationDidBecomeActive

I have a MenuViewController that loads when the app loads up; it is the root view of a UINavigationController.
Within the view I have a UIButton with an image that loads from a URL, as well as a label (its a picture indicating the weather and the current temp.).
Everything works fine, but if I am using the app on an iPhone 4, with multi-tasking, when the home button is pressed and then the app is reopened, I need the UIButton image and temp. label to reload.
I have tried calling this in my AppDelegate under applicationDidBecomeActive:
[self parseWeatherXML]; //re-parse weather data
[menuViewController reloadWeatherData]; //loads the image/label from the XML
with no luck.
I have also tried releasing menuViewController in applicationWillResign, then reallocating menuViewController in applicationDidBecomeActive so the viewDidLoad method gets called again, both ways just end up crashing my app.
Any help appreciated!
EDIT
Heres my method that gets called with the notification:
- (void)reloadWeather
{
[self parseWeatherXML];
UIImage *img = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString:iconURL]]];
if (img != nil)
{
NSLog(#"setting image");
[weatherButton setImage:img forState:normal];
img = nil;
}
currentTemp = [currentTemp stringByAppendingString:#"°F"];
[tempLabel setText:currentTemp];
tempLabel.adjustsFontSizeToFitWidth = YES;
if([self isIPad])
{
tempLabel.textAlignment = UITextAlignmentRight;
[tempLabel setFont: [UIFont systemFontOfSize: 45.0]];
}
currentTemp = nil;
}
I would have your MenuViewController become an observer to the UIApplicationDidBecomeActiveNotification and perform the parseWeatherXML data. I would think you would be refreshing the data from the URL, so you would need to wait for that data to come back again. So, I would follow the same logic that you are doing when you receive that notification.
UIApplicationDidBecomeActiveNotification
Posted when the application becomes
active. An application is active when
it is receiving events. An active
application can be said to have focus.
It gains focus after being launched,
loses focus when an overlay window
pops up or when the device is locked,
and gains focus when the device is
unlocked.
Availability
Available in iOS 2.0 and later.
Declared In
UIApplication.h
Have you tried saving the image and temp using a plist or something, during the applicationWillResign, and then during applicationDidBecomeActive, you can reload the image and temp from the saved file/label. Just another option to explore.

How to disable "shake to undo" in iPhone application written with Phonegap?

The only thing I've found is that you have to set UIApplicationSupportsShakeToEdit to false in plist file but it doesn't work for me.
I inserted this line:
[UIApplication sharedApplication].applicationSupportsShakeToEdit = NO;
in the webViewDidFinishLoad class, it worked wonders for me.
Go to the MainViewController.m and change webViewDidFinishLoad to look like this:
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
// Black base color for background matches the native apps
theWebView.backgroundColor = [UIColor blackColor];
[UIApplication sharedApplication].applicationSupportsShakeToEdit = NO;
return [super webViewDidFinishLoad:theWebView];
}