Skip to content

Instantly share code, notes, and snippets.

@mntone
Last active March 6, 2019 05:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mntone/49b83fb59dfe5283a8335ab4ff5f4e84 to your computer and use it in GitHub Desktop.
Save mntone/49b83fb59dfe5283a8335ab4ff5f4e84 to your computer and use it in GitHub Desktop.
細かい部分の調整
import UIKit
public final class ThemeSegmentedControl: UISegmentedControl {
private var observer: NSObjectProtocol?
private weak var selectedLayer: CALayer!
public override var frame: CGRect {
didSet {
guard let selectedLayer = selectedLayer else { return }
selectedLayer.frame.size.height = frame.size.height
selectedLayer.cornerRadius = 0.5 * frame.size.height
}
}
public override var selectedSegmentIndex: Int {
didSet { update(at: selectedSegmentIndex) }
}
public override var tintColor: UIColor! {
get { return themeTintColor }
set {
guard themeTintColor != newValue else { return }
themeTintColor = newValue
setupDesign()
}
}
private var themeTintColor: UIColor?
public override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
public override init(items: [Any]?) {
super.init(items: items)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
deinit {
if let observer = observer {
self.observer = nil
NotificationCenter.default.removeObserver(observer)
}
}
private func setup() {
backgroundColor = .clear
super.tintColor = .clear
addTarget(self, action: #selector(update(sender:)), for: .valueChanged)
observer = NotificationCenter.default
.addObserver(forName: UIAccessibility.darkerSystemColorsStatusDidChangeNotification,
object: nil,
queue: OperationQueue.main,
using: darkerSystemColorsStatusDidChange)
setupDesign()
}
private func darkerSystemColorsStatusDidChange(notification: Notification) {
if tintColor == nil {
setupDesign()
}
}
private func setupDesign() {
var selectedColor: UIColor
if let tintColor = tintColor {
selectedColor = tintColor
} else if UIAccessibility.isDarkerSystemColorsEnabled {
selectedColor = UIColor(red: 0.0, green: 0.25, blue: 0.87, alpha: 1.0)
} else {
selectedColor = UIColor(red: 0.0, green: 122.0 / 255.0, blue: 1.0, alpha: 1.0)
}
// Normal
let normalAttrs: [NSAttributedString.Key: Any] = [.foregroundColor: selectedColor]
setTitleTextAttributes(normalAttrs, for: .normal)
setTitleTextAttributes(normalAttrs, for: .highlighted)
// Selected
let selectedState: [UIControl.State] = [
.selected,
[.selected, .highlighted],
]
let selectedAttrs: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor.white]
selectedState.forEach { setTitleTextAttributes(selectedAttrs, for: $0) }
// Disable
let disabledAttrs: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor(white: 0.48, alpha: 0.35)]
setTitleTextAttributes(disabledAttrs, for: .disabled)
let selectedLayer = self.selectedLayer ?? createSelectedLayer()
selectedLayer.backgroundColor = selectedColor.cgColor
selectedLayer.shadowColor = selectedColor.cgColor
if selectedSegmentIndex != -1 {
update(at: selectedSegmentIndex)
}
}
private func createSelectedLayer() -> CALayer {
let selectedLayer = CALayer()
selectedLayer.cornerRadius = 0.5 * frame.size.height
selectedLayer.frame.size.height = frame.size.height
selectedLayer.rasterizationScale = UIScreen.main.scale
selectedLayer.shadowOffset = CGSize(width: 0.0, height: 2.0)
selectedLayer.shadowOpacity = 0.4
selectedLayer.shadowRadius = 2.0
selectedLayer.shouldRasterize = true
self.selectedLayer = selectedLayer
layer.addSublayer(selectedLayer)
return selectedLayer
}
public override func layoutSubviews() {
super.layoutSubviews()
if selectedSegmentIndex != -1 {
update(at: selectedSegmentIndex)
}
}
@objc private func update(sender: ThemeSegmentedControl!) {
update(at: selectedSegmentIndex)
}
private func update(at index: Int) {
let sortedSubviews = subviews.sorted { $0.frame.origin.x < $1.frame.origin.x }
let selectedFrame = sortedSubviews[index].frame
UIView.animate(withDuration: 0.3) {
self.selectedLayer.frame = selectedFrame
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment