问题:iOS UITableView滚动停止其他任务

时间:2015-07-17 23:34:51

标签: ios iphone xcode uitableview

我正在开发基于TCPIP上的异步套接字通信运行的应用程序。 应用程序的目标是从服务器循环获取数据(2秒)并在tableview上列出数据。

到目前为止,我完成了编码和一切。该应用程序运行正常。 但是,当我开始在UITableview中滚动时,循环提取会停止,直到tableviews声明滚动结束。

我只是添加具有相同行为的示例代码,而不是添加所有代码。 在这个示例项目中,我创建了计时器。 有一个标签显示计数器和按钮,以启动/停止屏幕上的计时器。 在屏幕中我还添加了uitextview,它有很长的文本,只是启用了滚动。

这是代码

#import <UIKit/UIKit.h>
int i;

@interface ViewController : UIViewController{



}

@property (strong, nonatomic)  NSTimer *timer;

@property (strong, nonatomic) IBOutlet UILabel *label;
@property (strong, nonatomic) IBOutlet UIButton *txtBtn;
- (IBAction)btnStartStop:(id)sender;

@end


#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize label,txtBtn, timer;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    i = 0;
    //timer = [[NSTimer alloc] init];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)btnStartStop:(id)sender {
    if ([txtBtn.titleLabel.text isEqualToString:@"Start"]) {
        [txtBtn setTitle:@"Stop" forState:UIControlStateNormal];

        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timer_Running) userInfo:nil repeats:YES];
            NSLog(@"Timer Started");
    }
    else{
        [txtBtn setTitle:@"Start" forState:UIControlStateNormal];
        [timer invalidate];
        NSLog(@"Timer Stopped");
    }


}

-(void)timer_Running{
    NSLog(@"Timer Running");
    label.text = [NSString stringWithFormat:@"%i", i];
    i++;
}


@end

对于上述代码; 当您单击“开始”按钮时,计数器将启动,并且您可以看到每个1s增加的标签。但是一旦你触摸并向上/向下滚动UITextView而不是数量没有增加,只需等到滚动结束并反复增加。

任何人都可以告诉我可能的原因以及如何避免这个问题。

感谢。

2 个答案:

答案 0 :(得分:0)

首先,您需要从后台线程启动计时器。将此代码更换为启动计时器:

timer = [NSTimer timerWithTimeInterval:0.1
                                         target:self
                              selector:@selector(timer_Running:)
                                       userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

其次,由于您的计时器现在将在后台线程中触发,您需要从主线程访问UIKit:

-(void) timer_Running:(NSTimer *)timer {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"Timer Running");
        label.text = [NSString stringWithFormat:@"%i", i];
    });
    i++;
}

请注意,i++不需要在主队列上安排。上面的代码已经过您的代码测试,并且可以显示正常工作。

答案 1 :(得分:0)

我找到了上述问题和解决方案的来源。 主要问题是关于NSRunLoopMode。 如果您使用的是NSTimer或performSelector对象,则默认情况下会将RunLoopMode的模式分配给NSDefaulRunLoopModes,这会在您滚动页面时驱动Timers停止。 解决方案是将计时器和performSelectors添加到NSRunLoopCommonModes而不是使用NSDefaultRunLoopModes。

这是我找到的解决方案。

感谢您的支持