comparing the action in iphone - iphone

user can only listen to three songs before he/she has to login or else they won't be able to listen anymore. for that can I compare IBAction like that (if(IBAction < 3)he stop and he have login for more song. This same question as I Ask before I am trying to solve that give me hint to do.
thanks in advance

IBAction is simply a marker for interface builder so that it knows what methods to provide connections for. If you look at in UINibDecleartions.h you will find
#ifndef IBAction
#define IBAction void
#endif
So no, you can do anything in code with IBAction. What you are looking for is probably something like
//Header
#interface SomeController : UIViewController {
NSInteger numTimesPressedButton;
}
-(IBAction)doSomething:(id)sender;
....
//.m File
- (id)initWithNibName:(NSString *)aNibName bundle:(NSBundle *)aNibBundle{
self = [super initWithNibName:aNibName bundle:aNibBundle];
if(self != nil)
{
numTimesPressedButton = 0;
...
}
return self;
}
-(IBAction)doSomething:(id)sender{
numTimesPressedButton++;
if (numTimesPressed > 3)
[someThing doSomeThingElse];
...
}

You should introduce a member of type int. Initialize it with 0. Each time your play action is called, check if it has reached your threshold. If yes, display the login screen, otherwise increase it by 1.

Related

Call a method from another class when shake is detected

HERE IS THE CODE: http://min.us/mWdMO0n14
I'm a Obj C newbie, so I've searched quite a bit, but haven't found anything that can solve my problem.
I have CalculatorViewController.h and .m and then CalculatorBrain.h and.m (Stanford Lectures)
in CalculatorBrain.m, I have the following method, with all of the variables defined as private in the CalculatorBrain header.
- (void)clearEverythingOnShakeGesture{
operand = 0;
waitingOperation = #"";
waitingOperand = 0;
}
Then in CalculatorBrain.m , I have everything set up to detect shakes, as follows. I've included some of the code above the shake detection just so you have a general idea.
#interface CalculatorViewController()
#property(nonatomic, retain) CalculatorBrain *brain;
#end
#implementation CalculatorViewController
#synthesize brain;
- (CalculatorBrain *)brain {
if (!brain) {
brain = [[CalculatorBrain alloc] init];
}
return brain;
}
-(BOOL)canBecomeFirstResponder{
return YES;
}
-(void)viewDidAppear: (BOOL) animated{
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.subtype == UIEventSubtypeMotionShake)
{
NSLog(#"SHAKE IT!");
[brain clearEverythingOnShakeGesture]; //********** not sure how to call this.
}
}
I'm not sure how to call [brain clearEverythingOnShakeGesture]; , because I get the error "Class method +clearEverythingOnShakeGesture not found, defaults to return type id". However, if I make it a class method, the variables inside are instance variables, which provides another error. Any help greatly appreciated.
The project's AppDelegate posted in the comment above is building the calculator view controller from a nib, then releasing it immediately. The app functions partially, but the UILabel property to be cleared on the shake gesture is nulled at that point.
Also, it's a good practice to declare private properties in the private category, synthesize them with _underscore aliases, and refer to them as self.property outside of synthesized methods.
Are you #import-ing the CalculatorBrain.h? Also, you're using a nice lazy initialization pattern by building the CalculatorBrain in the getter, but you're not calling the getter in the motionBegan: method. Try [self.brain clearEverything ...] to get the brain instance.
I don't see anything in the code that would make the compiler think you have a class method. So that's mysterious. Please double check about the header import. You are correct that the clearEverything... should be an instance method.

Setting a delegate using blocks in iPhone

