如何在Tableview单元格iOS中显示更新的多个NStimer值?

时间:2016-03-01 05:17:20

标签: ios uitableview nstimer

我想在tableview中设置多个运行计时器值,以便用户轻松检查剩余时间并停止任何特定计时器。

多个计时器启动和更新值完全显示在NSLog中。 用户为特定配方设置NSTimer。 现在假设用户在recipedetail中为recipe1设置计时器,现在从该recipedetail返回。 然后再次在recipedetail中为recipe2设置计时器,然后从该recipedetail返回。 我想在UITableView中显示所有计时器值。并且tableview放在recipedetail屏幕上。

所以我的观点是NSLog中的TimerUpdated值显示但不显示在tableview中,因为每个Recipedetails屏幕都会生成UITableView的新对象,因此值不会更新

 -(IBAction)okBtn:(id)sender
    {
       [self countdownTimer];
    }
-(void)countdownTimer {

        [[NSUserDefaults standardUserDefaults]setObject:recipeboxId forKey:[NSString stringWithFormat:@"timer_%@",recipeboxId]];
        [[NSUserDefaults standardUserDefaults]synchronize];
        // set timer

        [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
        (theAppDelegate).timer = [NSTimer scheduledTimerWithTimeInterval:0.6f
                                                 target:self
                                               selector:@selector(updateCounter:)
                                               userInfo:recipeboxId
                                                repeats:YES];
        [(theAppDelegate).timer fire];
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];//Timer run in background

        [self CreateLocalNotification];
    }


    -(void)calculateTimeFromPicker
    {
        NSString *hoursStr = [NSString stringWithFormat:@"%@",[hoursArray objectAtIndex:[self.picker_timer selectedRowInComponent:0]]];
        NSString *minsStr = [NSString stringWithFormat:@"%@",[minsArray objectAtIndex:[self.picker_timer selectedRowInComponent:1]]];
        NSString *secsStr = [NSString stringWithFormat:@"%@",[secsArray objectAtIndex:[self.picker_timer selectedRowInComponent:2]]];

        int hoursInt = [hoursStr intValue];
        int minsInt = [minsStr intValue];
        int secsInt = [secsStr intValue];

        interval = secsInt + (minsInt*60) + (hoursInt*3600);
        secondsLeft=interval;
    }
    - (void)updateCounter:(NSTimer *)theTimer {
        if(secondsLeft > 0 )
        {
            secondsLeft -- ;
            hours = secondsLeft / 3600;
            minutes = (secondsLeft % 3600) / 60;
            seconds = (secondsLeft %3600) % 60;

            [[NSUserDefaults standardUserDefaults]setInteger:secondsLeft forKey:[NSString stringWithFormat:@"secondsLeft_%@",recipeboxId]];
            [[NSUserDefaults standardUserDefaults]synchronize];

            NSLog(@"timer :%@",[NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds]);
            NSString *timer_updated_value=[NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds];
            [[NSUserDefaults standardUserDefaults]setObject:timer_updated_value forKey:[NSString stringWithFormat:@"updated_timer_%@",[(theAppDelegate).timer userInfo]]];
            [[NSUserDefaults standardUserDefaults]synchronize];
             recipeArr = [[(theAppDelegate).Timer_recipeIdArr reverseObjectEnumerator] allObjects];
            for (int section = 0; section < [recipeArr count]; section++)
                for (int section = 0; section < [recipeArr count]; section++)
                {

                    for (int row = 0; row < (int)[self.timerWindowTbl numberOfRowsInSection:section]; row++)
                    {

                        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];

                        UITableViewCell *cell = [self.timerWindowTbl cellForRowAtIndexPath:indexPath];

                                for(UILabel *lbl in [cell.contentView subviews])
                                {
                                    if([lbl isKindOfClass:[UILabel class]])
                                    {

                                        if(lbl.tag == 1)
                                        {
                                            NSString *timer_desc= [[NSUserDefaults standardUserDefaults]objectForKey:[NSString stringWithFormat:@"timerDescString_%@",recipeArr[indexPath.row]]];
                                            NSString *recipe_title=[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"timerRecipeTitle_%@",recipeArr[indexPath.row]]];
                                            NSString *updated_timer=[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"updated_timer_%@",recipeArr[indexPath.row]]];

                                            NSString *desc=[NSString stringWithFormat:@"%@\n'%@\' %@ %@.",recipe_title,timer_desc,NSLocalizedString(@"is done in",nil),updated_timer];
                                             lbl.text=updated_timer;
                                            [lbl setNeedsDisplay];

                                            NSLog(@"*******************************lbl.text:%@",lbl.text);
                                            lbl.numberOfLines=0;
                                            [lbl sizeToFit];
                                            for(UIButton *btn in [cell.contentView subviews])
                                            {
                                                if([btn isKindOfClass:[UIButton class]])
                                                {
                                                    if(btn.tag==2)
                                                    {
                                                        btn.titleLabel.text=[NSString stringWithFormat:@"%@",recipeArr[indexPath.row]];
                                                    }
                                                }
                                            }
                                            break;

                                        }
                                    }

                                }
                         }
                }
        }
        else
        {
            secondsLeft = hours = minutes = seconds = 0;
            [self TimerInvalidate];
            NSLog(@"Time out :");
        }
    }

