在我的viewController中,我有一个按钮,它调用一个方法来启动Timer类中的计时器。就像这样
主视图控制器
[self.timer startTimer];
在计时器课程中,startTimer
会调用countdownTime
方法,您可以在下面看到这两种方法。非常简单。在countdownTime方法结束时,时间放在视图中的标签中,就像我遍历时钟循环一样。
Timer *timerblah = self.gameClocks[i];
[self.gameClocks[i] setText: [NSString stringWithFormat:@"%@", self.time]];
换句话说,Timer类有一个数组属性,它保存所有时钟并连接到视图,因此能够设置文本。
此代码的问题在于模型(即Timer类)正在视图中设置文本。我希望视图控制器从模型中获取时间并在视图控制器中设置文本,即具有viewController并且只有viewController与视图通信。在viewController中获取时钟数组对我没有问题,但是,我确定如何将时间从countdownTime方法传递回viewController。设置一个NSNotification类来每秒发回时间似乎有点过头了,不是吗?
-(void)startTimer{
self.NStimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(countdownTime:)
userInfo:nil
repeats:YES];
}
-(void)countdownTime:(NSTimer *)timer
{
#logic to countdown time
self.minutes = self.secondsRemaining / 60;
self.stringMinutes = [NSString stringWithFormat:@"%i", self.minutes];
self.seconds = self.secondsRemaining - (self.minutes * 60);
self.stringSeconds = [NSString stringWithFormat:@"%i", self.seconds];
if (self.seconds < 10) self.stringSeconds = [NSString stringWithFormat:@"0%i", self.seconds];
self.time = [NSString stringWithFormat:@"%@:%@", self.stringMinutes, self.stringSeconds];
self.secondsRemaining -= 1;
if (self.secondsRemaining == 0){
[self stopTimer];
}
#adding to the view (from the model i.e. in Timer.m class)
for(int i = 0; i < [self.gameClocks count]; i++){
Timer *timerblah = self.gameClocks[i];
if (timerblah.systemClock == YES){
[self.gameClocks[i] setText: [NSString stringWithFormat:@"%@", self.time]];
}
}
}
更新
有评论建议我使用一个块来做到这一点。在timer类中,我添加了一个这样的方法来返回一个带时间的字符串(时间设置为self.time)
-(NSString *)passTheTime:(NSString (^)(void))returnBlock
{
return self.time;
}
然后,在视图控制器中,在计时器类上调用方法passTheTime。我在视图控制器中创建了一个存储时间的属性,因此我将其作为参数传递给块
[self.timer passTheFoo:^NSString * (self.timeToSet){
}];
a)我不确定在这个街区做什么。
b)我不确定是否有必要将self.timeToSet
传递给该区块。如何将Timer类中的self.time
连接到视图控制器中的self.timeToSet
c)出现错误incompatible block pointer type sending NSString *((^)(void)) to parameter of type NSString(^)(void)
d)或者,我可以将一个块传递给startTimer,并在选择器countdownTime中传递该块,并在countdownTime中的计算完成后返回self.time吗?
答案 0 :(得分:0)
您可以使用block更新视图控制器类中的标签,如下所示
在Timer Class中,创建一个块
TimerClass.h
#import <Foundation/Foundation.h>
typedef void(^TimerCallback)(NSString *time);
@interface TimerClass : NSObject{
TimerCallback timerCallback;
NSTimer *timer;
}
- (void)startTimerWithCallBack:(TimerCallback)callback;
@end
在TimerClass.m中,更新代码如下
#import "TimerClass.h"
@implementation TimerClass
- (void)startTimerWithCallBack:(TimerCallback)callback{
timerCallback = callback;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(countdownTime:)
userInfo:nil
repeats:YES];
}
-(void)countdownTime:(NSTimer *)timer
{
// countdown logic here
// call the callback method with time as a parameter to the viewcontroller class
// here for demo purpose I am passing random number as a value in callback, you need to pass the time that you want to display here
NSString *str = [NSString stringWithFormat:@"%d",1+arc4random()%10];
timerCallback(str);
}
@end
在ViewController类中,按如下方式调用timer start方法
TimerClass *timer = [[TimerClass alloc] init];
[timer startTimerWithCallBack:^(NSString *time) {
lbl.text = time; // display time in label
}];