在后台任务中将catextlayers添加到calayer

时间:2015-11-11 11:59:06

标签: ios swift calayer cashapelayer

我有一种情况,我不明白。 我喜欢在后台任务中创建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一样,在后台工作。

2 个答案:

答案 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类的工作   通常必须在应用程序的主线程上发生。有一些例外   对于这个规则 - 例如,基于图像的操作通常可以发生在   背景线程 - 但如果有疑问,假设工作需要发生   在主线上。