我有一种情况,我不明白。 我喜欢在后台任务中创建CATextLayers并在我的视图中显示它们,因为它需要一些时间。
这完美没有后台任务。我可以在我的视图中立即看到该文本" worldmapview"
@IBOutlet var worldmapview: Worldmapview! // This view is just an empty view.
override func viewDidLoad(){
view.addSubview(worldmapview);
}
func addlayerandrefresh_direct(){
var calayer=CALayer();
var newtextlayer:CATextLayer=create_text_layer(0,y1: 0,width:1000,heigth:1000,text:"My Text ....",fontsize:5);
self.worldmapview.layer.addSublayer(newtextlayer)
//calayer.addSublayer(newtextlayer);
calayer.addSublayer(newtextlayer)
self.worldmapview.layer.addSublayer(calayer);
self.worldmapview.setNeedsDisplay();
}
在后台任务中执行此操作时,文本不会出现在我的视图中。有时,并非总是如此,它会在几秒钟后出现(例如10)。
func addlayerandrefresh_background(){
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
var calayer=CALayer();
var newtextlayer:CATextLayer=create_text_layer(0,y1: 0,width:1000,heigth:1000,text:"My Text ....",fontsize:5);
dispatch_async(dispatch_get_main_queue(),{
self.worldmapview.layer.addSublayer(newtextlayer)
//calayer.addSublayer(newtextlayer);
calayer.addSublayer(newtextlayer)
self.worldmapview.layer.addSublayer(calayer);
self.worldmapview.setNeedsDisplay();
})
})
}
func create_text_layer(x1:CGFloat,y1:CGFloat,width:CGFloat,heigth:CGFloat,text:String,fontsize:CGFloat) -> CATextLayer {
let textLayer = CATextLayer()
textLayer.frame = CGRectMake(x1, y1, width, heigth);
textLayer.string = text
let fontName: CFStringRef = "ArialMT"
textLayer.font = CTFontCreateWithName(fontName, fontsize, nil)
textLayer.fontSize=fontsize;
textLayer.foregroundColor = UIColor.darkGrayColor().CGColor
textLayer.wrapped = true
textLayer.alignmentMode = kCAAlignmentLeft
textLayer.contentsScale = UIScreen.mainScreen().scale
return textLayer;
}
有人看到了,出了什么问题? 令人困惑的是:与CAShapeLayer一样,在后台工作。
答案 0 :(得分:4)
看起来setNeedDisplay
不会导致子图层重绘,我们需要在我们需要的所有图层上调用它,在这种情况下,它是新添加的图层
func addlayerandrefresh_background(){
let calayer = CALayer()
calayer.frame = self.worldmapview.bounds
dispatch_async(backgroundQueue, {
for var i = 0; i < 100 ; i+=10 {
let newtextlayer:CATextLayer=self.create_text_layer(0, y1: CGFloat(i) ,width:200,heigth:200,text:"My Text ....",fontsize:5)
calayer.addSublayer(newtextlayer)
}
dispatch_async(dispatch_get_main_queue(),{
self.worldmapview.layer.addSublayer(calayer)
for l in calayer.sublayers! {
l.setNeedsDisplay()
}
})
})
}
答案 1 :(得分:1)
UI上的所有更改都在主线程上执行。您无法在后台线程上更新用户界面。根据{{3}}
涉及视图,核心动画和许多其他UIKit类的工作 通常必须在应用程序的主线程上发生。有一些例外 对于这个规则 - 例如,基于图像的操作通常可以发生在 背景线程 - 但如果有疑问,假设工作需要发生 在主线上。