How do I get my segment UISegmentedControl to respond? - iphone

In my ViewController I have added A UISegmentedControl to preform different task for a different selection of the Segmented Control. Its a cards matching game.
And everything seems to work just fine, except that the Segmented Control is not reacting to the selection.., I created a switch to do something in case of "twoCardGame" and in case of "threeCardGame".
From what I understand it would be good to define those variables with enum, which I did in the top part of the controller, but it seems like i'm missing something in it..
Sorry if its not so directed, but my controller is pretty short and simple, would appreciate if you can tell me what am I doing wrong in term of the UISegmentedControl.
Here it is:
#import "CardGameViewController.h"
#import "PlayingCardsDeck.h"
#import "CardMatchingGame.h"
enum CardGame {
twoCardGame,
threeCardGame
};
#interface CardGameViewController ()
#property (weak, nonatomic) IBOutlet UILabel *notificationLabel;
#property (weak, nonatomic) IBOutlet UILabel *scoreCounter;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
#property (strong, nonatomic) CardMatchingGame *game;
#property (weak, nonatomic) IBOutlet UISegmentedControl *numberOfCardsToPlayWith;
#end
#implementation CardGameViewController
//creating the getter method that creates a new card game.
- (CardMatchingGame *)game {
if (!_game) {
_game = [[CardMatchingGame alloc] initWithCardCount:self.cardButtons.count
usingDeck:[[PlayingCardsDeck alloc] init]];
_game.numberOfCardsToPlayWith = [self selectNumberOfCardsToPlayWith];
}
return _game;
}
//creating a setter for the IBOutletCollection cardButtons
-(void)setCardButtons:(NSArray *)cardButtons {
_cardButtons = cardButtons;
[self updateUI];
}
- (void)updateUI {
for (UIButton *cardButton in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]];
[cardButton setTitle:card.contents forState:UIControlStateSelected];
[cardButton setTitle:card.contents
forState:UIControlStateSelected|UIControlStateDisabled];
cardButton.selected = card.isFaceUp;
cardButton.enabled = !card.isUnplayable;
cardButton.alpha = card.isUnplayable ? 0.3 : 1.0;
}
self.scoreCounter.text = [NSString stringWithFormat:#"Score: %d", self.game.score];
}
//Here I created a method to flipCards when the card is selected, and give the user a random card from the deck each time he flips the card. After each flip i'm incrementing the flipCount setter by one.
- (IBAction)flipCard:(UIButton *)sender {
[self.game flipCardAtIndex:[self.cardButtons indexOfObject:sender]];;
[self updateUI];
}
//sending an alert if the user clicked on new game button
- (IBAction)newGame:(UIButton *)sender {
UIAlertView* mes=[[UIAlertView alloc] initWithTitle:#"Think about it for a sec..?" message:#"This will start a new game" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[mes show];
}
- (NSUInteger)selectNumberOfCardsToPlayWith {
switch (self.numberOfCardsToPlayWith.selectedSegmentIndex) {
case twoCardGame:
return 2;
case threeCardGame:
return 3;
default:
return 2;
}
[self updateUI];
}
//preforming an action according to the user choice for the alert yes/no to start a new game
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [alertView cancelButtonIndex]) {
self.game = nil;
for (UIButton *button in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:button]];
card.isUnplayable = NO;
card.isFaceUp = NO;
button.alpha = 1;
}
self.notificationLabel.text = nil;
[self updateUI];
}
}
#end

Well, I don't see any addTarget: calls to segmented control. So you probably set them in Interface Builder. Check IB connections. If everything in IB seems ok -- try to addTarget: programmatically.

I think you'd be better off creating a selector and adding it to the segmented control target like so:
[segmentedControl addTarget:self
action:#selector(selectNumberOfCardsToPlayWith:)
forControlEvents:UIControlEventValueChanged];
- (NSUInteger)selectNumberOfCardsToPlayWith:(UISegmentedControl *)control {
switch (control.selectedSegmentIndex) {
case twoCardGame:
return 2;
case threeCardGame:
return 3;
default:
return 2;
}
[self updateUI];
}
This should work fine. Using similar code myself currently.

Related

