pass #selector to my UIbutton but click event not response - iphone

my code :
- (void)showWithStatus:(NSString *)status barColor:(UIColor*)barColor textColor:(UIColor*)textColor click:(SEL)click{
if(!self.superview)
[self.overlayWindow addSubview:self];
[self.overlayWindow setHidden:NO];
[self.topBar setHidden:NO];
self.topBar.backgroundColor = barColor;
NSString *labelText = status;
CGRect labelRect = CGRectZero;
CGFloat stringWidth = 0;
CGFloat stringHeight = 0;
if(labelText) {
CGSize stringSize = [labelText sizeWithFont:self.stringLabel.font constrainedToSize:CGSizeMake(self.topBar.frame.size.width, self.topBar.frame.size.height)];
stringWidth = stringSize.width;
stringHeight = stringSize.height;
labelRect = CGRectMake((self.topBar.frame.size.width / 2) - (stringWidth / 2), 0, stringWidth, stringHeight);
}
self.stringLabel.frame = labelRect;
self.stringLabel.alpha = 0.0;
self.stringLabel.hidden = NO;
self.stringLabel.text = labelText;
self.stringLabel.textColor = textColor;
clickBn=[[UIButton alloc]initWithFrame:self.stringLabel.frame];
clickBn.backgroundColor=[UIColor blueColor];
[clickBn addTarget:self action:click forControlEvents:UIControlEventTouchUpInside];
if(!clickBn.superview)
[self.topBar addSubview:clickBn];
[UIView animateWithDuration:0.4 animations:^{
self.stringLabel.alpha = 1.0;
}];
// [self setNeedsDisplay];
}
and call this method:
- (IBAction)successButtonPressed:(id)sender {
[KGStatusBar showSuccessWithStatus:#"Successfully synced" click:#selector(clickBn)];
}
- (void)clickBn {
NSLog(#"sss");
[KGStatusBar dismiss];
}
the NSLog(#"sss") not show. i want to pass a method to UIButton of customView ,but when i click the UIbutton not respond.

Create an delegate in control in .h file before #interface and after header files.
#protocol YourControlDelegate <NSObject>
-(void) delegateMethod;
#end
in #interface
#property (nonatomic,assign) id <YourControlDelegate> yourdelegate;
in .m #synthesize the yourdelegate.
in button click action call [self.yourdelegate delegateMethod];
In your ViewController add YourControlDelegate like as follow
#interface YourVC : UIViewController <YourControlDelegate>
in .m implement the delegate method
-(void) delegateMethod
{
//you code.
}
Here when you click the button the delegateMethod in viewController will be get called.

action should be a selector method.
If you want to pass the button as an argument to the method user : for example
[button addTarget:self action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
-(void)buttonClicked:(UIButton *)sender
{
//your code and you can also access the button properties using sender.
}
it is preferred. If you don't want to use sender(button) exclude the :

this is your clickBn method right?
- (void)clickBn {
NSLog(#"sss");
[KGStatusBar dismiss];
}
now what you doing in action? action:click??
do like following
clickBn=[[UIButton alloc]initWithFrame:self.stringLabel.frame];
clickBn.backgroundColor=[UIColor blueColor];
[clickBn addTarget:self action:#selector(clickBn) forControlEvents:UIControlEventTouchUpInside];
If you want to call method which is in another class then do like this
first make object of that class
ViewController *dvController = [ViewController alloc] init];
after that [dvController methodName];
do this all in your clickBn method First clickBn method will be called and it will call that another class method which you wanted to call
NOTE: you need to import that class in header

Related

Can you customize UISlider like the "unlock slider" in iPhone?

I have a question about UISliders in IOS and to what extent you can customize them?
I would like to implement a slider like the "Unlock slider" in iPhone.
But it seems like IOS have not provided any "standard" ways for implementing a slider like this?.
Is it possible to implement a standard UISlider and set it to a min.value (0.0) and maximum.value (0.5). If the slider "hits" a value greater then (0.01) it should automatically be pulled back to the min.value (0.0).
If it hits the maximum value (0.5), start an event then automatically pulled back to min.value?
All help is appreciated!
Try this. I use this in my Project
Slider.h
#class Slider;
#protocol SliderDelegate <NSObject>
#required
- (void) slideEnd;
#end
#interface Slider : UISlider
#property (nonatomic, weak) id<SliderDelegate> delegate;
Slider.m
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setMinimumTrackImage:YOUR_MINIMUM_TRACK_IMG forState:UIControlStateNormal];
[self setMaximumTrackImage:YOUR_MAXIMUM_TRACK_IMG forState:UIControlStateNormal];
[self setThumbImage:YOUR_THUMB_IMAGE];
self.minimumValue = 0.0;
self.maximumValue = 1.0;
self.value = 0.0;
[self addTarget:self action:#selector(moved:) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:#selector(moved:) forControlEvents:UIControlEventTouchUpOutside];
}
return self;
}
- (void) moved:(UISlider *) sender
{
if (self.value != 1.0) {
[self setValue: 0 animated: YES];
} else {
[[self delegate] slideEnd];
[self setValue: 0 animated: YES];
}
}
Implement it like this:
[self setSlider:[[Slider alloc] initWithFrame:CGRectMake(645, 25, 120, 50)]];
[[self view] addSubview:[self slider]];
[[self view] bringSubviewToFront:[self slider]];
[[self slider] setDelegate:self];
Don't forget to implement the delegate method:
- (void)slideEnd {
// Things you want to do when slide ends
}

Programmatically added button getting crash in storyboard

I am adding a button in UIScrollView in StoryBoard
Below is the code i am using.
-(void)addScrollView
{
for(int i=0;i<[array count];i++)
{
UIScrollView *subScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 400, SUBSCROLLVIEW_WIDTH, SUBSCROLLVIEW_HEIGHT)];
UITextView *txtVwDetail = [[UITextView alloc] initWithFrame:CGRectMake(342, 0, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT)];
txtVwDetail.text = SAMPLE_STRING;
[self addSubScrollView:subScrollView];
[self.view addSubview:subScrollView];
[self.view addSubview:txtVwDetail];
}
}
-(void)addSubScrollView:(UIScrollView *)aSubScrollView
{
for(int i=0;i<[array count];i++)
{
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
aButton.frame = CGRectMake(intBtnX, (aSubScrollView.frame.size.height - 80)/2, 50, 80);
[aButton setImage:[UIImage imageNamed:[self.items objectAtIndex:i]] forState:UIControlStateNormal];
**[aButton addTarget:self action:#selector(btnSubImageClicked) forControlEvents:UIControlEventTouchUpInside];**
aSubScrollView.contentSize = CGSizeMake(intScrollViewWidth, aSubScrollView.frame.size.height);
[aSubScrollView addSubview:aButton];
}
}
In addSubScrollView method I have added Button and its click event which is getting crashed.
-(void)btnSubImageClicked
{
NSLog(#"btnSubImageClicked");
}
I am having scenario as
MyMainViewController is the sourceViewController for my created customSegue which is the UIStoryboardSegue class
MyMainViewController having a UIView as PlaceHolderView in which I am adding MydestinationViewContoller's View which is this Scrollview
-(void)perform
{
BrowseScreenVC *srcObj = (BrowseScreenVC *)[self sourceViewController];
UIViewController *dstObj = (UIViewController *)[self destinationViewController];
for(UIView *vw in srcObj.viewPlaceHolder.subviews)
{
[vw removeFromSuperview];
}
NSLog(#"dest : %#",dstObj.view);
NSLog(#"destobj :%#",dstObj);
srcObj.currentViewController = dstObj;
[srcObj.viewPlaceHolder addSubview:[dstObj.view retain]];
}
UPDATE
With answer I also have to change the line
srcObj.currentViewController = dstObj;
to
srcObj.addChildViewController = dstObj;
to make it working
you have to add target as follow:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
#selector(), within these braces you have to provide the method that you want to perform. the ":" represents that the method has some argument. In this case the argument would be the button itself that is calling the method.
You have to implement your method then its signature would look like this
- (void)btnSubImageClicked:(id)sender{
// sender would be the button that is calling the method. you can use this object according to your requirements if you want.
// your code
}
if you want to call this method from somewhere else as well you can call it by passing sender argument nil. e.g [self btnSubImageClicked:nil];
Your action needs to accept an (id) sender argument, even if you are not using it:
-(void)btnSubImageClicked:(id) sender
{
NSLog(#"btnSubImageClicked");
}
In the addSubScrollView:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Button target should like
-(void) btnSubImageClicked:(id)sender{}
try this.
Updated:-
Please correct your code,change this line
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Now working i checked.
Instead of
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
write this,
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
and for better practice always write this,
-(void) btnSubImageClicked:(id)sender{}

how to set multiple buttons in UIScrollView?

how to set multiple buttons in UIScrollView and also how to set clicked action for particular button index?
UIScrollView *view = ..;
UIButton *button1 = ... ;
button1.tag = 1;
UIButton *button2 = ... ;
button1.tag = 2;
UIButton *button3 = ... ;
button1.tag = 3;
[view addSubview:button1];
[view addSubview:button2];
[view addSubview:button3];
In IBAction method check button tag to identify clicked button.
you can call this(initScrollView) method on viewDidLoad
- (void)viewDidLoad {
arrayScrollViewImages = [[NSArray alloc] initWithObjects:
[[MyKeyValuePair alloc] initWithKey:#"imagename1" withValue:#"imagename1.png"],
[[MyKeyValuePair alloc] initWithKey:#"imagename2" withValue:#"imagename2.png"],nil];
[self initScrollView];
}
here arrayScrollViewImages is NSArray
- (void) initScrollView
{
int width = 10;
for (int index = 0; index < [arrayScrollViewImages count]; index++) {
MyKeyValuePair *pair = [arrayScrollViewImages objectAtIndex:index];
UIImage *image = [UIImage imageNamed:pair.value];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(width, 2, 34, 34)];
[button setBackgroundImage:image forState:UIControlStateNormal];
[button setTag:index];
[button addTarget:self action:#selector(scrollViewButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
if (index == 0) {
[button setBackgroundColor:[UIColor colorWithRed:0.59 green:0.38 blue:0.21 alpha:1.00]];
}
[scrollView addSubview:button];
width += 45;
}
scrollView.contentSize = CGSizeMake(width, 48);
scrollView.contentOffset = CGPointMake(0, 0);
}
- (void) scrollViewButtonTapped:(id)sender {
for (UIButton *b in scrollView.subviews) {
if ([b isKindOfClass:[UIButton class]]) {
[b setBackgroundColor:[UIColor clearColor]];
}
}
UIButton *button = (UIButton *) sender;
[button setBackgroundColor:[UIColor colorWithRed:0.59 green:0.38 blue:0.21 alpha:1.00]];
MyKeyValuePair *pair = [arrayScrollViewImages objectAtIndex:button.tag];
labelEspecialidad.text = pair.key;
}
here MyKeyValuePair is a one class
*MyKeyValuePair.h*
#interface MyKeyValuePair : NSObject {
NSString *key;
NSString *value;
}
// Properties
#property (nonatomic, retain) NSString *key;
#property (nonatomic, retain) NSString *value;
#end
MyKeyValuePair.m
#implementation MyKeyValuePair
#synthesize key, value;
- (id) initWithKey: (NSString *) _key withValue: (NSString *) _value {
if (self = [super init]) {
self.key = _key;
self.value = _value;
}
return self;
}
- (void) dealloc {
[super dealloc];
[self.key release];
[self.value release];
}
#end
Using XCode Interface Builder
Add buttons (select and drag&drop them from side objects panel)
Create IBAction for every button (in owner class .h and implement in .m)
Link buttons to actions via right mouse click&drag
See some video tutorials on youtube, such as
http://www.youtube.com/watch?v=WgAAvRQBrPc
http://www.youtube.com/watch?v=uAdmetwz7sc
http://www.youtube.com/watch?v=vixD-N6cbDY
and read Developer Guide
http://www.switchonthecode.com/tutorials/creating-your-first-iphone-application-with-interface-builder
http://developer.apple.com/library/ios/#documentation/IDEs/Conceptual/Xcode4TransitionGuide/InterfaceBuilder/InterfaceBuilder.html
You can use an array of buttons for that purpose. Assign a unique tag id to each button, and programmatically spread the buttons along the UIScrollView. Have the UIScrollView listen to the Touch Up Inside event, where you can then determine which button has been clicked by the unique tag ID.

How to get tag number of UIButton

I am using Various button, and i have set tag of it from Xib files. And Connected all button to single method -(void) note:(id)sender.
Now i want to retrive tag number.so that i can see which button is clicked
-(void) note:(id)sender
{
NotesClass *note = [[NotesClass alloc] initWithNibName:#"NotesClass" bundle:nil];
note.notetag = sender;
NSLog(#"%#",note.notetag);
[self.navigationController pushViewController:note animated:YES];
}
When Print that NSlog I get this output:
<UIButton: 0x4e70350; frame = (227 119; 20 18); opaque = NO; autoresize = RM+BM; tag = 1; layer = <CALayer: 0x4e70480>>
Any one can please help me.
Try following code, it will surely help you out
UIButton *button = (UIButton *)sender;
NSInteger bTag = button.tag;
You can get the tag with
sender.tag
-(void) note:(id)sender
{
NotesClass *note = [[NotesClass alloc] initWithNibName:#"NotesClass" bundle:nil];
note.notetag = [sender tag];
NSLog(#"%d",note.notetag);
//Another option is to use
UIButton *button = (UIButton *)sender;
NSLog(#"%d",button.tag);
[self.navigationController pushViewController:note animated:YES];
}
Its %d not %# as tag is of int type
(void) note:(id)sender
{
NotesClass *note = [[NotesClass alloc] initWithNibName:#"NotesClass" bundle:nil];
note.notetag = [sender tag];
NSLog(#"%d",note.notetag);
[self.navigationController pushViewController:note animated:YES];
}
in .H file write below code
#interface tagViewController : UIViewController {
UIButton *btn1;
}
#property(nonatomic,retain)IBOutlet UIButton *btn1;
-(IBAction)btnclicked:(id)sender;
#end
and in .M file write below code
-(IBAction)btnclicked:(id)sender
{
btn1 = (UIButton *)sender;
NSLog(#"You Press Button No %d",btn1.tag);
}
Don't forgate maping of your button Suppose i have three button and i set it tag 1,2,3 and then after mapping all of them with btnclicked: in TouchUp Inside Event and then after run it it's working...

create uibutton subclass

I tried to subclass UIButton to include an activity indicator, but when i use initWithFrame:(since i'm subclassing uibutton i'm not using buttonWithType:) the button doesn't display. Also how would i set the button type in this case?:
my view controller:
ActivityIndicatorButton *button = [[ActivityIndicatorButton alloc] initWithFrame:CGRectMake(10, 10, 300, 44)];
[button addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Older Posts..." forState: UIControlStateNormal];
[cell addSubview:button];
[button release];
my activityindicatorbutton class:
#import <Foundation/Foundation.h>
#interface ActivityIndicatorButton : UIButton {
UIActivityIndicatorView *_activityView;
}
-(void)startAnimating;
-(void)stopAnimating;
#end
#implementation ActivityIndicatorButton
- (id)initWithFrame:(CGRect)frame {
if (self=[super initWithFrame:frame]) {
_activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
_activityView.frame = CGRectOffset(_activityView.frame, 60.0f, 10.0f);
[self addSubview: _activityView];
}
return self;
}
-(void) dealloc{
[super dealloc];
[_activityView release];
_activityView = nil;
}
-(void)startAnimating {
[_activityView startAnimating];
}
-(void)stopAnimating {
[_activityView stopAnimating];
}
#end
Favour composition over inheritance.
Create a UIView which contains the components you need and add them to your view.
I ran into a similar situation, and agree with Jeff that you don't really need to subclass UIButton. I solved this by subclassing UIControl, and then overriding layoutSubviews to do all of the configuration of the views I wanted on my "button". It's a much more simple implementation that subclassing UIButton since there does seem to be some hidden mojo going on under the hood. My implementation looked like this:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.opaque = YES;
self.imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[self addSubview:self.imageView];
self.textLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self addSubview:self.textLabel];
}
return self;
}
And layoutSubviews looked like this:
- (void)layoutSubviews {
[super layoutSubviews];
// Get the size of the button
CGRect bounds = self.bounds;
// Configure the subviews of the "button"
...
}
I have created a custom class, preferring composition over inheritance and it works perfect. My custom class has a button and it knows it's MCContact object. Also it draws a proper button and calculates frames automatically using MCContact object, that is passed.
Header file sample:
#import <UIKit/UIKit.h>
#protocol MCContactViewDelegate;
#interface MCContactView : UIView
{
}
#property (nonatomic, strong) MCContact *mcContact;
#property (nonatomic, weak) id <MCContactViewDelegate> delegate;
- (id)initWithContact:(MCContact*)mcContact delegate:(id <MCContactViewDelegate>)delegate;
#end
#protocol MCContactViewDelegate <NSObject>
- (void)contactViewButtonClicked:(MCContactView*)contactView;
#end
Implementation file:
#import "MCContactView.h"
#interface MCContactView()
{
UIButton *_button;
}
#end
#implementation MCContactView
- (id)initWithContact:(MCContact*)mcContact delegate:(id <MCContactViewDelegate>)delegate
{
self = [super initWithFrame:CGRectZero];
if (self) {
GetTheme();
_mcContact = mcContact;
_delegate = delegate;
_button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *normalBackgroundImage = [[UIImage imageNamed:#"tokenNormal.png"] stretchableImageWithLeftCapWidth:12.5 topCapHeight:12.5];
[_button setBackgroundImage:normalBackgroundImage forState:UIControlStateNormal];
UIImage *highlightedBackgroundImage = [[UIImage imageNamed:#"tokenHighlighted.png"] stretchableImageWithLeftCapWidth:12.5 topCapHeight:12.5];
[_button setBackgroundImage:highlightedBackgroundImage forState:UIControlStateHighlighted];
_button.titleLabel.font = [theme contactButtonFont];
[_button setTitleColor:[theme contactButtonTextColor] forState:UIControlStateNormal];
[_button setTitleEdgeInsets:UIEdgeInsetsMake(4, 6, 4, 6)];
NSString *tokenString = ([allTrim(mcContact.name) length]>0) ? mcContact.name : mcContact.eMail;
[_button setTitle:tokenString forState:UIControlStateNormal];
[_button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
CGSize size = [tokenString sizeWithFont:[theme contactButtonFont]];
size.width += 20;
if (size.width > 200) {
size.width = 200;
}
size.height = normalBackgroundImage.size.height;
[_button setFrame:CGRectMake(0, 0, size.width, size.height)];
self.frame = _button.frame;
[self addSubview:_button];
}
return self;
}
- (void)buttonClicked:(id)sender
{
[self.delegate contactViewButtonClicked:self];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
You have a pretty obvious problem that concerns your dealloc method: [super dealloc]; must be called AT THE END of your implementation, or else the line after that will try to access a memory space (the ivar space) that has been already deallocated, so it's going to crash.
For the other problem, I'm not sure it's a good idea to put an activity monitor as the subview of a button in general...
You don’t really want to subclass UIButton. It’s a class cluster, so individual instances will be something like UIRoundRectButton or some other private Apple class. What are you trying to do that requires a subclass?