Adding addTarget: method to custom UIView - ios

I created a custom UIView something like UIStepper, because I don't like the appearance of the UIStepper. I want UIStepper have a personal count label so I added it to my custom view and created a method to increase-decrease it. Now I need a [customView addTarget:(id) action:(del) forControlEvents:(UIControlEvents)] method to catch UIControlEventValueChanged; but I couldn't find anything about implementing it. I dig around the UIButton.h, UIStepper.h files but no luck too.. Can anyone help me to do that?
Here is how I created the custom view...
CounterView.h
#import <UIKit/UIKit.h>
#interface CounterView : UIView
#property NSString* name;
#property NSInteger count;
#property UILabel *label;
#property NSInteger customTag;
- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag;
#end
CounterView.m
#implementation CounterView
- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag
{
self = [super initWithFrame:CGRectMake(xPoint, yPoint, 24, 52)];
if (self) {
self.customTag = newTag;
self.count = newCount;
self.name = newName;
UIButton *btnUp = [[UIButton alloc] initWithFrame:CGRectMake(3, 2, 18, 12)];
[btnUp setImage:[UIImage imageNamed:#"top.png"] forState:UIControlStateNormal];
[btnUp addTarget:self action:#selector(increaseValue) forControlEvents:UIControlEventTouchUpInside];
UIButton *btnDown = [[UIButton alloc] initWithFrame:CGRectMake(3, 38, 18, 12)];
[btnDown setImage:[UIImage imageNamed:#"bottom.png"] forState:UIControlStateNormal];
[btnDown addTarget:self action:#selector(decreaseValue) forControlEvents:UIControlEventTouchUpInside];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 14, 24, 24)];
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
self.label.textAlignment = NSTextAlignmentCenter;
[self addSubview:btnUp];
[self addSubview:btnDown];
[self addSubview:self.label];
}
return self;
}
-(void) increaseValue{
self.count++;
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
}
-(void) decreaseValue{
self.count--;
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
}
#end

in the ViewController where you instantiate your CounterView you add this
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[yourViewInstantiation addGestureRecognizer:singleFingerTap];
[singleFingerTap release];
and the you implement the call back method:
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
//Do stuff here...
}
i hope that help you !

Just allow the actions to be set from outside of your control. Here is how to do it:
#interface CounterView : UIView
...
#property(nonatomic, strong) UIButton *btnUp;
#property(nonatomic, strong) UIButton *btnDown;
- (void)addUpTarget:(id)target action:(SEL)action;
- (void)addDownTarget:(id)target action:(SEL)action;
#end
#implementation CounterView
...
- (void)addUpTarget:(id)target action:(SEL)action
{
[_btnUp addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
}
- (void)addDownTarget:(id)target action:(SEL)action
{
[_btnDonw addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
}
...
#end
Then use methods:
- (void)addUpTarget:(id)target action:(SEL)action;
- (void)addDonwTarget:(id)target action:(SEL)action;
to set a target and actions for increasing and decreasing the values.

Related

IOS response button click in another viewController

Here is the main idea
+---MyViewController.m----+ +---BtnOnClickResp.m-----+
| | EventTouchUpInside: | |
| Button ---------------------------------------> OnBtnClick() |
| | textView.text=#"blabla"| | |
| *textView <------------------------------------------ + |
| | | |
+-------------------------+ +------------------------+
I want to test if button OnClick could be pressed in another controller like this:
MyViewController.h
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController
#property (nonatomic, strong) UITextView *textView;
+(id) sharedInstance;
#end
MyViewController.m
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController ()
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:[[BtnOnClickResp alloc] init] action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end
BtnOnClickResp.h
#import <UIKit/UIKit.h>
#interface BtnOnClickResp : UIViewController
#end
BtnOnClickResp.m
#import "BtnOnClickResp.h"
#import "MyViewController.h"
#interface BtnOnClickResp ()
#end
#implementation BtnOnClickResp
- (void) onBtnClick: (UIButton *) btn{
NSLog(#"btn was click but I am in another controller");
MyViewController *control = [MyViewController sharedInstance];
control.textView.text = #" I am setting this content in another view cheers!!!";
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The main idea is draw/add a button view in the MyViewController and make the response to click code in another controller, I thought the action assignment code:
[btn addTarget:self action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
if we change the self to the actually controller we want to use then the click event will be dispatched to that controller
But it seems not working.
Really a beginner of ios development would be happy if you don't downvote this beginner's question.
EIDT
After taking the advice as #Mike suggested,
I change the MyViewController.m to this:
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController (){
//here is the change , I made a private ref of the controller
BtnOnClickResp *respContl;
}
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:respContl action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
respContl = [[BtnOnClickResp alloc] init];
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end
Now I could see the NSLog of btn was click but I am in another controller but the view content still kept not changed to #" I am setting this content in another view cheers!!!" as it expected to be in BtnOnClickResp.m
This is the launch code in AppDelagate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *control = [[MyViewController alloc] init];
[self.window setRootViewController:control];
[self.window setBackgroundColor:[UIColor greenColor]];
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
return YES;
}
You are adding Target
[btn addTarget:[[BtnOnClickResp alloc] init] action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
to
[BtnOnClickResp alloc] init]
is Wrong
Because it will create new instance and add listener to it.
However you are try to access action in other instance
You have 4 solutions
Create shared instance of BtnOnClickResp and assign target to it
Pass the self of BtnOnClickResp to the MyViewController on and assign it
Create Delegate
Post Notification
Declare a property of BtnOnClickResp and set it as button target.
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController ()
#property(nonatomic, strong) BtnOnClickResp onClickRespObj;
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (id)init{
if(self = [super init]){
self.onClickRespObj = [[BtnOnClickResp alloc] init];
}
return self;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self.onClickRespObj action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end

UIButton with action-selector method in different class

Related to this previous question (Creating UI elements programmatically in Objective-C), this method resides in one class of the project, and other classes are able to call it to programmatically create buttons:
UIButton *createButton(CGFloat x, CGFloat y, CGFloat width, CGFloat height, NSString *caption, NSTextAlignmentCenter textPosition, UIColor *textColor, UIColor *backColor) {
UIButton *control = [[UIButton alloc] initWithFrame: CGRectMake(x, y, width, height)];
[control setTitle:caption forState:UIControlStateNormal];
control.titleLabel.textAlignment = textPosition;
control.backgroundColor = backColor;
[control setTitleColor: textColor forState:UIControlStateNormal];
return control;
}
I am now trying to add the target and action methods, to be handled by a common function, like so:
[control addTarget:nil
action:#selector(commonHandler)
forControlEvents:UIControlEventTouchDown];
It works for buttons that reside in the same class as the createButton() function, but although the buttons are successfully created in the other classes as well, they don't trigger the commonHandler() method.
NOTE: the createButton() and commonHandler() methods have been declared in its header file, and imported by all classes.
Is there any way to achieve this?
EDIT: The proposed solution still crashes
I modified the code as per the suggestions, and converted both the createButton and buttonAction to Objective-C methods, to enable reference to self.
class1 header
// class1.h
#import <UIKit/UIKit.h>
#import "class2.h"
#interface class1 : UIViewController {
UIButton *button1;
}
- (void) buttonAction:(UIButton *)control;
- (UIButton *) createButtonWithxPos:(CGFloat)x
yPos:(CGFloat)y
width:(CGFloat)width
height:(CGFloat)height
caption:(NSString *)caption
textPos:(NSTextAlignment)textPosition
textClr:(UIColor *)textColor
backClr:(UIColor *)backColor;
#end
class1 implementation
// class1.m
#import "class1.h"
#import "class2.h"
#implementation class1
- (void)viewDidLoad {
[super viewDidLoad];
button1 = [self createButtonWithxPos:10
yPos:10
width:200
height:30
caption:#"Cls1 Button"
textPos:NSTextAlignmentCenter
textClr:[UIColor whiteColor]
backClr:[UIColor blackColor]];
[self.view addSubview: button1];
}
- (UIButton *) createButtonWithxPos:(CGFloat)x
yPos:(CGFloat)y
width:(CGFloat)width
height:(CGFloat)height
caption:(NSString *)caption
textPos:(NSTextAlignment)textPosition
textClr:(UIColor *)textColor
backClr:(UIColor *)backColor
{
UIButton *control = [[UIButton alloc] initWithFrame: CGRectMake(x, y, width, height)];
[control setTitle:caption forState:UIControlStateNormal];
control.titleLabel.textAlignment = textPosition;
control.backgroundColor = backColor;
[control setTitleColor: textColor forState:UIControlStateNormal];
[control addTarget:self action: #selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
return control;
}
- (void) buttonAction:(UIButton *)control {
NSLog(#"button clicked...");
}
#end
class2 header
// class2.h
#import <UIKit/UIKit.h>
#interface class2 : UIViewController {
UIButton *button2;
}
#end
class2 implementation
// class2.m
#import "class1.h"
#import "class2.h"
#implementation class2
- (void) viewDidLoad {
[super viewDidLoad];
class1 *cls1 = [[class1 alloc] init];
button2 = [cls1 createButtonWithxPos:10
yPos:10
width:200
height:30
caption:#"Cls2 Button"
textPos:NSTextAlignmentCenter
textClr:[UIColor whiteColor]
backClr:[UIColor blackColor]];
[self.view addSubview: button2];
}
#end
Both button1 and button2 are created properly, but button1 triggers the buttonAction method while button2 does not - it crashes on touch.
Is it implemented wrongly?
(please excuse any omissions as I have only extracted the relevant portions from the actual project to illustrate here)

UIButton not being instantiated

I'm trying to instante a simple UIButton from a UIView already created in Interface Builder, but nothing's happening.
I've attached the following codes to the view:
"DetailViewTwo.h":
#import <UIKit/UIKit.h>
#interface DetailViewTwo : UIView
#property (nonatomic) bool viewIsShown;
#property (nonatomic) float lastY;
#property (weak, nonatomic) IBOutlet UILabel *titleLabel;
#property (strong, nonatomic) NSMutableArray *radioArray;
-(void)createOption:(NSString *)legenda Value:(NSString *)value action:(SEL)action;
-(void)clearView:(NSString *)novoNome;
-(void)escolherRota:(id)sender;
#end
"DetailViewTwo.m":
#import "DetailViewTwo.h"
#import "MainViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation DetailViewTwo
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_viewIsShown=false;
[self.layer setMasksToBounds:YES];
self.layer.cornerRadius=6;
UIButton *but=[UIButton buttonWithType:UIButtonTypeRoundedRect];
but.frame= CGRectMake(100, 15, 15, 15);
[but setTitle:#"Ok" forState:UIControlStateNormal];
[but addTarget:self action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:but];
}
return self;
}
#end
(Oh, also, my 'self.layer.cornerRadius=6;' is not working either, is it related??)
If you have this view created in storyboard you should use
-initWithCoder: initialiser instead of -initWithFrame:.
Also you should add the button to self.view not superview.
- (id)initWithCoder:(NSCoder *)aDecoder {
if(self = [super initWithCoder:aDecoder]) {
//Your code goes here
}
}
You need to add UIButton to View
[self.superview addSubview:but];
should be
[self addSubview:but];
i have a solution to instantiate (add) button in view. As per your code, you just need to replace [self.superview addSubview:but]; with this [self.view addSubview:but];.
UIButton *but=[UIButton buttonWithType:UIButtonTypeRoundedRect];
but.frame= CGRectMake(100, 15, 15, 15);
[but setTitle:#"Ok" forState:UIControlStateNormal];
[but addTarget:self action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:but]; // Changes done

UIButton from my class not working (EXC_BAD_ACCESS) in ViewController

I made my own class with the UIView including the UIButton and the method for it:
MyClass.h
#property (strong, nonatomic) UIView* mainBack;
#property (strong, nonatomic) UIButton* sortButton;
MyClass.m
- (id) initFor: (int) object {
if (self = [super init]) {
_mainBack = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
_sortButton = [UIButton buttonWithType:UIButtonTypeSystem];
_sortButton.frame = CGRectMake(10.0, 5.0, 60.0, 40.0);
[_sortButton addTarget:self action:#selector(ChangeSort) forControlEvents:UIControlEventTouchUpInside];
[_mainBack addSubview:_sortButton];
}
return self;
}
- (void) ChangeSort {
NSLog(#"change");
}
- (void) ShowBarOnView: (UIViewController*) view AtPoint: (CGPoint) point{
[_mainBack setFrame:CGRectMake(point.x, point.y, _mainBack.frame.size.width, _mainBack.frame.size.height)];
[view.view addSubview:_mainBack];
}
In ViewController I made the instance of myClass and called the method to show view
MyClass* mySort = [[myClass alloc] initFor: rooms];
[mySort ShowBarOnView:self AtPoint:CGPointMake(0, 50)];
So, I got the view with the button, but when pressed, the application crashes and shows:
EXC_BAD_ACCESS (code=1, address=0x0)
What is wrong?
Thanks.
Yes, I had the Same Problem!
I had my MainViewController creating the PlayingViewController in a method and long story short that was the problem.
SOFMainVC.h
SOFMainVC.m
#import "SOFPlayingVC.h" ...
- (void)someMethodBeingCalled {
SOFPlayingVC *playingVC = [[SOFPlayingVC alloc] init];
[self.view addSubview:playingVC.view];
}
SOFPlayingVC.m
...
...
- (void)viewDidLoad {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(0, 0, 100, 50)];
[button addTarget:self
action:#selector(buttonAction:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubView:button];
...
...
}
And if we were to Focus on SOFPlayingVC in instruments we'll see that the controller will be garbage collected as soon as it's done being instantiated. However if we simply add it to the controller that is in use as a #property (nonatomic, strong) we wont lose it until its out of the SOFMainViewController.
So the Solution to our issue here was to:
#import "SOFPlayingVC.h"
SOFMainVC.h
...
#interface SOFMainVC : UIViewController
#property (nonatomic, strong) SOFPlayingVC *playingVC;
...
#end
SOFMainVC.m
#import "SOFPlayingVC.h" ... ...
- (void)someMethodBeingCalled {
SOFPlayingVC *playingViewController = [[SOFPlayingVC alloc] init];
[self.view addSubview:playingVC.view];
}
If the posted code snippet appears exactly as written, the problem is that the following lines are NEVER executed. Xcode should probably be warning you about them:
_mainBack = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
_sortButton = [UIButton buttonWithType:UIButtonTypeSystem];
_sortButton.frame = CGRectMake(10.0, 5.0, 60.0, 40.0);
[_sortButton addTarget:self action:#selector(ChangeSort)
forControlEvents:UIControlEventTouchUpInside];
[_mainBack addSubview:_sortButton];
As posted, these lines exist completely outside of any method. What would make most sense is to create a factory method:
+ (instancetype) mainViewAtPoint:(CGPoint)point inContext:
(UIViewController*)viewController {
self.mainBack = [[UIView alloc] initWithFrame:CGRectMake(point.x,point.y,
320,50)];
self.sortButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.sortButton.frame = (CGRectMake(10.0, 5.0, 60.0, 40.0);
[self.sortButton addTarget:self action:#selector(ChangeSort)
forControlEvents:UIControlEventTouchUpInside];
[self.mainBack addSubview:self.sortButton];
[viewController.view addSubview: self.mainBack];
}
Now all you have to do to alloc, init, create, and add this view to your view controller is simple this:
[myClass mainViewAtPoint:aPoint inContext:aViewController];
The obvious clue that your button isn't actually created is tipped off by the EXC_BAD_ACCESS. It's telling you it's trying to reference memory location 0x0. Any time anything is trying to access 0x0 memory address, you're trying to call a method on an object that doesn't have a memory address... it's never been alloc'ed.
I solved this problem, by adding in
in ViewController.h
#property (strong, nonatomic) MyClass* mySort;
and changing my code in ViewController.m to
_mySort = [[SortAndSeach alloc] initFor:for_what];
[_mySort ShowBarOnView:self AtPoint:CGPointMake(0, 50)];
Thanks to all!

selector as parameter in IOS

I want to raise a different method for each created button.
I try to call "FirstImage" method in viewDidLoad but it doesn't work.
I have a problem with the selector in ViewDidLoad. Didn't recognise "FirstImage" which is a void method without parameter.
ViewController.m
- (void)createFirstButton:(NSString *)myName: (SEL *)myAction{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget:self
action:#selector(myAction)
forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:myName forState:UIControlStateNormal];
btn.frame = CGRectMake(20, 916, 120, 68);
[self.view addSubview:btn];
}
- (void)viewDidLoad{
[self createFirstButton:#"First" myAction:[self FirstImage]];
}
What I have done (I changed "CreateFirstButton" into "CreateButton") :
ViewControler.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myHeight;
#synthesize myWidth;
#synthesize myX;
#synthesize myY;
- (void)createButton:(NSString *)myName:(SEL)myAction:(NSUInteger)my_x:(NSUInteger)my_y:(NSUInteger)my_width:(NSUInteger)my_height
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget:self
action:myAction
forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:myName forState:UIControlStateNormal];
btn.frame = CGRectMake(my_x, my_y, my_width, my_height);
[self.view addSubview:btn];
}
- (void)myXcrementation{
myX = myX + 150;
}
- (void)viewDidLoad{
myX = 20; myY = 916; myWidth = 120; myHeight = 68;
[self createButton:#"First":#selector(FirstImage):myX:myY:myWidth:myHeight];
[self myXcrementation];
[self createButton:#"Previous":#selector(PreviousImage):myX:myY:myWidth:myHeight];
[self myXcrementation];
[self createButton:#"Pause":#selector(PauseImage):myX:myY:myWidth:myHeight];
[self myXcrementation];
[self createButton:#"Next":#selector(NextImage):myX:myY:myWidth:myHeight];
[self myXcrementation];
[self createButton:#"Last":#selector(LastImage):myX:myY:myWidth:myHeight];
}
- (void)FirstImage{
current = 0;
[self SetImage];
}
-(void)SetImage{
[myImageView setImage: [myArray objectAtIndex:(current)]];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController{
}
#property(assign, nonatomic) NSUInteger myHeight;
#property(assign, nonatomic) NSUInteger myWidth;
#property(assign, nonatomic) NSUInteger myX;
#property(assign, nonatomic) NSUInteger myY;
#end
I edited this post again and there is no more error.
Special thanks to everybody. It took me time to understand :)
You have to use use #selector as follows
[self createFirstButton:#"First" myAction:#selector(FirstImage)];
Then your signature is wrong, since SEL shouldn't be a pointer.
Change
- (void)createFirstButton:(NSString *)myName: (SEL *)myAction{
to
- (void)createFirstButton:(NSString *)myName: (SEL)myAction{
Finally myAction has type SEL so you can pass it directly to the UIButton method, as follows
[btn addTarget:self
action:myAction
forControlEvents:UIControlEventTouchUpInside];
Also, I'd like to add that using capitalized names for methods it's a very bad practice.
You should use
- (void)viewDidLoad{
[self createFirstButton:#"First" myAction:#selector(FirstImage)];
}
or
- (void)viewDidLoad{
[self createFirstButton:#"First" myAction:NSSelectorFromString(#"FirstImage")];
}
#selector(myAction) should be replaced with myAction, and (SEL *) should be replaced with SEL.
In your code, before -createFirstButton:myAction: is called, its second parameter [self FirstImage] would be evaluated(called) first. #selector() takes a name and returns a SEL.
Change the method literal as in the following
- (void)createFirstButton: (NSString *)myName withAction: (SEL)myAction
For both declaration and definition.
And also why have you declared the same method as a public as well as private?
Use
[self createFirstButton:#"First" withAction:NSSelectorFromString(#"FirstImage")];
And change the method name as :
- (void)createFirstButton:(NSString *)myName: withAction: (SEL) myAction{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget:self
action:myAction
forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:myName forState:UIControlStateNormal];
btn.frame = CGRectMake(20, 916, 120, 68);
[self.view addSubview:btn];
}
Also,
I wonder-all buttons having same frame, if possible pass frame this method.
If you are looking to pass string as method name to selector, then use NSSelectorFromString. String should end with ':' Example-
NSString *myName=#"aMethod:";
[button addTarget:self
action:NSSelectorFromString(myName)
forControlEvents:UIControlEventTouchDown];

Resources