On a view controller I have multiple textfields, which all use the same delegate. Now in the delegate the code gets really ugly since I have to differentiate between all the textfields (bunch of if/else-if or a switch statement). I came a cross this article:
Blocks in textfield delegates
But from this I still don't understand how this solves the problem? Doesn't this basically call one method and pass it the text and the method has no idea what textfield gave the string? You would still need to differentiate between the textfields, but this time inside the block (with the usual if(textfield == bazTextField)...).
I don't know that it exactly solves the problem so much as shifts it (and into viewDidLoad, which usually gets a bit of mush-mash in it anyway).
However in that example the block itself was being passed in the textfield to run comparisons with and "remembers" the values of all the instance variables as well (if it refers to them), so that's how it knows what text and text field is being dealt with.
I don't see how that code exactly is supposed to help though, since it assigns one block to the single delegate class to be used with all text field delegates - unless perhaps you were supposed to have one per text field, each with a different block. Then you have way more code than you'd have had with the if statements!
The article doesn't make it clear, but I believe the idea is to create one of these blocks (and block delegate objects) for each UITextField that you wish to have respond to textFieldShouldReturn.
hm, maybe I didn't completely understand the article, but I don't see the advantage of using blocks instead of selectors in that concrete example.
you could achieve something similar like this
#interface AlternativeTextFieldDelegate : NSObject <UITextFieldDelegate>
{
SEL selectorToCall;
id objectToCall;
}
- (void) setObjectToCall:(id)obj selector:(SEL)selector;
#end
#implementation AlternativeTextFieldDelegate
- (void) setObjectToCall:(id)obj selector:(SEL)selector
{
objectToCall = obj;
selectorToCall = selector;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[objectToCall performSelector:selectorToCall];
return YES;
}
#end
and the view controller
#interface ViewWithTextFieldsController : UIViewController
{
UITextField *tf1;
AlternativeTextFieldDelegate *delegateForTF1;
UITextField *tf2;
AlternativeTextFieldDelegate *delegateForTF2;
}
// ...IBOutlets and all that...
- (void) tf1ShouldReturn; // handles shouldReturn for tf1
- (void) tf2ShouldReturn; // handles shouldReturn for tf2
#end
#implementation ViewWithTextFieldsController
- (void) viewDidLoad // or wherever
{
delegateForTF1 = [[AlternativeTextFieldDelegate alloc] init];
[delegateForTF1 setObjectToCall:self selector:#selector(tf1ShouldReturn)];
tf1.delegate = delegateForTF1;
delegateForTF2 = [[AlternativeTextFieldDelegate alloc] init];
[delegateForTF2 setObjectToCall:self selector:#selector(tf2ShouldReturn)];
tf2.delegate = delegateForTF2;
}
// ...
#end
don't really know if that's any better than chaining if-elses though.
it seems to me that this complicates things more than the problem it solves.

switch state in the FlipsideViewController?

in my app i have a switch in the flipsideview when i set it to on all work properly then i touch Done to return to the main view, now when i touch again the info button it appear off till now no problem but if i touch Done button (without touch the switch) it will called the function with off statement my question is how to check if the switch (on FlipsideView) is on let it on where i should write my code maybe i'll do it by myself but where to write the code
You could store the state as a member variable, then update the UI in viewWillAppear:animated:. For example, in FlipsideViewController.h file, declare a member variable called switchIsOn:
#interface FlipsideViewController : UIViewController {
BOOL switchIsOn;
// Other member variables here
}
#property (nonatomic) BOOL switchIsOn;
Then in FlipsideViewController.m:
#synthesize switchIsOn;
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.switch setOn:self.switchIsOn animated:NO];
}
You can set the value of self.switchIsOn in response to the switch being toggled. e.g. create a method like this:
-(IBAction)handleSwitch:(id)sender {
self.switchIsOn = self.switch.on;
}
and then bind that method to the switch's Value Changed event.
Hope this helps.

Different actions on alert views buttons, depending on the alert view