2 个答案:

答案 0 :(得分:1)

我认为您需要对代码进行折射,每当配方计时器盯着特定食谱时,您需要重新加载tableview单元格

这是示例演示,您可以尝试使用单独的项目, 首先创建一个RecipeNSObject的子类,如下所示,

<{1>}文件中的

Recipe .h

@end

<{1>}文件中的

#import <Foundation/Foundation.h>
@class Recipe;
@protocol RecipeDelegate <NSObject> //we need to notify which recipe time changing
- (void)timerChangedInRecipe:(Recipe *)recipe;
@end


@interface Recipe : NSObject
@property (nonatomic, assign) NSInteger recipeboxId;
@property (nonatomic, strong) NSString *recipeName;
@property (nonatomic, strong) NSString *countTimer;

@property (nonatomic, assign) NSTimeInterval secondsLeft;
@property (nonatomic, assign) NSTimeInterval interval;

@property (nonatomic, assign) int hours;
@property (nonatomic, assign) int minutes;
@property (nonatomic, assign) int seconds;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) id<RecipeDelegate>delegate;

- (id)initWithRecipieId:(NSInteger)recipeId recipeName:(NSString *)name;
- (void )currentTimerString;
- (void)startTimer; //use to start the timer
- (void)stopTimer;  //stop the timer

我们创建了配方对象,这将处理计时器和通知到tableview,启动计时器并停止计时器,你可以添加一些其他功能,如果你想...:)

Recipe.m

中的

#import "Recipe.h"

@implementation Recipe
- (id)init
{
  self = [super init];
  if(self)
  {

  }
  return self;
}

- (id)initWithRecipieId:(NSInteger)recipeId recipeName:(NSString *)name
{
   self = [super init];
   if(self)
   {
      self.recipeboxId = recipeId;
      self.recipeName =  name;
   }
   return self;
}

- (void)currentTimerString //this is similar to your method updateCounter:
{
   self.secondsLeft -- ;
   if(self.secondsLeft > 0 )
   {
     _hours = (int)self.secondsLeft / 3600;
     _minutes = ((int)self.secondsLeft % 3600) / 60;
     _seconds = ((int)self.secondsLeft %3600) % 60;
     self.countTimer = [NSString stringWithFormat:@"%02d:%02d:%02d", self.hours, self.minutes, self.seconds];
      if([self.delegate respondsToSelector:@selector(timerChangedInRecipe:)]) 
         [self.delegate timerChangedInRecipe:self]; //notifying the tableview to reload the particular cell 
  }
  else
  {
     _hours = _minutes = _seconds = 0;
     [self stopTimer]; //timer finished stop the timer
  }
}

- (void)startTimer
 {
    if(_timer == nil)
      _timer =  [NSTimer scheduledTimerWithTimeInterval:0.6f target:self selector:@selector(currentTimerString) userInfo:nil repeats:YES];
   else
       [_timer fire];
 }

 - (void)stopTimer
 {
    if(_timer)
      [self.timer invalidate];
    self.timer = nil;
 }
 @end
<{1>}文件中的

ViewController.h file

