switch state in the FlipsideViewController? - iphone

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.

Related

How can I stop values being passed both ways unnecessarily?

I am making a color picker. I have the following code:
View controller.h:
#interface ColorPickerViewController : UIViewController <HueSliderDelegate> {
HueSlider *hueSlider;
float hue;
}
#property (nonatomic, assign) float hue;
#end
View controller.m:
-(void)setHue:(float)hueLocal {
hue = hueLocal;
hueSlider.hue = self.hue;
}
-(void)hueChanged {
self.hue = hueSlider.hue;
}
HueSlider.h:
#protocol HueSliderDelegate <NSObject>
-(void)hueChanged;
#end
#interface HueSlider : UISlider {
HueSlider *hueSlider;
float hue;
}
#property (nonatomic, assign) float hue;
#end
HueSlider.m:
//the hue float can be set when the user moves the slider
-(void)setHue:(float)hueLocal {
hue = hueLocal;
slider.value = self.hue;
[self.delegate hueChanged];
}
The problem is that the user changes the value, the slider sends the change up to the view controller. The view controller then changes it's value for hue, which sends the change back down to the slider. Sending it back down to the slider isn't needed and if the user is moving the slider along, it'll jump back to where it was. Any advice on how I can code this differently to stop this from happening?
Note: It's not actually a slider, but I put the problem into this context because it's less complex than describing the custom control that I've made, which is similar to a slider.
Add an additional BOOL property to control this. Add the property to your view controller class; flip the value whenever the user begins to move the slider (could do this in touchesBegan or whatever method actually moves the slider). The property could be called anything, but the idea is:
BOOL userIsAdjustingValue;
Initialize it to NO in one of your class setup methods (init, viewDidLoad). When your user touches/begins modifying the value via the interface slider, set it to YES. You could achieve this via another delegate method, or, assuming your slider is a subview and your responder chain is intact, you could probably trigger it in the controller directly with touchesBegan and then off again with touchesEnded.
Add an if statement surrounding the call in your controller that updates the slider value. If userIsAdjusttingValue == YES, then refrain from allowing the controller to update it.
When the user is done manipulating the slider, set the value back to NO, and your controller is free to manipulate the value of the slider as it deems fit.

Strange behaviour in viewWillAppear

I have a TabBar Controller with some tab bar item in it.
The first time that a user tap on a tab bar item, I want that a alertview is opened, so that the user can read some little instruction tips.
I have a global variable (say CONFIG), that hold some boolean valeus (CONFIG.tip1AlreadySeen, CONFIG.tip1AllreadySeen, etc.). All these boolean values are initializated to NO.
When the user tap a tab bar item, the viewWillAppear method in its viewcontroller is executed. In this method I put a code like this one:
-(void) viewVillAppear: (BOOL) animated {
extern CONFIG; // <- it's not the actual code but it indicates that a global variable must be used
[super viewWillAppear: animated];
if(CONFIG.tip1AlreadySeen == NO) {
CONFIG.tip1AlreadySeen = YES;
// code for showing the alertview
}
}
The strange thing is that this piece of code works perfectly in one viewcontroller but doesn't work in one another.
With some debug, I fidd out that in the another viewcontroller the code is executed but the assigment CONFIG.tipAlreadySeen = YES doesn't modify the actual value of CONFIG.tipAlreadySeen. This value is still NO. Unbelievable!!!
A little workaround was using the viewDidAppear method for changing the value:
-(void) viewVillAppear: (BOOL) animated {
extern CONFIG; // <- it's not the actual code but it indicates that a global variable must be used
[super viewWillAppear: animated];
if(CONFIG.tip1AlreadySeen == NO) {
// code for showing the alertview
}
}
-(void) viewDidAppear: (BOOL) animated {
extern CONFIG;
CONFIG.tip1AlreadySeen = YES;
}
...But I really did not understand what happened!!! Someone of you could explain this behaviour?
Thanks in advance!
Marco
Why must this be global and not contained in the view controller itself? Just a simple BOOL #property on your view controller that is toggled. And, to maintain this persistent across multiple runs of your application, save out the result to NSUserDefaults, which you in turn check each time you init your view controller.

How to obtain the container class of an Actionsheet?

I am a green hand of iPhone development, and I just get confused about a method UIActionsheet,which is the "showInView". So what is the relation between the view who called the actionsheet and the actionsheet it self.
Actually, I wannt to customize the button in an actionsheet, so I create a class for it and overide the methods, and I want really call the methods in the superview, anybody got a solution?
Thank you!
(btw, I tried the following code, but it doesn't work.)
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
{........
else if (buttonIndex==sharers.count+1)
{
AddCommentViewController *parentController=(AddCommentViewController *)[self.superview nextResponder];
}
There is no public API for accessing the container, or owner of a UIActionSheet.
You should not use the superview property to try to get to the owner, the internal view layout for the action sheet is private and can/will change between OS updates.
If you need to get hold of the owner then add a proper property to your UIActionSheet subclass to do this. For example:
#protocol MYActionSheetChoiceDelegate;
#interface MYActionSheet : UIActionSheet <UIActionSheetDelegate> {}
#property(nonatomic, assign) id<MYActionSheetChoiceDelegate> choiceDelegate;
#end
Notice that I name the property choiceDelegate since the delegate property is already taken. Now assuming your subclass is also your it's own UIActionSheetDelegate this can be done:
-(void)actionSheet:(UIActionSheet*)sheet willDismissWithButtonIndex:(NSInteger)index;
{
if (index == SOME_INDEX) {
[self.choiceDelegate actionSheet:self didChooseSomething:index];
}
}
Change and fill the gaps to your own needs.

access a controllers variable or method from within the views subview class

Good Evening,
Here is the problem, [self.view addSubview:pauseView];
before the pauseView is loaded over the current view a BOOL isPaused is turned to false and then the subview appears. i am trying to change the value of the variable to false from withing the pauseview but since it's not on the current class i am unable to do this.
I know that this topic is already covered in stackoverflow but i still cannot solve my problem. If i'm able to solve this problem, it will solve the same kind of problem in 3 others apps of mine.
Sincerely,
Sonic555gr
Define isPaused as a property in the class that defines isPaused (let's call it MasterView):
// inside MasterView.h
#property (nonatomic,assign) BOOL isPaused;
Then make your subview pauseView a custom UIView subclass (let's call it PauseView) and in this subclass define a property called master of type MasterView:
// inside PauseView.h
#property (nonatomic,assign) MasterView *master
Then when you alloc/init your pauseView just set this property:
// somewhere inside MasterView.m
PauseView *pauseView = [[PauseView alloc] initWithFrame:frame];
pauseView.master=self;
Finally in your PauseView class, in the point of your code where you want to change the isPaused property, do this:
// somewhere in PauseView.m
master.isPaused=YES
You really should have a think about your architecture and try to move your application logic from away from UIViews and back to the controller (i.e. delegates might be a good option but impossible to know without seeing more of your code and what you are trying to achieve).
If you insist on manipulating the variable from the UIView, you need to pass a reference of your viewController to the pauseView when you initialise it.
So in your PauseView class, you would create a custom initialiser:
-(id)initWithFrame:(CGRect)frame andViewController:(id)vc {
self = [super initWithFrame:frame];
if (self) {
// Any other custom initialisation here
}
}

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.