Objective-C: Why is my if statement not working? - objective-c

Here i have some code that checks if the iphone has a camera flash. And then check if my switch is on by using this code:
if(switch1.on){
}
The light turns on fine without this code and i have also tried this code as well:
if(!(switch1.on)){
}
and that successfully turns my camera flash on but also turns it on even when the switch is set to off
Here is my full code:
-(IBAction)torchon:(id)sender{
AVCaptureDevice *flashlight = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([flashlight isTorchAvailable] & [flashlight isTorchModeSupported:AVCaptureTorchModeOn]) {
BOOL success = [flashlight lockForConfiguration:Nil];
if(success){
if(switch1.on){ //// or (!(switch1.on))
on.hidden = YES;
[UIScreen mainScreen].brightness = 1.0;
[flashlight setTorchMode:AVCaptureTorchModeOn];
[flashlight unlockForConfiguration];
}
}
}
}
any help would be appreciated
**EDIT:**
Here is the code where i set the switch to no using ibactions when the value of the switch has changed. This code works successfully:
-(IBAction)switch1{
if (switch1.on) {
switch1.on = YES;
switch2.on = NO;
} else{
switch2.on = YES;
switch1.on = NO;
}
}
-(IBAction)switch2{
if (switch2.on) {
switch2.on = YES;
switch1.on = NO;
} else{
switch1.on = YES;
switch2.on = NO;
}
}
Answer
First add a bool:
bool yes;
then set that bool in the viewdidload
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
yes = YES;
}
After that set it to YES when the ibaction is called and set it to NO once the switch is turned off:
-(IBAction)switch1{
if (swich1.on) {
swich1.on = YES;
swich2.on = NO;
yes = YES;
}
}
-(IBAction)switch2{
if (swich2.on) {
swich2.on = YES;
swich1.on = NO;
yes = NO;
}
}
lastly where it checks if(switch1.on){} you need to change it to if(yes==YES){} so together that if statement looks like this:
-(IBAction)torchon:(id)sender{
AVCaptureDevice *flashlight = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([flashlight isTorchAvailable] & [flashlight isTorchModeSupported:AVCaptureTorchModeOn]) {
BOOL success = [flashlight lockForConfiguration:Nil];
if(success){
if(yes==YES){
on.hidden = YES;
[UIScreen mainScreen].brightness = 1.0;
[flashlight setTorchMode:AVCaptureTorchModeOn];
[flashlight unlockForConfiguration];
}
}
}
}

The UISwitch has another getter for the on property.
#property(nonatomic, getter=isOn) BOOL on;
It may be better to use .isOn instead of .on for getting the value.
Also, some of your code can be simplified:
-(IBAction)switch1{
[switch2 setOn:!switch1.isOn];
}
-(IBAction)switch2{
[switch1 setOn:!switch2.isOn];
}
It can get even better if you use the sender of the action in your methods.

It seems that your IBAction methods have a similar form as the getter for the switch. It is possible that this could lead to undesired side effects. Refactor your methods to a single method, more in line with good programming practice:
-(IBAction)switchDidChange:(UISwitch*)aSwitch {
UISwitch* otherSwitch = (aSwitch == switch1)? switch2 : switch1;
[otherSwitch setOn:!aSwitch.on animated:YES];
}
Also, in your code the on property does not really seem to influence what is switched on or off. Include this conditionality.

Related

Game Won't Return to Main Menu Upon Collision

