2013-05-10 74 views
0

我在核心数据中有2个实体来创建倒计时定时器。 Timer具有一个名为timerName的属性,实体Blinds(从“时间”更改)具有名为duration的属性。在倒数计时器中使用核心数据实体

实体称为

Timer <---->> Blind 

和属性称为

timerName <---->> duration 

与关系称为

blinds <---->>timer 

我需要的各种持续时间放到一个倒数计时器一次一个。当第一个持续时间达到0时,下一个持续时间从核心数据中提取,并且计数到零等。

我对Objective-C和核心数据非常陌生,但我知道我需要一个循环和获取请求,但不要不知道从哪里开始。任何代码示例将不胜感激。由于

编辑

我在我的观点或者Controller.h已经建立了fetchrequest在我model.m

- (NSFetchedResultsController *)frc_newTimer 
{ 
if (_frc_newTimer) return _frc_newTimer; 

    // Otherwise, create a new frc, and set it as the property (and return it below) 
_frc_newTimer = [_cdStack frcWithEntityNamed:@"Timer" 
         withPredicateFormat:nil 
          predicateObject:nil 
          sortDescriptors:@"timerName,YES" 
        andSectionNameKeyPath:nil]; 

return _frc_newTimer; 
} 

然后

#import <UIKit/UIKit.h> 
#import "Timer.h" 
#import "Blind.h" 

@interface BlindTimerViewController : UIViewController <NSFetchedResultsControllerDelegate> 
{ 
IBOutlet UILabel *lblCountDown; 
NSTimer *countdownTimer; 
int secondsCount; 
} 
- (IBAction)StartTimer:(id)sender; 
- (IBAction)ResetTimer:(id)sender; 
@property (assign, nonatomic) NSInteger currentTimeIndex; 
@property (nonatomic, strong) Model *model; 
@property (nonatomic, strong) Timer *myTimer; 
@end 

然后在视图Controller.m或者

@interface BlindTimerViewController() 

@end 

@implementation BlindTimerViewController 
@synthesize model = _model; 

an d

-(void) timerRun 
{ 
secondsCount = secondsCount -1; 
int minutes = secondsCount/60; 
int seconds = secondsCount - (minutes * 60); 

NSString *timerOutput = [NSString stringWithFormat:@"%2d:%.2d", minutes, seconds]; 
lblCountDown.text = timerOutput; 

//need to add a label for the next blind in the coredata list and update it while in a loop...... 

if (secondsCount == 0) { 
    [countdownTimer invalidate]; 
    countdownTimer = nil; 
    } 

} 

-(void) setTimer{ 
    // Configure and load the fetched results controller 
self.model.frc_newTimer.delegate = self; 
self.model.frc_newTimer.fetchRequest.predicate = [NSPredicate predicateWithFormat:@"timerName LIKE %@", @"Sample Timer"]; 

//add code to get the first coredata item in the blinds list 

secondsCount = 240; // i need to insert the CoreData Blinds HERE 
countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerRun) userInfo:nil repeats:YES]; 
} 

和按钮(尚未完全排序)开始行动

- (IBAction)StartTimer:(id)sender 
{ 
[self setTimer]; 

} 

- (IBAction)ResetTimer:(id)sender { 
    [countdownTimer invalidate]; 
    countdownTimer = nil; 
secondsCount = 0; 
lblCountDown.text = @"00:00"; 


} 

回答

1

我假设你正在运行的倒计时已知Timer。在这种情况下,你必须从Timer到其设置的Times的关系,你不需要读取请求时,我们可以直接访问它:

NSSet *times = self.myTimer.times; 

我们要对它进行排序,所以你可以运行在持续时间一些命令: (你可能还需要检查的次数> 0计数)

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"duration" ascending:YES]; 
NSArray *orderedTimes = [times sortedArrayUsingDescriptors:@[ sortDescriptor ]]; 

下一步,我们将需要一个实例变量来跟踪我们在哪里:

@property (assign, nonatomic) NSInteger currentTimeIndex; 

使用这些部件,您可以管理该过程,并使用NSTimer实际完成该工作。当计时器启动时,您将返回到时间,获取并排序时间,递增我们正在使用的索引,检查索引是否在范围内,获取持续时间并启动计时器。

我会很厚颜无耻地说,如果到期计时器为零,这意味着我们从头开始这个过程(最好将第一个案例带入特定的方法):

- (void)timerFired:(NSTimer *)expiringTimer 
{ 
    [expiringTimer invalidate]; 

    NSInteger index = (expiringTimer != nil ? (self.currentTimeIndex + 1) : 0); 

    NSSet *times = self.myTimer.times; 

    if (times.count < index) { 
     NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"duration" ascending:YES]; 
     NSArray *orderedTimes = [times sortedArrayUsingDescriptors:@[ sortDescriptor ]]; 

     double duration = [[[orderedTimes objectAtIndex:index] duration] doubleValue]; 

     [NSTimer scheduledTimerWithTimeInterval:duration target:self selector:@selector(timerFired:) userInfo:nil repeats:NO]; 
    } else { 
     // deal with the error 
    } 
} 

现在你可以用[self timerFired:nil];

开始倒数​​你还没说你在做什么,而计时器运行时,可能会改变的东西相当多的(比如要显示的更新每秒屏幕上的时间)...

如果您需要从核心数据DB获取计时器,这就是获取请求进来:

NSManagedObjectContext *context = <#Managed object context#>; 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Timer"]; 
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"timerName LIKE %@", @"Sample Timer"]]; 

NSArray *timers = [context executeFetchRequest:fetchRequest error:nil]; // should really add the error... 

Timer *myTimer = nil; 

if (timers.count == 1) { 
    myTimer = [timers lastObject]; 
} else { 
    // we didn't find the timer, agh! 
} 
+0

感谢上面的代码和解释,我会在我的项目尝试。是的,我需要显示屏每秒更新一次,当Times实体更改显示列表中的下一个时,我还需要更改另一个文本字段。最终,当每次达到0时,我都需要激活一个声音。如果我在任何地方调整了代码,我会发布它。 – 2013-05-10 18:14:06

+0

您可以使用2个定时器,每秒1个运行更新UI,另一个运行如上。或者使用每秒钟运行一次的计时器。无论采用哪种方式,您都需要一些实例变量来跟踪UI上的内容。像'currentTimeIndex','currentTimeDuration'和'currentTimeRemaining'。 – Wain 2013-05-10 18:21:05

+0

我收到一个错误,说在对象TimerViewController上找不到Property myTimer。 – 2013-05-10 21:12:38