将已装满的电池准确放入图像内,以便对不同的屏幕进行缩放和对齐

时间:2017-06-26 18:27:44

标签: ios swift swift3 uikit cgrect

enter image description here

我想在Swift3中实现上述目标,其中60%是用户当前的电池电量。随着电池电量的增加,必须填充绿色。我已经有了2个边框的图像,即最外面的边框,以及其中的边框作为1个图像。我想把填充的颜色放在那里。我遇到了麻烦,必须对值进行硬编码,因为它没有正确对齐。

最外边框和内边框的图像称为电池,我已将其放置在xcode中为3x,2x,1x。

let view1 = LevelView(frame: CGRect(x: battery.frame.origin.x,
                                        y: battery,
                                        width: battery.layer.preferredFrameSize().width - 25,
                                        height: battery.layer.preferredFrameSize().height / 2 - 5),
                          level: CGFloat(BatteryUtil.sharedInstance.batteryLevel()))

    battery.layer.addSublayer(view1.layer)

这是LevelView代码:

import UIKit

class LevelView : UIView {

  init(frame: CGRect, level: CGFloat) {
    super.init(frame: frame)
    //self.layer.borderWidth = 1.0
    let levelLayer = CAShapeLayer()
    levelLayer.path = UIBezierPath(roundedRect: CGRect(x: frame.origin.x,
                                                       y: frame.origin.y,
                                                       width: frame.width * level,
                                                       height: frame.height),
                                   cornerRadius: 0).cgPath
    levelLayer.fillColor = UIColor(red: 148/255.0, green: 201/255.0, blue: 61/255.0, alpha: 1).cgColor
    self.layer.addSublayer(levelLayer)

  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("Required, but Will not be called in a Playground")
  }
}

我对此非常陌生,如何使其成为理想的方式?

1 个答案:

答案 0 :(得分:2)

我建议摆脱位图图像,然后绘制整个形状。

尝试启动,然后根据需要调整设置:

import UIKit

@IBDesignable
class LevelView: UIView {

    @IBInspectable var batteryLevel: CGFloat = 0.6 {
        didSet {
            setNeedsDisplay()
        }
    }

    override func draw(_ rect: CGRect) {
        drawLevel(batteryLevel: batteryLevel)
    }

    func drawLevel(batteryLevel: CGFloat = 0.6) {
        //// General Declarations
        let context = UIGraphicsGetCurrentContext()!


        //// Variable Declarations
        let width: CGFloat = 334 * batteryLevel
        let batteryLabelText = "\(Int(round(batteryLevel * 100)))" + "%"

        //// White Rectangle Drawing
        let whiteRectanglePath = UIBezierPath(rect: CGRect(x: 24.5, y: 20.5, width: 334, height: 118))
        UIColor.white.setFill()
        whiteRectanglePath.fill()
        UIColor.black.setStroke()
        whiteRectanglePath.lineWidth = 5
        whiteRectanglePath.stroke()


        //// Green Rectangle Drawing
        let greenRectangleRect = CGRect(x: 24.5, y: 20.5, width: width, height: 118)
        let greenRectanglePath = UIBezierPath(rect: greenRectangleRect)
        UIColor.green.setFill()
        greenRectanglePath.fill()
        UIColor.black.setStroke()
        greenRectanglePath.lineWidth = 5
        greenRectanglePath.stroke()
        let greenRectangleStyle = NSMutableParagraphStyle()
        greenRectangleStyle.alignment = .center
        let greenRectangleFontAttributes = [
            NSFontAttributeName: UIFont(name: "HelveticaNeue-Bold", size: 12)!,
            NSForegroundColorAttributeName: UIColor.red,
            NSParagraphStyleAttributeName: greenRectangleStyle,
            ]

        let greenRectangleTextHeight: CGFloat = batteryLabelText.boundingRect(with: CGSize(width: greenRectangleRect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: greenRectangleFontAttributes, context: nil).height
        context.saveGState()
        context.clip(to: greenRectangleRect)
        batteryLabelText.draw(in: CGRect(x: greenRectangleRect.minX, y: greenRectangleRect.minY + (greenRectangleRect.height - greenRectangleTextHeight) / 2, width: greenRectangleRect.width, height: greenRectangleTextHeight), withAttributes: greenRectangleFontAttributes)
        context.restoreGState()


        //// Outer Rectangle Drawing
        let outerRectanglePath = UIBezierPath(roundedRect: CGRect(x: 7, y: 7, width: 372, height: 146), cornerRadius: 20)
        UIColor.black.setStroke()
        outerRectanglePath.lineWidth = 12
        outerRectanglePath.stroke()


        //// Bezier Drawing
        let bezierPath = UIBezierPath()
        bezierPath.move(to: CGPoint(x: 396, y: 53))
        bezierPath.addLine(to: CGPoint(x: 396, y: 109))
        bezierPath.addLine(to: CGPoint(x: 407, y: 98))
        bezierPath.addLine(to: CGPoint(x: 407, y: 64))
        bezierPath.addLine(to: CGPoint(x: 396, y: 53))
        bezierPath.close()
        UIColor.gray.setFill()
        bezierPath.fill()
        UIColor.black.setStroke()
        bezierPath.lineWidth = 12
        bezierPath.lineCapStyle = .round
        bezierPath.lineJoinStyle = .round
        bezierPath.stroke()
    }


}

如果需要,您可以将其直接添加到故事板中。

LevelView item in storyboard

将故事板中的引用添加到视图控制器。

Add a reference from your storyboard to your view controller