I am working on a collision game as objects move across the screen, but for some reason, it won't return to the main menu when the object collides. It looks fine to me. What's wrong here?
-(void)Crash {
if (CGRectIntersectsRect(StealthBomber.frame, LargeObstacle1.frame)) {
[self EndGame];
}
if (CGRectIntersectsRect(StealthBomber.frame, MediumObstacle1.frame)) {
[self EndGame];
}
if (CGRectIntersectsRect(StealthBomber.frame, SmallObstacle1.frame)) {
[self EndGame];
}
if (CGRectIntersectsRect(StealthBomber.frame, Grass.frame)) {
[self EndGame];
}
if (CGRectIntersectsRect(StealthBomber.frame, Dirt.frame)) {
[self EndGame];
}
}
-(void)EndGame {
StealthBomber.hidden = YES;
[timer invalidate];
[self performSelector:#selector(NewGame) withObject:nil afterDelay:5];
}
-(void)NewGame {
LargeObstacle1.hidden = NO;
MediumObstacle1.hidden = NO;
SmallObstacle1.hidden = NO;
StealthBomber.hidden = NO;
StealthBomber.center = CGPointMake(32, 92);
StealthBomber.image = [UIImage imageNamed:#"stealthbomber.png"];
startGame = YES;
}
I fixed the issue. It was a matter of not showing hidden items and hiding other items when newGame is called.

Can I use scrollview.bounces property of webview for handling webview scroll?

I want to stop bounce in webview. can my app get rejected in appstore if I use following statement in my code?
self.viewController.webView.scrollView.bounces = NO;
Thanks!
if ([[[UIDeice currentDevice] SystemVersion] floatValue] >= 5.0)//iOS>=5.0
{
webView.scrollView.bounces = NO;
}
else//iOS<5.0
{
for (id subview in webView.subviews)
{
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
((UIScrollView *)subview).bounces = NO;
}
}
if (webView respondsToSelector:#selector(scrollView)]) {
webView.scrollView.bounces = NO;
} else {
for (id subview in webView.subviews) {
if ([[subview class] isSubclassOfClass:[UIScrollView class]]) {
((UIScrollView*)subview).bounces = NO;
}
}
}

Hide Copy and Deselect UITextView options after copying all text

I am working on a messaging app. I want to give a "copy" option to the user when they enter their message in a UITextView. When the user presses the "copy" button, it is copying the message, but the popover shows again and again, and the text is still selectable.
I don't know how to control this. I have pasted some source code for your reference.
I wrote a sub class for UITextView.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
NSLog(#"Action : %#", NSStringFromSelector(action));
NSLog(#"Sender : %#", sender);
if (action == #selector(copy:))
{
[self selectAll:self];
//return [super canPerformAction:action withSender:sender];
return YES;
}
else if (action == #selector(cut:))
{
return NO;
}
return NO;
}
I have solved my problem. I have used below codes to solve.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == #selector(copy:))
{
[self selectAll:self];
return YES;
}
else if (action == #selector(cut:))
{
return NO;
}
return NO;
}
- (void)copy:(id)sender
{
UIPasteboard *pastBoard = [UIPasteboard generalPasteboard];
[pastBoard setString:self.text];
self.selectedTextRange = nil;
[self resignFirstResponder];
}
Thanks to Mr.Vimal Venugopalan and Mr.Mrueg. It is working for me. It will help to some one.
If you are using the iOS5
UITextView adopts the UITextInput protocol, which has a selectedTextRange property. Set the property to nil:
Add the below code just above the last return NO.
self.selectedTextRange = nil;
Hope this helps

segmentedControl and TextView refresh/reload - xcode

I've got the following code which is a segmentedControl for a language selection option. Case 0 is for English and case 1 is for Greek which is then passed to a UITextView. The problem is that every time I press the button for case 1 or 0 I have to go back to the previous view controller which is a table view controller and come back to the "detailViewController" for the correct language to be displayed. Is there a way for this to be done without switching back and forth between the view controllers? Something like a small animation or a refresh or a reload method for UITextView.
int a;
- (IBAction)languageSeg:(id)sender {
switch (((UISegmentedControl *)sender).selectedSegmentIndex) {
case 0:
a=0;
break;
case 1:
a=1;
break;
default:
break;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
UIImage *saladImage = [UIImage imageNamed:#"salad.jpg"];
UIImage *fishImage = [UIImage imageNamed:#"fish.jpg"];
[textDetail setScrollEnabled:YES];
[textDetail setContentSize:CGSizeMake(320, 190)];
//Switch the UIImages and UILabel based on item
switch (itemNumber) {
case 0:
itemName.text = #"Salad";
itemPic.image = saladImage;
self.title = #"Salads";
if (a==0){
textDetail.text = #"description in english";
}
if (a==1){
textDetail.text = #"description in greek";
}
break;
case 1:
// etc.
You can update the text for the textView in the languageSeg: method the same way you set it initially in viewWillAppear:
I would create a separate method that handles the language switch, then call that method from both viewWillAppear and languageSeg and anywhere else you need it.
For example, your language setter method would include the code currently at the bottom of viewWillAppear:
- (void) languageSetter {
switch (itemNumber) {
case 0:
itemName.text = #"Salad";
itemPic.image = saladImage;
self.title = #"Salads";
if (a==0){
textDetail.text = #"description in english";
}
if (a==1){
textDetail.text = #"description in greek";
}
break;
case 1:
// etc.
break;
default:
// default case
break;
}
}
Then your viewWillAppear: method would look like this:
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
UIImage *saladImage = [UIImage imageNamed:#"salad.jpg"];
UIImage *fishImage = [UIImage imageNamed:#"fish.jpg"];
[textDetail setScrollEnabled:YES];
[textDetail setContentSize:CGSizeMake(320, 190)];
[self languageSetter];
}
And your languageSeg: method would look like this:
- (IBAction)languageSeg:(id)sender {
switch (((UISegmentedControl *)sender).selectedSegmentIndex) {
case 0:
a=0;
break;
case 1:
a=1;
break;
default:
break;
}
[self languageSetter];
}
A lot of implementation would be dependent on how the rest of your code is set up and your individual needs, but this is the general idea.
I have an app with a language selector, and I use NSUserDefaults. Works like a charm.
In the view controller with the picker:
- (IBAction)languageSeg:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
switch (((UISegmentedControl *)sender).selectedSegmentIndex) {
case 0:
[defaults setInteger:0 forKey:#"language"];
break;
case 1:
[defaults setInteger:1 forKey:#"language"];
break;
default:
break;
}
}
And In the vieWillAppear in the viewController displaying the language:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults integerForKey:#"language"] == 0) {
textDetail.text = #"description in english";
}else{
textDetail.text = #"description in greek";
}
Now, in the viewDidLoad method, you need to give it a default value if there is no value set by the user yet, like this: (again in your view controller displaying the setting, not the picker view.)
if (![defaults integerForKey:#"language"]) {
[defaults setInteger:0 forKey:#"language"];
}
textDetail.text = #"description in english";
Where is the switch (itemNumber) got called?
If it's in methods like viewDidLoad or viewWillAppear etc, it will only be called when this view shows up.
You may need to extract this part as a method, and also put it in (IBAction)languageSeg:(id)sender. For example:
- (void)updateView
{
switch (itemNumber) {
case 0:
itemName.text = #"Salad";
itemPic.image = saladImage;
self.title = #"Salads";
if (a==0){
textDetail.text = #"description in english";
}
if (a==1){
textDetail.text = #"description in greek";
}
break;
case 1:
// etc.
}
Then call this method in viewDidLoad and
languageSeg: after switch block.

Singleton method not getting called in Cocos2d

I am calling a Singleton method that does not get called when I try doing this.
I get no errors or anything, just that I am unable to see the CCLOG message.
Under what reasons would a compiler not give you error and not allow you to call a method?
[[GameManager sharedGameManager] openSiteWithLinkType:kLinkTypeDeveloperSite];
The method is defined as follows:
-(void)openSiteWithLinkType:(LinkTypes)linkTypeToOpen
{
CCLOG(#"WE ARE IN openSiteWithLinkType"); //I NEVER SEE THIS MESSAGE
NSURL *urlToOpen = nil;
if (linkTypeToOpen == kLinkTypeDeveloperSite)
{
urlToOpen = [NSURL URLWithString:#"http://somesite.com"];
}
if (![[UIApplication sharedApplication]openURL:urlToOpen])
{
CCLOG(#"%#%#",#"Failed to open url:",[urlToOpen description]);
[self runSceneWithID:kMainMenuScene];
}
}
HERE IS THE CODE TO MY SINGLETON:
#import "GameManager.h"
#import "MainMenuScene.h"
#implementation GameManager
static GameManager* _sharedGameManager = nil;
#synthesize isMusicON;
#synthesize isSoundEffectsON;
#synthesize hasPlayerDied;
+(GameManager*) sharedGameManager
{
#synchronized([GameManager class])
{
if (!_sharedGameManager)
{
[[self alloc] init];
return _sharedGameManager;
}
return nil;
}
}
+(id)alloc
{
#synchronized ([GameManager class])
{
NSAssert(_sharedGameManager == nil,#"Attempted to allocate a second instance of the Game Manager singleton");
_sharedGameManager = [super alloc];
return _sharedGameManager;
}
return nil;
}
-(id)init
{
self = [super init];
if (self != nil)
{
//Game Manager initialized
CCLOG(#"Game Manager Singleton, init");
isMusicON = YES;
isSoundEffectsON = YES;
hasPlayerDied = NO;
currentScene = kNoSceneUninitialized;
}
return self;
}
-(void) runSceneWithID:(SceneTypes)sceneID
{
SceneTypes oldScene = currentScene;
currentScene = sceneID;
id sceneToRun = nil;
switch (sceneID)
{
case kMainMenuScene:
sceneToRun = [MainMenuScene node];
break;
default:
CCLOG(#"Unknown Scene ID, cannot switch scenes");
return;
break;
}
if (sceneToRun == nil)
{
//Revert back, since no new scene was found
currentScene = oldScene;
return;
}
//Menu Scenes have a value of < 100
if (sceneID < 100)
{
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad)
{
CGSize screenSize = [CCDirector sharedDirector].winSizeInPixels;
if (screenSize.width == 960.0f)
{
//iPhone 4 retina
[sceneToRun setScaleX:0.9375f];
[sceneToRun setScaleY:0.8333f];
CCLOG(#"GM: Scaling for iPhone 4 (retina)");
}
else
{
[sceneToRun setScaleX:0.4688f];
[sceneToRun setScaleY:0.4166f];
CCLOG(#"GM: Scaling for iPhone 3G or older (non-retina)");
}
}
}
if ([[CCDirector sharedDirector] runningScene] == nil)
{
[[CCDirector sharedDirector] runWithScene:sceneToRun];
}
else
{
[[CCDirector sharedDirector] replaceScene:sceneToRun];
}
}
-(void)openSiteWithLinkType:(LinkTypes)linkTypeToOpen
{
CCLOG(#"WE ARE IN openSiteWithLinkType");
NSURL *urlToOpen = nil;
if (linkTypeToOpen == kLinkTypeDeveloperSite)
{
urlToOpen = [NSURL URLWithString:#"http://somesite.com"];
}
if (![[UIApplication sharedApplication]openURL:urlToOpen])
{
CCLOG(#"%#%#",#"Failed to open url:",[urlToOpen description]);
[self runSceneWithID:kMainMenuScene];
}
}
-(void) test
{
CCLOG(#"this is test");
}
#end
Perhaps sharedGameManager is returning nil? This won't cause an error.
Edit: The issue is in the new code you posted:
if (!_sharedGameManager) {
[[self alloc] init];
return _sharedGameManager;
}
return nil;
If _sharedGameManager is non-nil, this will return nil. You want:
if (!_sharedGameManager) {
[[self alloc] init];
}
return _sharedGameManager;
Check this Cocoa With Love article on how to make a proper singleton.