将充满电的电池准确地放置在图像中,以便它针对不同的屏幕进行缩放和对齐
Place the filled battery inside the image accurately so it scales and aligns for different screens
我想在 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")
}
}
我对此很陌生,如何使其成为所需的方式?
我建议去掉位图图像,只绘制整个形状。
试试这个开始,然后根据需要调整设置:
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()
}
}
如果需要,您可以将其直接添加到故事板中。
将情节提要中的引用添加到视图控制器。
我想在 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")
}
}
我对此很陌生,如何使其成为所需的方式?
我建议去掉位图图像,只绘制整个形状。
试试这个开始,然后根据需要调整设置:
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()
}
}
如果需要,您可以将其直接添加到故事板中。
将情节提要中的引用添加到视图控制器。