when the level is undefined or out of bounds, show question mark on battery (configurable via noLevelText).
This commit is contained in:
parent
14381b43d6
commit
12e1ff8049
|
@ -21,8 +21,8 @@ batteryView.level = 42 // anywhere in 0...100
|
|||
s.author = { "Yonat Sharon" => "yonat@ootips.org" }
|
||||
s.social_media_url = "http://twitter.com/yonatsharon"
|
||||
|
||||
s.swift_versions = ['4.2', '5.0']
|
||||
s.swift_version = '4.2'
|
||||
s.swift_versions = ['4.2', '5.0']
|
||||
s.platform = :ios, "8.0"
|
||||
s.requires_arc = true
|
||||
|
||||
|
|
|
@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- when the level is undefined or out of bounds, show question mark on battery (configurable via `noLevelText`).
|
||||
|
||||
## [1.3.5] - 2019-06-21
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
import UIKit
|
||||
|
||||
class BatteryViewController: UIViewController {
|
||||
@IBOutlet var battery: BatteryView!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
let bigBattery = BatteryView(frame: view.bounds.insetBy(dx: 60, dy: 120))
|
||||
|
@ -38,6 +40,10 @@ class BatteryViewController: UIViewController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func changeBatteryLevel(_ sender: UISlider) {
|
||||
battery.level = Int(sender.value.rounded())
|
||||
}
|
||||
}
|
||||
|
||||
@UIApplicationMain
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
@ -30,21 +30,30 @@
|
|||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="isVertical" value="NO"/>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="level">
|
||||
<integer key="value" value="40"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="borderColor">
|
||||
<color key="value" red="0.60000002384185791" green="0.40000000596046448" blue="0.20000000298023224" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="35" minValue="0.0" maxValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="Kg0-p9-8Sw">
|
||||
<rect key="frame" x="18" y="561" width="339" height="31"/>
|
||||
<connections>
|
||||
<action selector="changeBatteryLevel:" destination="BYZ-38-t0r" eventType="valueChanged" id="siV-5Y-K4j"/>
|
||||
</connections>
|
||||
</slider>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="Kg0-p9-8Sw" secondAttribute="trailing" constant="20" symbolic="YES" id="2d1-fr-d7U"/>
|
||||
<constraint firstItem="Kg0-p9-8Sw" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" constant="20" symbolic="YES" id="3gh-BS-Nev"/>
|
||||
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="iEh-y5-b3Q" secondAttribute="bottom" constant="20" id="Chp-Dd-o8T"/>
|
||||
<constraint firstItem="iEh-y5-b3Q" firstAttribute="top" secondItem="Kg0-p9-8Sw" secondAttribute="bottom" constant="16" id="p2x-0w-NLF"/>
|
||||
<constraint firstItem="iEh-y5-b3Q" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="zui-qd-LGW"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="battery" destination="iEh-y5-b3Q" id="csU-kd-7tD"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
|
|
|
@ -32,6 +32,7 @@ batteryView.borderColor = .darkGray
|
|||
batteryView.highLevelColor = .green
|
||||
batteryView.lowLevelColor = .red
|
||||
batteryView.noLevelColor = .gray
|
||||
batteryView.noLevelText = "?" // shown over battery when the level is undefined or out of bounds
|
||||
```
|
||||
|
||||
**Battery Shape:**
|
||||
|
@ -44,7 +45,6 @@ batteryView.terminalWidthRatio = 0.4 // relative to battery width
|
|||
|
||||
batteryView.borderWidth = 2.5 // default is batteryLength / 20
|
||||
batteryView.cornerRadius = 5 // default is batteryLength / 10
|
||||
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
|
|
@ -43,9 +43,12 @@ extension Int {
|
|||
// swiftlint:disable redundant_type_annotation
|
||||
@IBInspectable open dynamic var highLevelColor: UIColor = UIColor(red: 0.0, green: 0.9, blue: 0.0, alpha: 1) { didSet { layoutFillColor() } }
|
||||
@IBInspectable open dynamic var lowLevelColor: UIColor = UIColor(red: 0.9, green: 0.0, blue: 0.0, alpha: 1) { didSet { layoutFillColor() } }
|
||||
@IBInspectable open dynamic var noLevelColor: UIColor = UIColor(red: 0.8, green: 0.8, blue: 0.8, alpha: 1) { didSet { layoutFillColor() } }
|
||||
@IBInspectable open dynamic var noLevelColor: UIColor = UIColor(white: 0.8, alpha: 1) { didSet { layoutFillColor() } }
|
||||
// swiftlint:enable redundant_type_annotation
|
||||
|
||||
/// label shown over battery when the level is undefined or out of range
|
||||
@IBInspectable open dynamic var noLevelText: String? = "?"
|
||||
|
||||
@IBInspectable open dynamic var borderColor: UIColor = .black {
|
||||
didSet {
|
||||
bodyOutline.borderColor = borderColor.cgColor
|
||||
|
@ -93,12 +96,13 @@ extension Int {
|
|||
layoutLevel()
|
||||
}
|
||||
|
||||
// MARK: - Sublayers
|
||||
// MARK: - Subviews & Sublayers
|
||||
|
||||
private var bodyOutline = CALayer()
|
||||
private var terminalOutline = CALayer()
|
||||
private var terminalOpening = CALayer()
|
||||
private var levelFill = CALayer()
|
||||
public let noLevelLabel = UILabel()
|
||||
private let bodyOutline = CALayer()
|
||||
private let terminalOutline = CALayer()
|
||||
private let terminalOpening = CALayer()
|
||||
private let levelFill = CALayer()
|
||||
|
||||
private func setUp() {
|
||||
layer.addSublayer(bodyOutline)
|
||||
|
@ -107,6 +111,9 @@ extension Int {
|
|||
layer.addSublayer(terminalOutline)
|
||||
layer.addSublayer(terminalOpening)
|
||||
setNeedsLayout()
|
||||
|
||||
noLevelLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(noLevelLabel)
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
@ -121,6 +128,8 @@ extension Int {
|
|||
// layout body
|
||||
bodyOutline.frame = bodyFrame
|
||||
bodyOutline.borderWidth = borderWidth != 0 ? borderWidth : length / 20
|
||||
noLevelLabel.center = bodyOutline.center
|
||||
noLevelLabel.font = noLevelLabel.font.withSize(min(bodyFrame.width, 0.75 * bodyFrame.height))
|
||||
|
||||
// layout terminal
|
||||
let parallelInsetRatio = (1 - terminalWidthRatio) / 2
|
||||
|
@ -150,6 +159,9 @@ extension Int {
|
|||
if level >= 0 && level <= .fullBattery {
|
||||
let levelInset = (isVertical ? levelFrame.height : levelFrame.width) * CGFloat(.fullBattery - level) / CGFloat(Int.fullBattery)
|
||||
(_, levelFrame) = levelFrame.divided(atDistance: levelInset, from: direction)
|
||||
noLevelLabel.text = nil
|
||||
} else {
|
||||
noLevelLabel.text = noLevelText
|
||||
}
|
||||
levelFill.frame = levelFrame.integral
|
||||
layoutCornerRadius()
|
||||
|
@ -184,3 +196,9 @@ extension UIColor {
|
|||
return UIColor(hue: h, saturation: s, brightness: b, alpha: a)
|
||||
}
|
||||
}
|
||||
|
||||
extension CALayer {
|
||||
var center: CGPoint {
|
||||
return CGPoint(x: frame.midX, y: frame.midY)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue