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.
Related
I want to get the value of the resultingPoints inside this delegate method
- (void)perksDetailsViewController:(PerksDetailsViewController *)sender didPassRequiredPoints:(NSNumber *)requiredPoints withCard:(Card *)selectedCard
{
double perksPoints = [requiredPoints doubleValue];
self.resultingPoints = [NSNumber numberWithDouble:[selectedCard subtractPoints:perksPoints] ];
NSLog(#"points remaining %#", self.resultingPoints);
}
This works fine but then when I try to access the resultingPoints inside the method below, resultingPoints has a null value, as being said also by the NSLog I placed.
- (void) didPressDone:(id)sender {
PointsResultsViewController *pointsResults = [self.storyboard instantiateViewControllerWithIdentifier:#"resultsPointsVC"];
[self.navigationController pushViewController:pointsResults animated:YES];
pointsResults.leftPointsLabel.text = [self.resultingPoints stringValue];
NSLog(#"hey points left is%#", self.resultingPoints);
}
What could be a good way to get the value of the resultingPoints from the first method?
Thanks in advance.
EDIT:
Log outputs
2012-05-02 15:47:48.297 CardWallet[22196:f803] points remaining 900
2012-05-02 15:47:49.291 CardWallet[22196:f803] hey points left is(null)
From your last comment:
this is it's property declaration #property (nonatomic, weak) NSNumber *resultingPoints;
This is probably the source of your problem. A weak property will be deallocated and set to nil if nothing else is retaining it, which is the case here. Make it a strong property and it will still be around when you push the new view controller.
From the details you've given in chat, you are actually dealing with two different instances of this class. One that is on the screen, and one that is being used as a delegate.
When assigning the delegate, you have to make sure it is the same object that is on the screen. This is best done in prepareForSegue, when the segue's destination view controller is the view controller that is about to appear.
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.
I want to access tag value of a button of a view to another view but it always shows zero.
I declare an integer variable: NSInteger tag; in interface part of songView.h and set its #property(nonatomic) NSInteger tag;
In songView.m synthesize it as #synthesize tag;
Now I assign it the tag value of button like this:
-(IBAction)track1ButtonPressed:(id) sender
{
self.tag = [sender tag];
}
Now I want to access this(tag) value in another view i.e. audioView, I code like this in audioView.m:
songView *songview=[songView alloc];
if (songview.tag==1)
{}
else{}
By running this code always else part execute because the value of songview.tag is 0(ZERO),
I also set the tag value of button as 1 in IB.
Try to declare integer variable with different name other than tag..ex: NSInteger btnTag;
Because in general for any view the tag is zero
First of all, you have to not only to allocate your objects, but also initialize it. So replace
songView *songview=[songView alloc];
with
CGRect songFrame = CGRectMake(0.f, 0.f, 120.f, 120.f);
songView *songview=[[songView alloc] initWithFrame:songFrame];
initWithFrame is the designated initializer for a UIView and I suppose your songView class is a subclass of UIView.
Then I am not sure if assign is the default modifier for #property, to make sure define your tag property as
#property(nonatomic, assign) NSInteger tag;
Then it should work. If not, set a breakpoint into your track1ButtonPressed:(id) sender method to see it is getting called and inspect the sender object manually using the debugger.
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
}
}
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.