简体   繁体   English

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

[英]adding catextlayers to calayer in a background task

I have a situation, which I do not understand. 我有一种情况,我不了解。 I like to create CATextLayers in a background task and show them in my view, because it takes some time. 我喜欢在后台任务中创建CATextLayers并在我的视图中显示它们,因为这需要一些时间。

This works perfect without a background task. 无需后台任务即可完美运行。 I can see the text immediately in my view "worldmapview" 我可以在“ 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();
  }  

When doing this in a backgroundtask, the text does not appear in my view. 在后台任务中执行此操作时,该文本不会出现在我的视图中。 Sometimes, not always, it appears after some seconds (10 for example). 有时(并非总是如此),它会在几秒钟后出现(例如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;
    }

Does someone see, what is wrong ? 有人看到了,怎么了? What is very confusing : The same doing with CAShapeLayer works in the background. 非常令人困惑的是:与CAShapeLayer相同的操作在后台工作。

Looks like setNeedDisplay not cause sublayers redraw and we need call it on all layers we need, in this case it's newly added layer 看起来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()
            }
        })

    })
}

All the changes on UI are performed on main thread. UI上的所有更改都在主线程上执行。 You cannot update User Interface on background thread. 您无法在后台线程上更新用户界面。 According to Apple's documentation 根据苹果的文件

Work involving views, Core Animation, and many other UIKit classes usually must occur on the app's main thread. 涉及视图,Core Animation和许多其他UIKit类的工作通常必须在应用程序的主线程上进行。 There are some exceptions to this rule—for example, image-based manipulations can often occur on background threads—but when in doubt, assume that work needs to happen on the main thread. 该规则有一些例外情况,例如,基于图像的操作通常可以在后台线程上进行,但如有疑问,请假定工作需要在主线程上进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM