我们在iOS多线程编程中,经常会在子线程中需要操作主线程UI的视图控件,比如,把子线程中执行的运算结果,在主线程中TextView中显示。或者动态创建按钮UIButton,添加到主线程UI 视图UIView中,这种操作,在动画等各种应用中非常普遍,对初学者来说,需要抓住最简单的操作框架,就可以实现漂亮的界面。
下面直接看段代码。
-(void) downloadTextFile:(NSString *)urlToDownload htmlFlag:(BOOL)html writeToLocalFile:(NSString*)fileNameStr updateMenuFlag:(bool)flag{
//download the file in a seperate thread.这是一段从网上下载文档的代码,用子线程实现
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:urlToDownload];
//下面的函数是用于在主线程UI中显示当前子线程状态
[self threadMessageShow:@"downloading remote config file...."];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if(flag){//这是一个标志,用于把下载内容填到用户定义的变量中
[self threadMessageShow:@"First running, please connect WiFi and wait until remote config downloading finish! "];
}
if (urlData)
{
@autoreleasepool {
FileOps *fileOps = [[FileOps alloc] init];
//FileOps是用户自定义的文件操作类,下次后面会单独讲。
NSString * myString = [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];//把URL数据编码
if(html){//判断是否为html地址
myString=[self parseHtml:myString];解析HTML
}
NSLog(@"\n----------Test File Download ------\n%@",myString);
NSMutableString * nsmtabStr=[myString mutableCopy];
//解析结果拷贝到用户定义的对象中。
[fileOps WriteToStringFile:nsmtabStr withFileName:fileNameStr];
//解析结果写入文档
NSLog(@"File Saved !");
}
}
});
}
///////
-(void)threadMessageShow:(NSString *)msg{
@autoreleasepool {
dispatch_async(dispatch_get_main_queue(),
//子线程中用这个方法调用主线程视图控件,把所有与UI相关控件放在下面的括弧中操作
^{//show the download status in the main view
if(!messageView)
//messageView是主线程的一个UITextView控件,使用者可以自己定义在本类中
//也可以单独定义,由个人自己选择
{
messageView=[[UITextView alloc]initWithFrame:CGRectMake(5, baseHeight/3, baseWidth-10, 60)];
messageView.font=[UIFont boldSystemFontOfSize:18];
messageView.textColor=[UIColor redColor];
[self.view addSubview:messageView];
}
messageView.text=msg;
});
[NSThread sleepForTimeInterval:0.5f];
为了让用户能看到这个显示,需要在这里加一个延时定时器
[messageView removeFromSuperview];//定时器结束后,把动态创建的视图从主线程中删除。
}
}