I have 3 alert views in my apps.
'wonAlert'
'lostAlert'
'nagAlert'
I implement this to give them actions.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
This used to work fine, when I had just the 'wonAlert' and 'lostAlert', they had a dismiss and a learn more button that took them to wikipedia,
now I want the nag alert to take them to the app store.
how can I make it so the above method knows which alert view the tap is coming from, or something like that?
Cheers, Sam
It sounds like you've got the UIAlertViews in variables, so I'd use them:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView == wonAlert) {
//DO STUFF
}
else if (alertView == lostAlert) {
//DO OTHER STUFF
}
else if (alertView == nagAlert) {
//OPEN APP STORE
}
}
More than one view can have the same tag and you can easily mistype the title or change it and forget to update the delegate method.
In your view controller header file, add <UIAlertViewDelegate> so that it agrees to handle UIAlertView delegate methods:
#interface MyViewController : UIViewController <UIAlertViewDelegate> { ... }
In the implementation of your view controller, add the following delegate method:
- (void) alertView:(UIAlertView *)_actionSheet clickedButtonAtIndex:(NSInteger)_buttonIndex {
if ([_actionSheet.title isEqualToString:#"titleOfMyAlertView"]) {
if (_buttonIndex == 0) {
// do stuff for first button
}
else if (_buttonIndex == 1) {
// do something for second button
}
// etc. if needed
}
}
The _actionSheet.title property can be used to distinguish between alert views. My recommendation is to use NSString constants or NSLocalizedString(), if you have a localized strings table, to title your alert views.
I answered a similar question here:
Alert with 2 buttons
the correct way to do this is using the tag property of alerts
upon creating each alert, set its tag variable by adding:
alertName.tag = #; //ex: alertName.tag = 1
Then, in the clickedButtonAtIndex method, you will need to add an 'if' block for each alert you have as shown in the folllowing code:
if(alert.tag == 1)
{
if (buttonIndex == 0)
{
//do stuff
}
else
{
//do other stuff
}
}
if(alert.tag == 2)
///...etc
I would do what Alex suggests, but use the tag property of the AlertView to determine which AlertView had been used.

How can I pass a parameter to this function?

I have the following code:
[replyAllBtn addTarget:self.target action:#selector(ReplyAll:) forControlEvents:UIControlEventTouchUpInside];
- (void)replyAll:(NSInteger)tid {
// some code
}
How can I send a parameter to the ReplyAll function?
The replyAll method should accept (id)sender. If a UIButton fired the event, then that same UIButton will be passed as the sender. UIButton has a property "tag" that you can attach your own custom data to (much like .net winforms).
So you'd hook up your event with:
[replyAllBtn addTarget:self.target action:#selector(ReplyAll:) forControlEvents:UIControlEventTouchUpInside];
replyAllBtn.tag=15;
then handle it with:
(void) ReplyAll:(id)sender{
NSInteger *tid = ((UIControl*)sender).tag;
//...
A selector function will normally be defined as such:
- (void) ReplyAll:(id)sender;
So the only parameter an action will ever receives is the actual control that called it.
You could just add a property to your control that can be read in replyAll
If you want to send an int value, set the tag of the button = the int value you want to pass. Then you can access the tag value of the button to get the int you wanted.
NSInteger is not a pointer. Try this
NSInteger tid = sender.tag;
It's working now :D.
{
NSInteger tid = [sender tag];
}
The MVC model used in Cocoa works differently. Basically, the idea is that a control (=view) such as a button only lets a function know it was pressed, not knowing what this means. The function then has to know all the dynamics and dependencies. In your case, it's the function that has to find the parameter. To accomplish that, you'll "bind" other objects to the function (= controller).
I suggest you read a few Cocoa tutorials first if you want to get ahead with iPhone programming.
There's a few good ways to do this. The two most commonly implemented would be to have the controller (who's receiving the action) know about possible senders, or having the sender itself have a method that you end up using to determine the proper behavior.
The first (my preferable way, but it's easy to argue the opposite) would be implemented like such:
#interface Controller : NSObject {
UIButton *_replyToSender;
UIButton *_replyToAll;
}
- (void)buttonClicked:(id)sender;
#end
#implementation Controller
- (void)buttonClicked:(id)sender {
if (sender == _replyToSender) {
// reply to sender...
} else if (sender == _replyToAll) {
// reply to all...
}
}
#end
The second way would be implemented in a manner such as:
typedef enum {
ReplyButtonTypeSender = 1,
ReplyButtonTypeAll,
} ReplyButtonType;
#interface Controller : NSObject {
}
- (void)buttonClicked:(id)sender;
#end
#interface MyButton : UIButton {
}
- (ReplyButtonType)typeOfReply;
#end
#implementation Controller
- (void)buttonClicked:(id)sender {
// You aren't actually assured that sender is a MyButton, so the safest thing
// to do here is to check that it is one.
if ([sender isKindOfClass:[MyButton class]]) {
switch ([sender typeOfReply]) {
case ReplyButtonTypeSender:
// reply to sender...
break;
case ReplyButtonTypeAll:
// reply to all...
break;
}
}
}
#end