简体   繁体   中英

Swift Dynamically created UILabel shows up twice

I have written a custom graph UIView subclass, and I use it to graph some basic data, and insert some user-defined data. As a final step, I'd like to add a UILabel on top of the graph with the user-defined data-point called out.

I highlight the point, and then create and add the UILabel:

if(graphPoints[i] == highlightPoint){
            var point2 = CGPoint(x:columnXPoint(i), y:columnYPoint(graphPoints[i]))
            point2.x -= 8.0/2
            point2.y -= 8.0/2
            let circle2 = UIBezierPath(ovalInRect:
                CGRect(origin: point2,
                    size: CGSize(width: 8.0, height: 8.0)))
            highlightColor.setFill()
            highlightColor.setStroke()
            circle2.fill()
            let circle = UIBezierPath(ovalInRect:
                CGRect(origin: point,
                    size: CGSize(width: 5.0, height: 5.0)))
            UIColor.whiteColor().setFill()
            UIColor.whiteColor().setStroke()

            circle.fill()
            var pointLabel : UILabel = UILabel()
            pointLabel.text = "Point = \(graphPoints[i])"
            pointLabel.frame = CGRectMake(point2.x, point2.y, 100, 50)
            self.addSubview(pointLabel)
        } else {
            let circle = UIBezierPath(ovalInRect:
                CGRect(origin: point,
                    size: CGSize(width: 5.0, height: 5.0)))
            UIColor.whiteColor().setFill()
            UIColor.whiteColor().setStroke()
            circle.fill()

        }

This looks like it should work, but the UILabel is added twice. What am I doing wrong?

This code is probably in drawRect . You're doing subview-adding in drawRect which is incorrect. drawRect gets called at least twice as the view appears, and perhaps many times after that.

You should be overriding some early lifecycle method, like awakeFromNib() or the constructor. In that, construct your label and add it as a child view. This way the addSubView() happens once as it should. The label will be invisible having no contents, so don't worry about that.

In drawRect , just update all the necessary attributes of the label including the frame .

If you find you're actually needing lots of text "labels" that come and go, different quantity for every graph, you don't really want UILabel s as subviews after all. Consider directly drawing text on screen with someString.drawAtPoint(...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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