This commit is contained in:
Ilya Laktyushin
2022-12-03 21:57:32 +04:00
parent 9c1c901a97
commit 02e06779ef
135 changed files with 19521 additions and 711 deletions

View File

@@ -53,8 +53,9 @@ public extension SegmentedControlTheme {
}
}
private func generateSelectionImage(theme: SegmentedControlTheme) -> UIImage? {
return generateImage(CGSize(width: 20.0, height: 20.0), rotatedContext: { size, context in
private func generateSelectionImage(theme: SegmentedControlTheme, cornerRadius: CGFloat) -> UIImage? {
let cornerRadius = cornerRadius - 1.0
return generateImage(CGSize(width: 4.0 + cornerRadius * 2.0, height: 4.0 + cornerRadius * 2.0), rotatedContext: { size, context in
let bounds = CGRect(origin: CGPoint(), size: size)
context.clear(bounds)
@@ -62,8 +63,8 @@ private func generateSelectionImage(theme: SegmentedControlTheme) -> UIImage? {
context.setShadow(offset: CGSize(width: 0.0, height: -3.0), blur: 6.0, color: theme.shadowColor.withAlphaComponent(0.12).cgColor)
}
context.setFillColor(theme.foregroundColor.cgColor)
context.fillEllipse(in: CGRect(x: 2.0, y: 2.0, width: 16.0, height: 16.0))
})?.stretchableImage(withLeftCapWidth: 10, topCapHeight: 10)
context.fillEllipse(in: CGRect(x: 2.0, y: 2.0, width: cornerRadius * 2.0, height: cornerRadius * 2.0))
})?.stretchableImage(withLeftCapWidth: Int(2 + cornerRadius), topCapHeight: Int(2 + cornerRadius))
}
public struct SegmentedControlItem: Equatable {
@@ -119,7 +120,12 @@ public final class SegmentedControlNode: ASDisplayNode, UIGestureRecognizerDeleg
let dividersCount = self._items.count > 2 ? self._items.count - 1 : 0
if self.dividerNodes.count != dividersCount {
self.dividerNodes.forEach { $0.removeFromSupernode() }
self.dividerNodes = (0 ..< dividersCount).map { _ in ASDisplayNode() }
self.dividerNodes = (0 ..< dividersCount).map { _ in
let node = ASDisplayNode()
node.backgroundColor = self.theme.dividerColor
return node
}
self.dividerNodes.forEach(self.addSubnode(_:))
}
if let layout = self.validLayout {
@@ -164,7 +170,7 @@ public final class SegmentedControlNode: ASDisplayNode, UIGestureRecognizerDeleg
f(true)
}
public init(theme: SegmentedControlTheme, items: [SegmentedControlItem], selectedIndex: Int) {
public init(theme: SegmentedControlTheme, items: [SegmentedControlItem], selectedIndex: Int, cornerRadius: CGFloat = 9.0) {
self.theme = theme
self._items = items
self._selectedIndex = selectedIndex
@@ -196,7 +202,7 @@ public final class SegmentedControlNode: ASDisplayNode, UIGestureRecognizerDeleg
super.init()
self.clipsToBounds = true
self.cornerRadius = 9.0
self.cornerRadius = cornerRadius
self.addSubnode(self.selectionNode)
self.itemNodes.forEach(self.addSubnode(_:))
@@ -204,7 +210,7 @@ public final class SegmentedControlNode: ASDisplayNode, UIGestureRecognizerDeleg
self.dividerNodes.forEach(self.addSubnode(_:))
self.backgroundColor = self.theme.backgroundColor
self.selectionNode.image = generateSelectionImage(theme: self.theme)
self.selectionNode.image = generateSelectionImage(theme: self.theme, cornerRadius: cornerRadius)
}
override public func didLoad() {
@@ -286,6 +292,26 @@ public final class SegmentedControlNode: ASDisplayNode, UIGestureRecognizerDeleg
}
}
public func animateSelection(to point: CGPoint, transition: ContainedViewLayoutTransition) -> CGRect {
self.isUserInteractionEnabled = false
self.alpha = 0.0
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
let selectionFrame = self.selectionNode.frame
transition.animateFrame(node: self.selectionNode, from: self.selectionNode.frame, to: CGRect(origin: CGPoint(x: point.x - self.selectionNode.frame.height / 2.0, y: self.selectionNode.frame.minY), size: CGSize(width: self.selectionNode.frame.height, height: self.selectionNode.frame.height)))
return selectionFrame
}
public func animateSelection(from point: CGPoint, transition: ContainedViewLayoutTransition) -> CGRect {
self.isUserInteractionEnabled = true
self.alpha = 1.0
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
let selectionFrame = self.selectionNode.frame
transition.animateFrame(node: self.selectionNode, from: CGRect(origin: CGPoint(x: point.x - self.selectionNode.frame.height / 2.0, y: self.selectionNode.frame.minY), size: CGSize(width: self.selectionNode.frame.height, height: self.selectionNode.frame.height)), to: self.selectionNode.frame)
return selectionFrame
}
public func updateTheme(_ theme: SegmentedControlTheme) {
guard theme != self.theme else {
return
@@ -293,7 +319,7 @@ public final class SegmentedControlNode: ASDisplayNode, UIGestureRecognizerDeleg
self.theme = theme
self.backgroundColor = self.theme.backgroundColor
self.selectionNode.image = generateSelectionImage(theme: self.theme)
self.selectionNode.image = generateSelectionImage(theme: self.theme, cornerRadius: self.cornerRadius)
for itemNode in self.itemNodes {
if let title = itemNode.attributedTitle(for: .normal)?.string {