Цель C: отправка аргументов в метод, вызываемый UIButton - PullRequest
4 голосов
/ 30 января 2011

У меня есть метод, который вызывается при нажатии кнопки UIB. Когда я создаю кнопку, я хочу, чтобы она сохраняла NSTimer в качестве аргумента.

Это таймер и создание кнопки UIB. Как бы я добавил в таймер для отправки в метод? Я пробовал withObject:timer, но он выдает предупреждение и вылетает во время выполнения.

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:(0.009) target:self selector:@selector(moveStickFig:) userInfo:stickFig repeats:YES];
[stickFig addTarget:self action:@selector(tapFig:andTime:) forControlEvents:UIControlEventTouchUpInside];

Это метод, который я отправляю:

-(void) tapFig:(id)sender andTime:(NSTimer *)timer

Я также пытался [stickFig performSelector:@selector(tapFig:andTime) withObject:nil withObject:timer] после того, как я определил UIButton, но это также приводит к предупреждению и сбоям.

Ответы [ 6 ]

7 голосов
/ 30 января 2011

Вы не можете - UIControl селекторы действия вызываются без параметров, элемента управления, являющегося источником действия, или элемента управления, являющегося источником действия, и события UIEvent, которые произошли на этомконтроль.В IB вы должны подключить UIButton к такому методу: вы не можете добавлять какие-либо другие пользовательские параметры.

Если вы хотите, чтобы он имел доступ к другим объектам, они должны быть переменными экземпляра.

Просмотрите Введение Apple в Цель C , если вы хотите понять, как определять переменные экземпляра.

2 голосов
/ 11 июля 2012

Вы можете использовать подход, при котором вы расширяете UIButton.

@interface MyButton : UIButton
@property (nonatomic, retain) NSDictionary *userInfo;
@end

Тогда ваш метод

- (void)foo:(MyButton *)sender{
    NSLog(@"%@", [sender.userInfo valueForKeyPath:@"extraData"]);
}

И для установки userInfo

...
MyButton *myButton = (MyButton *)[UIButton buttonWithType:UIButtonTypeCustom];
//set up a dictionary with info, called userInfo
myButton.userInfo = userInfo;
[myButton addTarget:self selector:@selector(foo:) forControlEvent:UIControlEventTouchUpInside];

Будет ли это работатьдля тебя?

0 голосов
/ 09 марта 2016

Вы можете создать подкласс UIButton, добавить свойство в этот подкласс, сохранить свой объект в этом свойстве и получить его в методе действия через отправителя.

0 голосов
/ 30 января 2011

Я предлагаю создать небольшой класс поддержки, который будет работать как делегат, который просто позаботится о вашем клике, а затем поменять цель вашего addTarget метода.

Сначала создайте свой класс поддержки:


@interface ClickDelegate : NSObject {
    NSTimer timer;
}

@property (nonatomic, assign) NSTimer *timer;

- (void)clickAction:(id)sender;

@end


@implementation ClickDelegate

@synthesize timer; 

- (void)clickAction:(id)sender {
    // do what you need (like destroy the NSTimer)
}

@end

Затем измените цель:


// In your view controller

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:(0.009) target:self selector:@selector(moveStickFig:) userInfo:stickFig repeats:YES];                                                                               

// Instantiate a new delegate for your delegate action
// and set inside of it all the objects/params you need
ClickDelegate *aDelegate = [[ClickDelegate alloc] init];
aDelegate.timer = timer;

[stickFig addTarget:aDelegate action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];

self.myDelegate = aDelegate; // as suggested in the comments, you need to retain it
[aDelegate release]; // and then release it

Таким образом, вы делегируете обратный вызов click другому объекту.Этот случай действительно прост (вам просто нужно получить экземпляр NSTimer), но в сложном сценарии он также помогает вам разрабатывать логику приложения, делегируя разные вещи разным маленьким классам.

Надеюсь, это поможет!Чао

0 голосов
/ 30 января 2011

Вам нужно сделать таймер свойством контроллера представления, а затем ссылаться на него из вашего метода tapFig:.Вот как может выглядеть ваш код:

MainViewController.h

//
//  MainViewController.h
//  TapFigSample
//
//  Created by Moshe Berman on 1/30/11.
//  Copyright 2011 MosheBerman.com. All rights reserved.
//

@interface MainViewController : UIViewController  {
    NSTimer *timer; 
    UIButton *stickFig;
}

@property (nonatomic, retain) NSTimer *timer;
@property (nonatomic, retain) UIButton *stickFig;

- (void)tapFig:(id)sender;

- (void) moveStickFig;

- (void) moveStickFig:(id)yourArgument


@end

MainViewController.m

//
//  MainViewController.m
//  TapFigSample
//
//  Created by Moshe Berman on 1/30/11.
//  Copyright 2011 MosheBerman.com. All rights reserved.
//

#import "MainViewController.h"


@implementation MainViewController

@synthesize timer, stickFig;

- (void) viewDidLoad{

    [self  setTimer:[NSTimer scheduledTimerWithTimeInterval:(0.009) target:self selector:@selector(moveStickFig:) userInfo:stickFig repeats:YES]];
    [stickFig addTarget:self action:@selector(tapFig:) forControlEvents:UIControlEventTouchUpInside];

}

- (void)tapFig:(id)sender{
    //do something with self.timer

}

- (void) moveStickFig:(id)yourArgument{
    //Move the stick figure
    //A tophat and a cane might 
    //look nice on your stick figure
    // :-)
}

- (void)dealloc {
    [stickFig release];
    [timer release];
    [super dealloc];
}


@end

Обратите внимание на объявление @property в заголовочном файле.Я бы тоже хотел еще раз взглянуть на инициализацию таймера, но это мог быть только я.Надеюсь, это поможет!

0 голосов
/ 30 января 2011

Измените ваш метод так, чтобы в качестве аргумента использовался один NSArray.Затем создайте свой массив параметров и передайте его performSelector.

. Для большей ясности:

Вы должны создать IBAction, требуемый для события элемента управления, и второй метод, который принимаетNSArray в качестве аргумента.Когда вызывается метод IBAction, он вызывает второй метод после создания NSArray параметров.Думайте об этом как о «цепочке методов».

...