和详细控制器一样,与配方详细控制器 #import <UIKit/UIKit.h> #import "Recipe.h" //import the recipe class @interface ViewController : UIViewController <UITableViewDataSource,UITableViewDelegate,RecipeDelegate> @property (weak, nonatomic) IBOutlet UITableView *timerWindowTbl; @property (nonatomic, strong) NSMutableArray *recipeArr; //array to hold the recipes @end 文件

相同
ViewController.m

并在#import "ViewController.h" #import "RecipeDetailViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _recipeArr = [[NSMutableArray alloc] init]; [self populateRecipe]; //i am simply creating the recipes hear for testing } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)populateRecipe { for(NSInteger k = 0 ; k < 10 ; k++) { Recipe *recipe = [[Recipe alloc] initWithRecipieId:k recipe eName:[NSString stringWithFormat:@"recipe_%ld",(long)k]]; [self.recipeArr addObject:recipe]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } //just configure your tableview - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.recipeArr.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RECIPEE_CELL"]; if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"RECIPEE_CELL"]; } Recipe *recipe = self.recipeArr[indexPath.row]; recipe.delegate = self; cell.textLabel.text = recipe.recipeName; cell.detailTextLabel.text = recipe.countTimer; return cell; } //hear go to recipe detail controller and set timer - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { Recipe *selRecipe = self.recipeArr[indexPath.row]; RecipeDetailViewController *recipeDetailController = [[RecipeDetailViewController alloc] initWithNibName:@"RecipeDetailViewController" bundle:nil]; recipeDetailController.selectedRecipe = selRecipe; [self.navigationController pushViewController:recipeDetailController animated:YES]; } //this is the delegate method from recipe class //this method is responsible for reloading the particular cell - (void)timerChangedInRecipe:(Recipe *)recipe { NSInteger index = recipe.recipeboxId; NSIndexPath *rowPath = [NSIndexPath indexPathForRow:index inSection:0]; [self.timerWindowTbl reloadRowsAtIndexPaths:@[rowPath] withRowAnimation:UITableViewRowAnimationNone]; } @end 文件中,

RecipeDetailViewController.h

在源代码中编辑你是共享的 我认为,单元格类型中的问题,如果你想要你可以子类化tableview单元格并将计时器标签放在所需的位置,

因此,在您的代码中,#import <UIKit/UIKit.h> #import "Recipe.h" @interface RecipeDetailViewController : UIViewController @property (weak, nonatomic) IBOutlet UIDatePicker *timePicker; @property (weak, nonatomic) IBOutlet UIButton *okButton; @property (weak, nonatomic) IBOutlet UILabel *timerLabel; @property (nonatomic, strong) Recipe *selectedRecipe; - (IBAction)okBtn:(id)sender; @end 文件替换下面的方法

RecipeDetailViewController .m

并在 #import "RecipeDetailViewController.h" @interface RecipeDetailViewController () @end @implementation RecipeDetailViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. [_timePicker addTarget:self action:@selector(timerChanged:) forControlEvents:UIControlEventValueChanged]; //i am setting a sample picker } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)timerChanged:(UIDatePicker *)datePickerView { NSTimeInterval duration = datePickerView.countDownDuration; int hours = (int)(duration/3600.0f); int minutes = ((int)duration - (hours * 3600))/60; int seconds = minutes/60; _selectedRecipe.interval = seconds + (minutes*60) + (hours*3600); _selectedRecipe.secondsLeft =_selectedRecipe.interval; _timerLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds]; _selectedRecipe.interval = duration; } - (IBAction)okBtn:(id)sender //hear start the timer particular recipe { [_selectedRecipe startTimer]; } @end 文件替换

ViewController.m

并在属性检查器

中将 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RECIPEE_CELL"]; if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RECIPEE_CELL"]; } Recipe *recipe = self.recipeArr[indexPath.row]; recipe.delegate = self; cell.textLabel.text = recipe.recipeName; cell.detailTextLabel.text = recipe.countTimer; NSLog(@"timer in cell :%@",cell.detailTextLabel.text); return cell; } 模式更改为RecipeDetailViewController.m

您可以下载已修改 code hear

答案 1 :(得分:0)

在主队列中放置与UI相关的更改,以便更好地理解下面给出的代码。您还可以在Main_queue中添加其他与UI相关的更改

dispatch_async(dispatch_get_main_queue(), ^{

           lbl.text=updated_timer;

});