I am having some trouble with the UIButton.
This is my code:
I am not using the Interface Builder and I am a new programmer.
What I want is that when the button is selected the title changes and the button's transparency changes from half visible to fully visible.
Thanks in advance, -Marnix
The problem is that the if statement is just executed once, when you're creating the button. Inside MyCode2, add this line:
[Button1 addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
Every time that the button's pressed, the buttonAction method will be executed, so:
- (IBAction)buttonAction:(id)sender {
if(Button1.selected == NO) {
// Do your "NO" stuff
}else if(Button1.selected == YES) {
// Do your "YES" stuff
}
}
You have to declare this IBAction in your .h and add this method in your .m file.
First of all, you should set title for different control state like
[Button1 setTitle:#"UnTapped" forState:UIControlStateSelected];
Second, you don't need to put setTitle method inside of this check.
Besides, you need to put this check inside of a method of the button to make it work. If you didn't use IB, then just use addTarget: action: forControlEvent like
[Button1 addTarget:self actoin:#selector(changeButtonState:) forControlEvent:UIControlEventTouchUpInside];
Lastly, did you make the button keep selected after touch? If not, add
Button1.selected = !Button1.selected
in the method. All in all, your method should looks like this
- (IBAction)buttonAction:(id)sender {
Button1.selected = !Button1.selected
if(Button1.selected == NO) {
Button1.alpha = 0.5
}else if(Button1.selected == YES) {
Button1.alpha = 1.0
}
}
Related
I need to do action for next and previous button event for ios video player, here am using mpmovieplayerviewcontroller.
MPMoviePlayerController fires off MPMoviePlayerPlaybackStateDidChangeNotification when either the Prev or Next is tapped. There's no way to be notified whether each one is tapped.
The only way I found, was to create my own custom controls for backward and forward, adding a target to it to perform an action:
[prevBtn addTarget:self action:#selector(onClick:)
forControlEvents:UIControlEventTouchUpInside];
[nextBtn addTarget:self action:#selector(onClick:)
forControlEvents:UIControlEventTouchUpInside];
Then in your onClick method:
(void)onClick:(UIButton*)sender
{
if (sender == prevBtn)
{
// Do whatever when prevBtn is tapped
}
else if (sender == nextBtn)
{
// Do whatever when nextBtn is tapped
}
}
FYI: you must set the player's controlStyle property to MPMovieControlStyleNon to hide the default controls.
I am setting the background image on a UIButton which has title text. This works fine, except that about 5% of the time, rarely and non-deterministically, with the same code, the text does not appear.
In my UIButton subclass:
[self setBackgroundImage:normalImage forState:UIControlStateNormal];
// Also set a background image for all other states.
In a UIButton category, I have this convenience method for setting the title:
- (void)setNormalTitle:(NSString *)title {
[self setTitle:title forState:UIControlStateNormal];
[self setTitle:title forState:UIControlStateSelected];
[self setTitle:title forState:UIControlStateHighlighted];
[self setTitle:title forState:UIControlStateSelected | UIControlStateHighlighted];
}
I'm not finding this issue having been encountered by anyone. Any ideas? I can always create a custom UIView which contains the button and draws text on top using a UILabel, but I wonder if there's a known issue I'm encountering here.
Update: I seem to have worked around the issue by setting the title asynchronously:
_tabCell = loadTopNibObject(#"MYTabSmall3HeaderCell");
dispatch_async(dispatch_get_main_queue(), ^{
_tabCell.tab0Button.normalTitle = #"Option 1";
_tabCell.tab1Button.normalTitle = #"Option 2";
_tabCell.tab2Button.normalTitle = #"Option 3";
});
Update 2: Nope, the above doesn't work. I've breakpointed and printed out the empty button's text, which reports the correct string even though the button appears blank. I've also tried running setNeedsDisplay: when the button is touched, to no avail. Also tried re-setting the button text to some specific string (e.g. #"test") on touch but this doesn't kick in any visible letting.
I've three randomly generated images( actually UIButton) and when application runs it asks the user to choose one random image among the three(say a.png).after user select the image app will do some thing based on correct image was selected or not.
Now the question is that how can i identify that user select right image? I'm trying to get name of image that user select and then check it, but really no idea how to do that.
I've searched google for this but can't find something useful.
Can anyone help?
Thanks
When you really want to store the name of the image into the button, instead of using the tagproperty, you could set it to the title and hide the titleLabel (apple reference says: Although this property is read-only, its own properties are read/write. Use these properties to configure the appearance of the button label.):
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"a.png"] forState:UIControlStateNormal];
button.titleLabel.hidden = true;
[button setTitle:#"a.png" forState:UIControlStateNormal];
then you can access to the imagename with button.currentTitle.
While generating your UIButtons you can fill the tag property.
Then you can check if your sender.tag equals the value you filled in.
When you only want to check if the correct image is selected, you can set only this one to 1 and the other buttons to 0.
To know which button clicked u need to add tag say from 0, 1, 2
[yourButton setTag:0]; //set tag 1 and 2 also to other button
Now add same selector or method to all buttons:
[yourButton setTarget:#selector(buttonClicked:) forState:UIControlTouchUPInside];
// setTarget to other buttons too
method would be this:
-(void)buttonClicked:(id)sender
{
if([sender tag] == 0)
{
//button 1 clicked
}
else if([sender tag] == 1)
{
//button 2 clicked
}
else if([sender tag] == 2)
{
//button 3 clicked
}
}
Well if you are using UIButtons for this purpose, you could set Target Selector on each button and determine the UIButton using their tag values.
There's also one more method to help. But only of you use 'backgroundImage'.This action is should be linked with your buttons:
-(IBAction)photoIconClicked:(id)sender{
if ([sender isKindOfClass:[UIButton class]]){
UIButton *button = (UIButton*)sender;
_currentImage = button.currentBackgroundImage;
}
}
I'm showing an NSAlert with a custom view and three buttons. The custom view has two text fields and it allows the user to log in.
In the Mac App Store, an NSAlert with a similar design comes up. When the user clicks the sign in button, the NSAlert does not dismiss (until the credentials are verified). How does Apple keep the alert up?
Get the NSButton you want to behave differently. Change its target and action. (To call through to the original target/action, preserve them before you change them.)
NSAlert *alert = ...;
NSButton *button = [[alert buttons] objectAtIndex:...];
id oldTarget = [button target];
SEL oldAction = [button action];
[button setTarget:self];
[button setAction:#selector(verifyCredentials:)];
Alternatively, you may want to build the alert as a custom window controller and XIB (which is how Apple did it in the case of the App Store.) In that case, you have fine-grained control over button behaviour.
Swift 4 style
let alert = NSAlert()
alert.alertStyle = .informational
alert.messageText = "Y/N?"
alert.addButton(withTitle: "Y")
alert.addButton(withTitle: "N")
guard let window = view.window else { return } // for NSViewController
alert.beginSheetModal(for: window) { res in
if res == .alertFirstButtonReturn {
// "Y" action
} else {
// "N" action
}
}
I must be missing something obvious here but ...
UIControl has a method
- (void)addTarget:(id)target action:(SEL)action forControlEvents: (UIControlEvents)controlEvents
which lets you add an action to be called when any of the given controlEvents occur. ControlEvents are a bitmask of events which tell you if a touch went down, or up inside, or was dragged etc., there's about 16 of them, you or them together and get called when any of them occur.
The selector can have one of the following signatures
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)
none of those tell you what the control event bitmask was. The UIEvent is something slightly different, it's related to the actual touch event and doesn't (I think) contain the UIControlEvent. The sender (UIControl) doesn't have a way to find the control events either.
I'd like to have one method which deals with a number of control events as I have some common code regardless of which event or events happened but I still need to know what the UIControlEvents were for some specific processing.
Am I missing a way to find out what UIControlEvents were used when the action was called or do I really have to separate my code into
- (void)actionWithUIControlEventX;
- (void)actionWithUIControlEventY;
I encountered the same problem, and came up with a solution. It's not amazingly pretty, but it works quite well. It is a UIControl category that stores the last UIControlEvent fired to its own tag property. You can get it from the link below. For further reference, here's the doc from my category, for a more detailed description of what's going on.
Hopefully this helps! Cheers/J
UIControl+CaptureUIControlEvents
git gist at: http://gist.github.com/513796
PROBLEM: upon firing, UIControlEvents are not passed into the target action
assigned to the particular event. This would be useful in order to have only
one action that switches based on the UIControlEvent fired.
SOLUTION: add a way to store the UIControlEvent triggered in the UIEvent.
PROBLEM: But we cannot override private APIs, so:
(WORSE) SOLUTION: have the UIControl store the UIControlEvent last fired.
The UIControl documentation states that:
When a user touches the control in a way that corresponds to one or more
specified events, UIControl sends itself sendActionsForControlEvents:.
This results in UIControl sending the action to UIApplication in a
sendAction:to:from:forEvent: message.
One would think that sendActionsForControlEvents: can be overridden (or
subclassed) to store the flag, but it is not so. It seems that
sendActionsForControlEvents: is mainly there for clients to trigger events
programatically.
Instead, I had to set up a scheme that registers an action for each control
event that one wants to track. I decided not to track all the events (or in
all UIControls) for performance and ease of use.
USAGE EXAMPLE:
On UIControl setup:
UIControlEvents capture = UIControlEventTouchDown;
capture |= UIControlEventTouchDown;
capture |= UIControlEventTouchUpInside;
capture |= UIControlEventTouchUpOutside;
[myControl captureEvents:capture];
[myControl addTarget:self action:#selector(touch:) forControlEvents:capture];
And the target action:
- (void) touch:(UIControl *)sender {
UIColor *color = [UIColor clearColor];
switch (sender.tag) {
case UIControlEventTouchDown: color = [UIColor redColor]; break;
case UIControlEventTouchUpInside: color = [UIColor blueColor]; break;
case UIControlEventTouchUpOutside: color = [UIColor redColor]; break;
}
sender.backgroundColor = color;
}
When you create your UIControl, set a value for the tag property. Then in your action function, you can determine the tag of the UIControl that called it using [sender tag]. Here's an example:
-(void)viewDidLoad {
UIButton *button1 = [[UIButton alloc] initWithFrame(CGRectMake(0.0,0.0,100.0,100.0)];
button1.tag = 42;
[button1 addTarget:self action:#selector(actionWithUIControlEvent:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button1];
UIButton *button2 = [[UIButton alloc] initWithFrame(CGRectMake(100.0,0.0,100.0,100.0)];
button2.tag = 43;
[button2 addTarget:self action:#selector(actionWithUIControlEvent:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button2];
}
-(void)actionWithUIControlEvent:(id)sender {
switch([sender tag]) {
case 42:
//Respond to button 1
break;
case 43:
//Respond to button 2
break;
default:
break;
}
}