These buttons represent sets, each set can be...
Empty: "K7s" is empty and represented by K7s.alpha = 0.4
Full: "Q7s" is full and represented by Q7s.alpha = 1.0 & borderWidth = 2
or
Partially Filled: "J7s" is a partially filled set, represented by adding the smaller frame. I'd like this smaller frame to be a CALayer that adjusts the SuperLayer(J7s)'s alpha to 1.0 inside the new layer's bounds. The result would appear as...
let highlighterLayer = CALayer()
highlighterLayer.borderWidth = 1
highlighterLayer.bounds = CGRect(x: 0, y: 0, width: buttonSize.width, height: percentHeight)
Buttons[tag].layer.addSublayer(highlighterLayer)
highlighterLayer.position = CGPoint(x: Buttons[tag].bounds.midX, y: Buttons[tag].bounds.midY)
Highlights[tag] = highlighterLayer
We cannot do something with a sublayer that will "adjust" the superlayer's alpha.
However, you can add a sublayer and change its alpha and border width.
Quick example -- UIButton
subclass:
class SomeButton: UIButton {
public var fillPct: CGFloat = 0 {
didSet {
setNeedsLayout()
}
}
public var highlightColor: UIColor = .green
private let highlighterLayer = CALayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
highlighterLayer.borderColor = UIColor.black.cgColor
layer.addSublayer(highlighterLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
var r = bounds
r.size.height *= fillPct
highlighterLayer.frame = r
highlighterLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
highlighterLayer.borderWidth = 2.0 * fillPct
highlighterLayer.backgroundColor = highlightColor.withAlphaComponent(fillPct).cgColor
}
}
and a demo controller - each tap of the "Cycle Values" button will cycle through a few sets of example "fill percentage" values:
class HighlightButtonTestVC: UIViewController {
var btns: [SomeButton] = []
var demoVals: [[CGFloat]] = [
[0.0, 1.0, 0.5],
[1.0, 0.5, 0.0],
[0.5, 0.5, 1.0],
]
var valsIdx: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
let stackView = UIStackView()
stackView.backgroundColor = UIColor(red: 0.0, green: 0.4, blue: 0.0, alpha: 1.0)
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
stackView.heightAnchor.constraint(equalToConstant: 60.0),
stackView.centerXAnchor.constraint(equalTo: g.centerXAnchor),
])
["K7s", "Q7s", "J7s"].forEach { str in
let b = SomeButton()
b.setTitle(str, for: [])
b.setTitleColor(.black, for: .normal)
b.setTitleColor(.lightGray, for: .highlighted)
stackView.addArrangedSubview(b)
btns.append(b)
}
for i in 0..<3 {
btns[i].fillPct = demoVals[0][i]
}
let vBtn = UIButton(type: .system)
vBtn.setTitle("Cycle Values", for: [])
vBtn.addTarget(self, action: #selector(cycleVals), for: .touchUpInside)
vBtn.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(vBtn)
NSLayoutConstraint.activate([
vBtn.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 20.0),
vBtn.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
vBtn.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
])
}
@objc func cycleVals() {
valsIdx += 1
for i in 0..<3 {
btns[i].fillPct = demoVals[valsIdx % 3][i]
}
}
}
The result - for value sets:
[0.0, 1.0, 0.5],
[1.0, 0.5, 0.0],
[0.5, 0.5, 1.0],
is:
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.