How to use UISwitch to tell the controller to check a certain condition in a method

In my card matching game:
-I have a method that checking cards that were flipped in certain index. It's basically the whole logic in the app.
-I have another method that checks the matching.
Now, I created a switch button in my view controller that will tell the controller that the user changed the mode for "3" cards instead of the basic mode (2 cards).
My issue is, how do i tell the controller to check in the matching method if there is more than 2 matches..it's driving me crazy please try to help me figure this out.
I also have in the controller an updateUI method that making cards that are matched fade away so I need to make sure it behaves the same.
The following code show's the flipCardAtIndex method, matching method & view controller in the same order:
CardMatchingGame.m (the last method is flipCardAtIndex):
#import "CardMatchingGame.h"
#import "PlayingCardsDeck.h"
#interface CardMatchingGame()
#property (readwrite, nonatomic) int score;
#property (strong, nonatomic) NSMutableArray *cards;
#property (strong, nonatomic) NSString *notification;
#end
#implementation CardMatchingGame
-(NSMutableArray *) cards {
if (!_cards) _cards = [[NSMutableArray alloc] init];
return _cards;
}
-(id)initWithCardCount:(NSUInteger)count usingDeck:(Deck *)deck {
self = [super init];
if (self) {
for (int i = 0; i < count; i++) {
Card *card = [deck drawRandonCard];
if (!card) {
self = nil;
} else {
self.cards[i] = card;
}
}
}
return self;
}
-(Card *) cardAtIndex:(NSUInteger)index {
return (index < self.cards.count) ? self.cards[index] : nil;
}
#define FLIP_COST 1
#define MISMATCH_PENALTY 2
#define BONUS 4
-(void) flipCardAtIndex:(NSUInteger)index {
Card *card = [self cardAtIndex:index];
if (!card.isUnplayable) {
if (!card.isFaceUp) {
for (Card *otherCard in self.cards) {
if (otherCard.isFaceUp && !otherCard.isUnplayable) {
NSMutableArray *myCards = [[NSMutableArray alloc] init];
[myCards addObject:otherCard];
int matchScore = [card match:myCards];
if (matchScore) {
otherCard.unplayble = YES;
card.unplayble = YES;
self.notification = [NSString stringWithFormat:#"%# & %# match!", card.contents, otherCard.contents];
self.score += matchScore * BONUS;
} else {
otherCard.faceUp = NO;
self.score -= MISMATCH_PENALTY;
self.notification = [NSString stringWithFormat:#"%# did not matched to %#", card.contents, otherCard.contents];
}
break;
}
}
self.score -= FLIP_COST;
}
card.faceUp = !card.isFaceUp;
}
}
#end
PlayingCards.m (Only the first method, matching method) :
#import "PlayingCards.h"
#implementation PlayingCards
#synthesize suit = _suit;
//overriding the :match method of cards to give different acore if its only a suit match or a number match
-(int)match:(NSArray *)cardToMatch {
int score = 0;
for (int i = 0; i < cardToMatch.count; i++) {
PlayingCards *nextCard = cardToMatch[i];
if ([nextCard.suit isEqualToString:self.suit]) {
score += 1;
} else if (nextCard.rank == self.rank) {
score += 4;
}
}
return score;
}
My view controller (the last method is the one for the switch button) :
#import "CardGameViewController.h"
#import "PlayingCardsDeck.h"
#import "CardMatchingGame.h"
#interface CardGameViewController ()
#property (weak, nonatomic) IBOutlet UILabel *flipsLabel;
#property (weak, nonatomic) IBOutlet UILabel *notificationLabel;
#property (weak, nonatomic) IBOutlet UILabel *scoreCounter;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
#property (strong, nonatomic) CardMatchingGame *game;
#property (nonatomic) int flipsCount;
#property (nonatomic) NSNumber *mode;
//#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#end
#implementation CardGameViewController
#synthesize mode = _mode;
//creating the getter method that creates a new card game.
-(CardMatchingGame *) game {
if (!_game) _game = [[CardMatchingGame alloc] initWithCardCount:self.cardButtons.count usingDeck:[[PlayingCardsDeck alloc] init]];
return _game;
}
//creating a setter for the IBOutletCollection cardButtons
-(void) setCardButtons:(NSArray *)cardButtons {
_cardButtons = cardButtons;
[self updateUI];
}
//creating the setter for the flipCount property. Whick is setting the flipsLabel to the right text and adding the number of counts.
-(void) setFlipsCount:(int)flipsCount {
_flipsCount = flipsCount;
self.flipsLabel.text = [NSString stringWithFormat:#"Flips: %d", self.flipsCount];
}
-(void) updateUI {
for (UIButton *cardButton in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]];
[cardButton setTitle:card.contents forState:UIControlStateSelected];
[cardButton setTitle:card.contents forState:UIControlStateSelected|UIControlStateDisabled];
cardButton.selected = card.isFaceUp;
cardButton.enabled = !card.unplayble;
if (card.unplayble) {
cardButton.alpha = 0.1;
}
//updating the score
self.scoreCounter.text = [NSString stringWithFormat:#"Score: %d", self.game.score];
//if notification in CardMatchingGame.m is no nil, it will be presented
if (self.game.notification) {
self.notificationLabel.text = self.game.notification;
}
}
}
//Here I created a method to flipCards when the card is selected, and give the user a random card from the deck each time he flips the card. After each flip i'm incrementing the flipCount setter by one.
- (IBAction)flipCard:(UIButton *)sender {
[self.game flipCardAtIndex:[self.cardButtons indexOfObject:sender] forMode:self.mode];
self.flipsCount++;
[self updateUI];
}
//sending an alert if the user clicked on new game button
- (IBAction)newGame:(UIButton *)sender {
UIAlertView* mes=[[UIAlertView alloc] initWithTitle:#"Are you sure..?" message:#"This will start a new game" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[mes show];
}
//preforming an action according to the user choice for the alert yes/no to start a new game
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [alertView cancelButtonIndex]) {
self.flipsCount = 0;
self.game = nil;
for (UIButton *button in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:button]];
card.unplayble = NO;
card.faceUp = NO;
button.alpha = 1;
}
self.notificationLabel.text = nil;
[self updateUI];
}
}
-(void) setMode:(NSNumber *)mode {
mode = _mode;
}
-(void) switchValueChange:(id)sender {
UISwitch *Switch = (UISwitch *) sender;
NSNumber *twoCards = [NSNumber numberWithInt:2];
NSNumber *threeCards = [NSNumber numberWithInt:3];
if (Switch.on) {
self.mode = twoCards;
}
else
{
self.mode = threeCards;
}
}
- (void)viewDidLoad
{
UISwitch *mySwitch;
[super viewDidLoad];
[mySwitch addTarget:self action:#selector(switchValueChange:) forControlEvents:UIControlEventValueChanged];
[self updateUI];
}
#end
Actually, getting the switch value is the easy part. You can get set a referencing outlet from your switch to your viewController (CardGameViewController), and in your view controller's viewDidLoad method, add the method to listen for changes to switch's value:
[mySwitch addTarget:self action:#selector(switchValueChange:) forControlEvents:UIControlEventValueChanged];
Add a new property called NSNumber *mode in your CardGameViewController and synthesize it.
Now you can update the "mode" (which I believe could be an instance variable) in switchValueChanged method:
- (void)switchValueChange:(id)sender
{
UISwitch *switch = (UISwitch *) sender;
if (sender.on)
self.mode = 2;
else
self.mode = 3;
}
If my assumption is right, then by "mode" you mean how many cards to match, is that correct? 2 means, that atleat 2 cards should be same when faced up, and 3 means, that 3 cards should match in suit or number.
Start by changing the match method in your PlayingCards to something like this (accepting another parameter named mode) (You might have to update the same method in its parent class too):
//overriding the :match method of cards to give different acore if its only a suit match or a number match
-(int)match:(NSArray *)cardToMatch forMode:(NSNumber *) mode{
int score = 0;
int cardsMatched = 0;
for (int i = 0; i < cardToMatch.count; i++) {
PlayingCards *nextCard = cardToMatch[i];
if ([nextCard.suit isEqualToString:self.suit]) {
score += 1;
cardsMatched++;
} else if (nextCard.rank == self.rank) {
score += 4;
cardsMatched++;
}
if (cardsMatched >= [mode intValue])
break;
}
return score;
}
Now, in your CardMatchingGame.m method, change the flipCardAtIndex method to this (accepting another parameter named mode):
-(void) flipCardAtIndex:(NSUInteger)index forMode (NSNumber *mode) {
Card *card = [self cardAtIndex:index];
if (!card.isUnplayable) {
if (!card.isFaceUp) {
NSMutableArray *myFaceUpCards = [[NSMutableArray alloc] init];
// UPDATED: Loop through all the cards that are faced up and add them to an array first
for (Card *otherCard in self.cards) {
if (otherCard.isFaceUp && !otherCard.isUnplayable && orderCard != card) {
[myCards addObject:otherCard];
}
// UPDATED: Now call the method to do the match. The match method now takes an extra parameter
int matchScore = [card match:myCards forMode:mode];
if (matchScore) {
otherCard.unplayble = YES;
card.unplayble = YES;
self.notification = [NSString stringWithFormat:#"%# & %# match!", card.contents, otherCard.contents];
self.score += matchScore * BONUS;
} else {
otherCard.faceUp = NO;
self.score -= MISMATCH_PENALTY;
self.notification = [NSString stringWithFormat:#"%# did not matched to %#", card.contents, otherCard.contents];
}
}
self.score -= FLIP_COST;
}
card.faceUp = !card.isFaceUp;
}
}
Finally, change call to
[self.game flipCardAtIndex:[self.cardButtons indexOfObject:sender]];
in
- (IBAction)flipCard:(UIButton *)sender
method of CardGameViewController to
[self.game flipCardAtIndex:[self.cardButtons indexOfObject:sender] forMode:self.mode];
Take a look and see if that makes sense.
Remove #property (weak, nonatomic) IBOutlet UISwitch *mySwitch; from your .m class.
Instead, go to your storyboard, click on the controller that has the switch, then click on the Assistant Editor button on top right (looks like a face). It will open up CardGameViewController.h. Now right click on the switch view on the storyoard, and click and drag from New Referencing Outlet to CardViewController.h. This is how you reference your switch into your controller.
Now that you have the switch variable in the interface file, go to your implementation file (CardGameViewController.m) and synthesize the variable:
#synthesize mySwitch = _mySwitch;
Now, change your viewDidLoad method to this:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.mySwitch addTarget:self action:#selector(switchValueChange:) forControlEvents:UIControlEventValueChanged];
[self updateUI];
}
Also remove setMode method. If you are synthesizing mode variable, then you don't need it.
Give it a try now. You know how to debug in xcode using breakpoints?

How to make reference to a UIButton in viewDidLoad?

This is my action UIButton:
-(IBAction)favoriteButtonPressed:(id)sender
{
if (favoriteButtonSelected == 0) {
[sender setSelected:YES];
favoriteButtonSelected = 1;
[sender setImage:[UIImage imageNamed:#"favoritedItem.png"]];
[selectedObject setValue:#"Yes" forKey:#"Favorite"];
} else {
[sender setSelected:NO];
favoriteButtonSelected = 0;
[sender setImage:[UIImage imageNamed:#"notFavorite.png"]];
[selectedObject setValue:#"No" forKey:#"Favorite"];
}
}
How to make a reference to the button in viewDidLoad? To make the following code work:
- (void)viewDidLoad
{
[super viewDidLoad];
if ([[selectedObject valueForKey:#"Favorite"] isEqual:#"Yes"]) {
[favoriteButton setImage:[UIImage imageNamed:#"favoritedItem.png"]];
[favoriteButton setSelected:YES];
favoriteButtonSelected = 1;
} else {
[favoriteButton setImage:[UIImage imageNamed:#"notFavorite.png"]];
[favoriteButton setSelected:NO];
favoriteButtonSelected = 0;
}
}
EDIT FOR PROGRESS:
Now I did like this: Ctrl-drag from UIButton to ViewController in Assistant Editor. Connection: Outlet, name: favoriteButton, type: UIButton, storage: weak. But errors still there. + error for synthesize & error in viewDidUnload.. suggestion?
The Assistant Editor header for View Controller with the added property from Ctrl-drag:
#interface DetailViewController : UIViewController {
IBOutlet UIScrollView *viewScroller;
}
#property (nonatomic, strong) IBOutlet UILabel *mylLabel;
#property (nonatomic, strong) NSString *selectedObj;
#property (strong, nonatomic) NSArray *detailsDataSource;
#property int detailIndex;
#property (weak, nonatomic) IBOutlet UIButton *favoriteButton; //The added property
#end
Control drag from your button to the header of the viewcontroller to create a property. (You can do this while in assistant mode, second button on the top right)..
Then you can reference your button from wherever using that property
What you need is an IBOutlet for the button.
You can ctrl+drag the button from XIB file to the header of this class, and create a IBOutlet property named favoriteButton.
Well unless you are using the latest version of Xcode you do need to #synthesize favorite button.
You really should post your error messages you are just making people guess.

Resign keyboard immediately after button press

I have a button, "getResponse", that makes a XMLRPC call to a server after you put in an IP address in a UITextField. Id like the "getResponse" button to first resign the keyboard if its up THEN make the call to the server.
As it is now, if the keyboard is up, it will make the call to the server, retrive the info or the error if no valid server found, THEN resign the keyboard.
I know its probably something very easy but I can't for the life of me figure it out. Any help would be great, thanks!
Code:
h.
#import <UIKit/UIKit.h>
#import "XMLRPCResponse.h"
#import "XMLRPCRequest.h"
#import "XMLRPCConnection.h"
#interface SecondViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate> {
IBOutlet UILabel *helloResponse;
IBOutlet UILabel *SumCountsResponse;
IBOutlet UITextField *serverInput;
IBOutlet UIPickerView *pickerView;
IBOutlet UILabel *pickerTrap;
IBOutlet UIAlertView *alert;
NSMutableArray * pickerViewArray;
int trapSelected;
}
#property(nonatomic,retain) IBOutlet UILabel *helloResponse;
#property(nonatomic,retain) IBOutlet UILabel *SumCountsResponse;
#property(nonatomic,retain) IBOutlet UITextField *serverInput;
#property(nonatomic,retain) IBOutlet UIPickerView *pickerView;
#property(nonatomic,retain) IBOutlet UILabel *pickerTrap;
#property(nonatomic,retain) IBOutlet UIAlertView *alert;
- (IBAction)getResponse:(id)sender;
- (IBAction)serverInputReturn:(id)sender;
- (IBAction)backgroundTouched:(id)sender;
#end
m.
#import "SecondViewController.h"
#implementation SecondViewController
#synthesize helloResponse;
#synthesize SumCountsResponse;
#synthesize serverInput;
#synthesize pickerView;
#synthesize pickerTrap;
#synthesize alert;
-(IBAction)serverInputReturn:(id)sender { //resign keyboard on 'return' button
[sender resignFirstResponder];
}
-(IBAction)backgroundTouched:(id)sender { //resign keyboard on background touch
[serverInput resignFirstResponder];
}
-(IBAction)getResponse: (id) sender {
[self serverInputReturn:self]; //trying to call method to resign keyboard first
//setup IP call for XMLserver
NSString *server = serverInput.text;
NSString *http = #"http://";
server = [server stringByAppendingString:#":8080/RPC2"];
server = [http stringByAppendingString:server];
//Begin calls to XMLRPC server for data return
XMLRPCRequest *requestHello = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
[requestHello setMethod:#"hello" withObjects:[NSArray arrayWithObjects: nil]];
NSString *resultHello = [self executeXMLRPCRequest:requestHello];
[requestHello release];
XMLRPCRequest *requestSumCounts = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
[requestSumCounts setMethod:#"SumCountsString" withObjects:[NSArray arrayWithObjects: nil]];
NSString *resultSumCounts = [self executeXMLRPCRequest:requestSumCounts];
[requestSumCounts release];
XMLRPCRequest *requestTrapCountX = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
[requestTrapCountX setMethod:#"TrapCountString" withObjects:[NSArray arrayWithObjects: [NSNumber numberWithInt:trapSelected], nil]];
NSString *resultTrapCountX = [self executeXMLRPCRequest:requestTrapCountX];
[requestTrapCountX release];
if (![resultHello isKindOfClass:[NSString class]]){
alert = [[UIAlertView alloc] initWithTitle:#"Error: Invalid Server Address" message:#"Please Check Server Address and Try Again" delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
}
else{
helloResponse.text = resultHello;
SumCountsResponse.text = resultSumCounts;
pickerTrap.text = resultTrapCountX;
}
}
}
- (id)executeXMLRPCRequest:(XMLRPCRequest *)req {
XMLRPCResponse *userInfoResponse = [XMLRPCConnection sendSynchronousXMLRPCRequest:req];
if ([userInfoResponse isKindOfClass:[NSError class]]) {
return alert;
}
else{
return [userInfoResponse object];
}
}
Instead of
[self serverInputReturn:self];
Try
[self serverInputReturn:self.serverInput];
You need to pass the UITextField not the UIViewController.
Make sure that you are setting the UITextField's delegate to the UIViewController via
self.serverInput.delegate = self;

iPhone UISwitch Problem

My switch will not reset when I call clearbtn, it just remains in the same state. Also when I call pushme and check to see if the switch is on or off it always detects its off, what would be causing this? How can I fix this? I created a Window-based application just to play around, I didnt create a UIViewController yet, is that what is causing this issue? Thank You.
My .h file
UIButton *_pushmebutton;
UITextField *_nametextfield;
UILabel *_pushmelabel;
UIImageView *_bgimage;
UISwitch *_bgswitch;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UIButton *pushmebutton;
#property (nonatomic, retain) IBOutlet UITextField *nametextfield;
#property (nonatomic, retain) IBOutlet UILabel *pushmelabel;
#property (nonatomic, retain) IBOutlet UISwitch *bgswitch;
#property (nonatomic, retain) IBOutlet UIImageView *bgimage;
- (IBAction)textFieldReturn:(id)sender;
- (IBAction)backgroundTouched:(id)sender;
- (IBAction)pushme:(id)sender;
- (IBAction)clearbtn:(id)sender;
- (IBAction)changebg:(id)sender;
My .m File
#import "MyFirstAppAppDelegate.h"
#implementation MyFirstAppAppDelegate
#synthesize window=_window;
#synthesize pushmebutton = _pushmebutton;
#synthesize nametextfield = _nametextfield;
#synthesize pushmelabel = _pushmelabel;
#synthesize bgswitch = _bgswitch;
#synthesize bgimage = _bgimage;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
- (void)dealloc
{
[_window release];
[_pushmebutton release];
[_pushmelabel release];
[_nametextfield release];
[super dealloc];
}
-(IBAction)pushme:(id)sender
{
if([_nametextfield.text length] == 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please Enter Your Name" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil]; [alert show]; [alert release];
}
else
{
[_nametextfield resignFirstResponder];
if(_bgimage.hidden == false)
{
self.pushmelabel.backgroundColor = [UIColor redColor];
}
if(_bgswitch.on)
{
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %# Thanks for using the App! Switch: On!", _nametextfield.text];
self.pushmelabel.text = msg;
}
else
{
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %# Thanks for using the App! Switch: Off!", _nametextfield.text];
self.pushmelabel.text = msg;
}
}
}
-(IBAction)clearbtn:(id)sender;
{
_nametextfield.text = #"";
_pushmelabel.text = #"";
_pushmelabel.backgroundColor = [UIColor clearColor];
[_bgswitch setOn:NO animated:YES];
}
-(IBAction)textFieldReturn:(id)sender
{
[sender resignFirstResponder];
}
-(IBAction)backgroundTouched:(id)sender
{
[_nametextfield resignFirstResponder];
}
-(IBAction)changebg:(id)sender
{
if(_bgimage.hidden == false)
{
_bgimage.hidden = true;
_pushmelabel.backgroundColor = [UIColor clearColor];
}
else if(_bgimage.hidden == true)
{
_bgimage.hidden = false;
if([_pushmelabel.text length] > 0)
{
_pushmelabel.backgroundColor = [UIColor redColor];
}
}
}
#end
My hunch is telling me that you haven't connected the outlet to the switch in IB. Check for that connection and make it if necessary. If the connection is already there, NSLog your switch in the pushme method and see if it comes out to nil.
You really shouldn't use ApplicationDelegate like this - it's intended to be the delegate for application events, and that is all it should be. Since it doesn't inherit from UIViewController, it wont participate in normal view lifecycle stuff, so it's very likely that is your problem. Put your view stuff in a UIViewController, and try your switch again.

iPhone iOS4 low-level camera control?

Is there a way to manually set low-level still-camera settings like shutter speed, aperture, or ISO in iOS4 on the iPhone 4? I don't think it exists in the official SDK but perhaps someone has found some private APIs to allow this?
I find my iPhone 4 camera to be unusable because even in fairly decent lighting, it always insists on shooting at the slowest 1/15th a second shutter speed causing motion blur if the subject is moving at all.
Thanks!
Not directly. Please file a bug report.
Yes, there may be private APIs available, but that's of limited use.
Try this, I could be useful for you:
#interface MyViewController ()
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#property (nonatomic, retain) IBOutlet UIToolbar *myToolbar;
#property (nonatomic, retain) OverlayViewController *overlayViewController;
#property (nonatomic, retain) NSMutableArray *capturedImages;
// toolbar buttons
- (IBAction)photoLibraryAction:(id)sender;
- (IBAction)cameraAction:(id)sender;
#end
#implementation MyViewController
- (void)viewDidLoad
{
self.overlayViewController =
[[[OverlayViewController alloc] initWithNibName:#"OverlayViewController" bundle:nil] autorelease];
// as a delegate we will be notified when pictures are taken and when to dismiss the image picker
self.overlayViewController.delegate = self;
self.capturedImages = [NSMutableArray array];
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
// camera is not on this device, don't show the camera button
NSMutableArray *toolbarItems = [NSMutableArray arrayWithCapacity:self.myToolbar.items.count];
[toolbarItems addObjectsFromArray:self.myToolbar.items];
[toolbarItems removeObjectAtIndex:2];
[self.myToolbar setItems:toolbarItems animated:NO];
}
}
- (void)viewDidUnload
{
self.imageView = nil;
self.myToolbar = nil;
self.overlayViewController = nil;
self.capturedImages = nil;
}
- (void)dealloc
{
[_imageView release];
[_myToolbar release];
[_overlayViewController release];
[_capturedImages release];
[super dealloc];
}
- (void)showImagePicker:(UIImagePickerControllerSourceType)sourceType
{
if (self.imageView.isAnimating)
[self.imageView stopAnimating];
if (self.capturedImages.count > 0)
[self.capturedImages removeAllObjects];
if ([UIImagePickerController isSourceTypeAvailable:sourceType])
{
[self.overlayViewController setupImagePicker:sourceType];
[self presentModalViewController:self.overlayViewController.imagePickerController animated:YES];
}
}
- (IBAction)photoLibraryAction:(id)sender
{
[self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
}
- (IBAction)cameraAction:(id)sender
{
[self showImagePicker:UIImagePickerControllerSourceTypeCamera];
}
// as a delegate we are being told a picture was taken
- (void)didTakePicture:(UIImage *)picture
{
[self.capturedImages addObject:picture];
}
// as a delegate we are told to finished with the camera
- (void)didFinishWithCamera
{
[self dismissModalViewControllerAnimated:YES];
if ([self.capturedImages count] > 0)
{
if ([self.capturedImages count] == 1)
{
// we took a single shot
[self.imageView setImage:[self.capturedImages objectAtIndex:0]];
}
else
{
// we took multiple shots, use the list of images for animation
self.imageView.animationImages = self.capturedImages;
if (self.capturedImages.count > 0)
// we are done with the image list until next time
[self.capturedImages removeAllObjects];
self.imageView.animationDuration = 5.0; // show each captured photo for 5 seconds
self.imageView.animationRepeatCount = 0; // animate forever (show all photos)
[self.imageView startAnimating];
}
}
}
#end