addTarget : action : forControlEvents에 매개 변수 전달
다음과 같이 addTarget : action : forControlEvents를 사용하고 있습니다.
[newsButton addTarget:self
action:@selector(switchToNewsDetails)
forControlEvents:UIControlEventTouchUpInside];
그리고 선택기 "switchToNewsDetails"에 매개 변수를 전달하고 싶습니다. 내가 성공한 유일한 것은 다음과 같이 작성하여 (id) 보낸 사람을 전달하는 것입니다.
action:@selector(switchToNewsDetails:)
그러나 정수 값과 같은 변수를 전달하려고합니다. 이 방법으로 작성하면 작동하지 않습니다.
int i = 0;
[newsButton addTarget:self
action:@selector(switchToNewsDetails:i)
forControlEvents:UIControlEventTouchUpInside];
이 방법으로 작성해도 작동하지 않습니다.
int i = 0;
[newsButton addTarget:self
action:@selector(switchToNewsDetails:i:)
forControlEvents:UIControlEventTouchUpInside];
어떤 도움을 주시면 감사하겠습니다 :)
action:@selector(switchToNewsDetails:)
switchToNewsDetails:
여기서 메소드에 매개 변수를 전달하지 않습니다 . 특정 동작이 발생할 때 버튼을 호출 할 수있는 선택기를 만들면됩니다 (귀하의 경우에는 터치 업). 컨트롤은 3 가지 유형의 선택기를 사용하여 작업에 응답 할 수 있으며 모든 매개 변수의 미리 정의 된 의미를 갖습니다.
매개 변수없이
action:@selector(switchToNewsDetails)
메시지를 보내는 제어를 나타내는 1 개의 매개 변수
action:@selector(switchToNewsDetails:)
메시지를 보내는 컨트롤과 메시지를 트리거 한 이벤트를 나타내는 2 개의 매개 변수가 있습니다.
action:@selector(switchToNewsDetails:event:)
정확히 무엇을하려고하는지 명확하지 않지만 각 버튼에 특정 세부 정보 색인을 할당하려는 경우 다음을 수행 할 수 있습니다.
- 각 버튼의 태그 속성을 필수 색인과 동일하게 설정
에
switchToNewsDetails:
방법 당신은 인덱스와 오픈 적절한 deatails를 얻을 수 있습니다 :- (void)switchToNewsDetails:(UIButton*)sender{ [self openDetails:sender.tag]; // Or place opening logic right here }
버튼 클릭과 함께 사용자 정의 매개 변수를 전달하려면 UIButton SUBCLASS 만하면 됩니다.
(ASR이 켜져 있으므로 코드에 릴리스가 없습니다.)
이것은 myButton.h입니다
#import <UIKit/UIKit.h>
@interface myButton : UIButton {
id userData;
}
@property (nonatomic, readwrite, retain) id userData;
@end
이것은 myButton.m입니다
#import "myButton.h"
@implementation myButton
@synthesize userData;
@end
용법:
myButton *bt = [myButton buttonWithType:UIButtonTypeCustom];
[bt setFrame:CGRectMake(0,0, 100, 100)];
[bt setExclusiveTouch:NO];
[bt setUserData:**(insert user data here)**];
[bt addTarget:self action:@selector(touchUpHandler:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:bt];
수신 기능 :
- (void) touchUpHandler:(myButton *)sender {
id userData = sender.userData;
}
위 코드의 특정 부분에 대해 좀 더 구체적으로 설명해야하는 경우 의견에 자유롭게 문의하십시오.
Target-Action은 다음과 같은 세 가지 다른 유형의 조치 선택기를 허용합니다.
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event
Need more than just an (int) via .tag? Use KVC!
You can pass any data you want through the button object itself (by accessing CALayers keyValue dict).
Set your target like this (with the ":")
[myButton addTarget:self action:@selector(buttonTap:) forControlEvents:UIControlEventTouchUpInside];
Add your data(s) to the button itself (well the .layer
of the button that is) like this:
NSString *dataIWantToPass = @"this is my data";//can be anything, doesn't have to be NSString
[myButton.layer setValue:dataIWantToPass forKey:@"anyKey"];//you can set as many of these as you'd like too!
Then when the button is tapped you can check it like this:
-(void)buttonTap:(UIButton*)sender{
NSString *dataThatWasPassed = (NSString *)[sender.layer valueForKey:@"anyKey"];
NSLog(@"My passed-thru data was: %@", dataThatWasPassed);
}
I made a solution based in part by the information above. I just set the titlelabel.text to the string I want to pass, and set the titlelabel.hidden = YES
Like this :
UIButton *imageclick = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
imageclick.frame = photoframe;
imageclick.titleLabel.text = [NSString stringWithFormat:@"%@.%@", ti.mediaImage, ti.mediaExtension];
imageclick.titleLabel.hidden = YES;
This way, there is no need for a inheritance or category and there is no memory leak
I was creating several buttons for each phone number in an array so each button needed a different phone number to call. I used the setTag function as I was creating several buttons within a for loop:
for (NSInteger i = 0; i < _phoneNumbers.count; i++) {
UIButton *phoneButton = [[UIButton alloc] initWithFrame:someFrame];
[phoneButton setTitle:_phoneNumbers[i] forState:UIControlStateNormal];
[phoneButton setTag:i];
[phoneButton addTarget:self
action:@selector(call:)
forControlEvents:UIControlEventTouchUpInside];
}
Then in my call: method I used the same for loop and an if statement to pick the correct phone number:
- (void)call:(UIButton *)sender
{
for (NSInteger i = 0; i < _phoneNumbers.count; i++) {
if (sender.tag == i) {
NSString *callString = [NSString stringWithFormat:@"telprompt://%@", _phoneNumbers[i]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callString]];
}
}
}
As there are many ways mentioned here for the solution, Except category feature .
Use the category feature to extend defined(built-in) element into your customisable element.
For instance(ex) :
@interface UIButton (myData)
@property (strong, nonatomic) id btnData;
@end
in the your view Controller.m
#import "UIButton+myAppLists.h"
UIButton *myButton = // btn intialisation....
[myButton set btnData:@"my own Data"];
[myButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
Event handler:
-(void)buttonClicked : (UIButton*)sender{
NSLog(@"my Data %@", sender. btnData);
}
You can replace target-action with a closure (block in Objective-C) by adding a helper closure wrapper (ClosureSleeve) and adding it as an associated object to the control so it gets retained. That way you can pass any parameters.
Swift 3
class ClosureSleeve {
let closure: () -> ()
init(attachTo: AnyObject, closure: @escaping () -> ()) {
self.closure = closure
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
}
@objc func invoke() {
closure()
}
}
extension UIControl {
func addAction(for controlEvents: UIControlEvents, action: @escaping () -> ()) {
let sleeve = ClosureSleeve(attachTo: self, closure: action)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
}
}
Usage:
button.addAction(for: .touchUpInside) {
self.switchToNewsDetails(parameter: i)
}
There is another one way, in which you can get indexPath of the cell where your button was pressed:
using usual action selector like:
UIButton *btn = ....;
[btn addTarget:self action:@selector(yourFunction:) forControlEvents:UIControlEventTouchUpInside];
and then in in yourFunction:
- (void) yourFunction:(id)sender {
UIButton *button = sender;
CGPoint center = button.center;
CGPoint rootViewPoint = [button.superview convertPoint:center toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rootViewPoint];
//the rest of your code goes here
..
}
since you get an indexPath it becames much simplier.
See my comment above, and I believe you have to use NSInvocation when there is more than one parameter
more information on NSInvocation here
http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html
This fixed my problem but it crashed unless I changed
action:@selector(switchToNewsDetails:event:)
to
action:@selector(switchToNewsDetails: forEvent:)
I subclassed UIButton in CustomButton and I add a property where I store my data. So I call method: (CustomButton*) sender and in the method I only read my data sender.myproperty.
Example CustomButton:
@interface CustomButton : UIButton
@property(nonatomic, retain) NSString *textShare;
@end
Method action:
+ (void) share: (CustomButton*) sender
{
NSString *text = sender.textShare;
//your work…
}
Assign action
CustomButton *btn = [[CustomButton alloc] initWithFrame: CGRectMake(margin, margin, 60, 60)];
// other setup…
btnWa.textShare = @"my text";
[btn addTarget: self action: @selector(shareWhatsapp:) forControlEvents: UIControlEventTouchUpInside];
If you just want to change the text for the leftBarButtonItem shown by the navigation controller together with the new view, you may change the title of the current view just before calling pushViewController to the wanted text and restore it in the viewHasDisappered callback for future showings of the current view.
This approach keeps the functionality (popViewController) and the appearance of the shown arrow intact.
It works for us at least with iOS 12, built with Xcode 10.1 ...
참고URL : https://stackoverflow.com/questions/3988485/passing-parameters-to-addtargetactionforcontrolevents
'Programing' 카테고리의 다른 글
Swift에 포함 된 경우 (0) | 2020.07.08 |
---|---|
객체를 직렬화하여 Android의 파일로 저장하려면 어떻게합니까? (0) | 2020.07.08 |
Laravel의 리소스 컨트롤러에 새로운 메소드 추가 (0) | 2020.07.08 |
HTML / CSS에서 이미지의 일부만 표시하려면 어떻게해야합니까? (0) | 2020.07.08 |
루비 배열 find_first 객체? (0) | 2020.07.08 |