使用NSTimer翻转UISwitch

时间:2012-05-28 00:30:13

标签: objective-c cocoa-touch nstimer

我正在尝试学习如何使用NSTimer,我想到了以下内容:创建一个开关。让应用程序开始时计时器开始,每秒后,调用一个改变开关状态的函数。

这是我到目前为止所做的:

我在头文件ViewControl.h中声明了定时器和开关:

//Timer 
{NSTimer *timer;}
@property (weak, nonatomic) IBOutlet UISwitch *zeSwitch;

然后,在ViewControl.m文件中,我定义了以下内容:

- (IBAction)zeSwitch:(id)sender {
    UISwitch *zeSwitchSatus = (UISwitch *) sender;
    BOOL yn = zeSwitchSatus.isOn;
    [zeSwitch setOn:yn animated:YES];

}    

- (void)viewDidLoad
{

    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self 
    selector:@selector(zeSwitch) userInfo:nil repeats:YES];


    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

所以我希望当我运行代码时,我会看到一个打开或关闭的开关。然后我会看到它随着时间的推移自动改变它的状态,而不会干扰我。

image!

但那没用!我先得到上面的图片。没有什么变化。然后当我按下开关时它会崩溃。 (但我的想法是根本不接触它。)

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

你非常接近。这里有一些问题。首先,您给定时器的方法命名为zeSwitch: - 冒号很重要。所以你需要像这样创建计时器:

timer = [NSTimer scheduledTimerWithTimeInterval:1 
                                         target:self 
                                       selector:@selector(zeSwitch:) 
                                       userInfo:nil             //^ Note colon!
                                        repeats:YES];

没有冒号的名为zeSwitch的方法实际上是交换机的访问方法,因为您已将属性命名为zeSwitch。您应该重命名计时器的操作方法以澄清这一点。现在,计时器每秒都会调用交换机的访问器方法,这实际上并没有做任何事情。

接下来,计时器将本身传递给它调用的方法。 sender中的zeSwitch:参数将是计时器,而不是开关。如果这个方法实际上是通过计时器调用的,那么你会发生崩溃,因为你要向计时器发送isOn,而且它没有响应。

你有一个开关的插座,所以你可以通过那个插座参考它:

- (void)flipSwitch: (NSTimer *)tim
{
    BOOL switchIsOn = [[self zeSwitch] isOn];

请注意,我已更正此方法中的名称和类型 - 您还需要更改计时器创建以反映这一点:@selector(flipSwitch:)

第三,您想要翻转开关,因此您应该将其设置为当前状态的相反。下一行需要是:

    [[self zeSwitch] setOn:!switchIsOn animated:YES];

!运算符否定了BOOL附加的YES,将NO转换为{{1}},反之亦然。

答案 1 :(得分:3)

1)当您指定一个带有一个参数的选择器时,您需要在名称后面加冒号,因此@selector(zeSwitch:)

2)由计时器触发的选择器将计时器作为参数而不是开关,因此- (IBAction)zeSwitch:(NSTimer *)timer