2

I'm trying to create a custom UIView that can be used as a progress bar or similar (@IBDesignable with IBInspectables). I want a centered (primarily X-axis, but for now Y as well) UILabel in this view.

private func addLabel()
{
    let label = UILabel(frame: CGRectMake(0, 0, self.frame.width / 4, self.frame.height / 4))
    label.center = self.center
    label.textAlignment = .Center
    label.text = "5"
    //Color just to see the whole label
    label.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.5)
    self.addSubview(label)
}

In Interfacebuilder the label centers just fine:

Interface Builder centered label

However, when running it on my device (iPhone 5S) the label is aligned slightly to the right (picture below). I've tried different approaches (like making the label frame self.frame) but it's still not centered correctly. What am I missing?

UILabel on device

override func drawRect(rect: CGRect) {
    // Drawing code
    let center = CGPoint(x:bounds.width/2, y: bounds.height)
    let radius: CGFloat = max(bounds.width, bounds.height)
    let startAngle: CGFloat = π
    let endAngle: CGFloat = 2 * π

    path = UIBezierPath(arcCenter: center, radius: radius / 2 - arcWidth / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true)
    path.lineWidth = arcWidth

    arcBackgroundColor.setStroke()
    path.stroke()

    self.addLayer()
}

private func addLayer()
{
    progressLayer = CAShapeLayer()
    progressLayer.path = self.path.CGPath
    progressLayer.strokeColor = self.progressColor.CGColor
    progressLayer.fillColor = UIColor.clearColor().CGColor
    progressLayer.lineWidth = self.arcWidth

    if animatesOnDraw && progress > 0 {
        self.layer.addSublayer(progressLayer)
        self.animateProgress(0)

    } else {
        progressLayer.strokeEnd = CGFloat(self.progress / self.maxValue)
        progressLayer.opacity = Float(self.progressStrokeEndValue)
        self.layer.addSublayer(progressLayer)
    }


        addLabel() //as shown above

}
Mattias
  • 415
  • 3
  • 13

4 Answers4

3

The problem is label.center = self.center, because the center of the label and the center of the superview are in different coordinate systems so they might not be the same. Use instead

label.center = CGPoint(x: self.view.frame.bounds.size.width / 2.0, y:self.view.frame.bounds.size.height / 2.0)
Taimur Ajmal
  • 2,778
  • 6
  • 39
  • 57
Jelly
  • 4,522
  • 6
  • 26
  • 42
0

Try this:

self.label.center = view.center
Abhinandan Pratap
  • 2,142
  • 1
  • 18
  • 39
0

Add the UILabel programatically and Modify the UILabel frame from

let label = UILabel(frame: CGRectMake(0, 0, self.frame.width / 4, self.frame.height / 4))

To

let label = UILabel(frame: CGRectMake(self.frame.width/2 - (self.frame.height/4)/2, 0, self.frame.width / 4, self.frame.height / 4))

ELSE

Implement Autolayout

Manishankar
  • 327
  • 1
  • 12
0

A possible solution can be:-

@IBOutlet customView : UIView! 
//Let customView be the outlet of your custom view

func addLabel () {
    let CenterY = customView.center.y
    let CenterX = customView.center.x
    let heightOfCustom = customView.frame.size.height
    let widthOfCustom = customView.frame.size.width
    // If you want a label with height and width 1/4th of the width of the custom view
    let label = UILabel(frame : CGRectMake(CenterX - widthOfCustom/8, CenterY - heightOfCustom/8, widthOfCustom/4, heightOfCustom/4))
    label.text = "5"
    label.textAlignment = .Center
    label.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.5)
    self.addSubview(label)
}
Abhishek729
  • 327
  • 5
  • 14