diff --git a/Example/BetterSegmentedControl/ViewController.swift b/Example/BetterSegmentedControl/ViewController.swift index 6b77686..89f5044 100644 --- a/Example/BetterSegmentedControl/ViewController.swift +++ b/Example/BetterSegmentedControl/ViewController.swift @@ -36,6 +36,7 @@ class ViewController: UIViewController { // Control 1: Created and designed in IB control1.segments = LabelSegment.segments(withTitles: ["Recent", "Nearby", "All"], normalTextColor: UIColor(red: 0.48, green: 0.48, blue: 0.51, alpha: 1.00)) + control1.segmentSpacing = 50 // Control 2: Created and designed in IB control2.segments = LabelSegment.segments(withTitles: ["Music", "Movies", "Apps"], diff --git a/Example/Podfile.lock b/Example/Podfile.lock index b60d72d..edf310f 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - BetterSegmentedControl (2.0) + - BetterSegmentedControl (2.0.1) - iOSSnapshotTestCase (5.0.2): - iOSSnapshotTestCase/SwiftSupport (= 5.0.2) - iOSSnapshotTestCase/Core (5.0.2) @@ -31,7 +31,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - BetterSegmentedControl: ce9b68b81c963991211c561026ed2cf711f9ac63 + BetterSegmentedControl: 09607b27861d49cbce48b7673b74f9150a3d371a iOSSnapshotTestCase: 2d51aa06775e95cecb0a1fb9c5c159ccd1dd4596 Nimble: 051e3d8912d40138fa5591c78594f95fb172af37 Nimble-Snapshots: bbd1ab264bacc24a9ce24a8363bc05aac783aeb0 @@ -39,4 +39,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 609c5442f2ad21fe0424eaab055f9caa5c2944a1 -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.0 diff --git a/Pod/Classes/BetterSegmentedControl+Options.swift b/Pod/Classes/BetterSegmentedControl+Options.swift index 51e66a1..a7b9df5 100644 --- a/Pod/Classes/BetterSegmentedControl+Options.swift +++ b/Pod/Classes/BetterSegmentedControl+Options.swift @@ -30,6 +30,7 @@ public extension BetterSegmentedControl { /* Other */ case backgroundColor(UIColor) case cornerRadius(CGFloat) + case segmentSpacing(CGFloat) } } diff --git a/Pod/Classes/BetterSegmentedControl.swift b/Pod/Classes/BetterSegmentedControl.swift index c9d05dc..4abe662 100644 --- a/Pod/Classes/BetterSegmentedControl.swift +++ b/Pod/Classes/BetterSegmentedControl.swift @@ -93,6 +93,10 @@ import UIKit indicatorView.layer.borderColor = newValue?.cgColor } } + /// The horizontal spacing between segments. + @IBInspectable public var segmentSpacing: CGFloat = 0 { + didSet { setNeedsLayout() } + } /// The duration of the animation of an index change. Defaults to `0.3`. @IBInspectable public var animationDuration: TimeInterval = 0.3 @@ -158,6 +162,8 @@ import UIKit private var totalInsetSize: CGFloat { indicatorViewInset * 2.0 } + private var totalSpacings: CGFloat { return segmentSpacing * CGFloat(normalSegmentViewCount - 1) } + private var isLayoutDirectionRightToLeft: Bool { let layoutDirection = UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) return layoutDirection == .rightToLeft @@ -339,6 +345,8 @@ import UIKit animationDuration = value case let .animationSpringDamping(value): animationSpringDamping = value + case let .segmentSpacing(value): + segmentSpacing = value } } } @@ -447,9 +455,10 @@ import UIKit } private func frameForElement(atIndex index: Int) -> CGRect { - let elementWidth = (width - totalInsetSize) / CGFloat(normalSegmentViewCount) - let x = CGFloat(isLayoutDirectionRightToLeft ? lastIndex - index : index) * elementWidth - + let elementWidth = (width - totalInsetSize - totalSpacings) / CGFloat(normalSegmentViewCount) + let spacingOffset = CGFloat(index) * segmentSpacing + let x = CGFloat(isLayoutDirectionRightToLeft ? lastIndex - index : index) * elementWidth + spacingOffset + return CGRect(x: x + indicatorViewInset, y: indicatorViewInset, width: elementWidth, diff --git a/Pod/Classes/Options.swift b/Pod/Classes/Options.swift new file mode 100644 index 0000000..e8eb677 --- /dev/null +++ b/Pod/Classes/Options.swift @@ -0,0 +1,28 @@ +// +// Options.swift +// Pods +// +// Created by George Marmaridis on 15/05/2017. +// +// + +import Foundation + +public enum BetterSegmentedControlOption { + /* Selected segment */ + case indicatorViewBackgroundColor(UIColor) + case indicatorViewInset(CGFloat) + case indicatorViewBorderWidth(CGFloat) + case indicatorViewBorderColor(UIColor) + + /* Behavior */ + case alwaysAnnouncesValue(Bool) + case announcesValueImmediately(Bool) + case panningDisabled(Bool) + + /* Other */ + case backgroundColor(UIColor) + case cornerRadius(CGFloat) + case bouncesOnChange(Bool) + case segmentSpacing(CGFloat) +} diff --git a/Pod/Classes/Segments/LabelSegment.swift b/Pod/Classes/Segments/LabelSegment.swift index f32f64c..c83df98 100644 --- a/Pod/Classes/Segments/LabelSegment.swift +++ b/Pod/Classes/Segments/LabelSegment.swift @@ -15,9 +15,22 @@ open class LabelSegment: BetterSegmentedControlSegment { static let normalBackgroundColor: UIColor = .clear static let normalTextColor: UIColor = .black static let normalFont: UIFont = .systemFont(ofSize: 13) + static var normalAttributes: ((UIFont?, UIColor?) -> [NSAttributedString.Key: Any]) = { (normalFont, normalTextColor) in + var attrs = [NSAttributedString.Key: Any]() + attrs[NSAttributedString.Key.font] = normalFont == nil ? DefaultValues.normalFont : normalFont! + attrs[NSAttributedString.Key.foregroundColor] = normalTextColor == nil ? DefaultValues.normalTextColor : normalTextColor! + return attrs + } + static let selectedBackgroundColor: UIColor = .clear static let selectedTextColor: UIColor = .black static let selectedFont: UIFont = .systemFont(ofSize: 13, weight: .medium) + static var selectedAttributes: ((UIFont?, UIColor?) -> [NSAttributedString.Key: Any]) = { (selectedFont, selectedTextColor) in + var attrs = [NSAttributedString.Key: Any]() + attrs[NSAttributedString.Key.font] = selectedFont == nil ? DefaultValues.selectedFont : selectedFont! + attrs[NSAttributedString.Key.foregroundColor] = selectedTextColor == nil ? DefaultValues.selectedTextColor : selectedTextColor! + return attrs + } } // MARK: Properties @@ -26,10 +39,12 @@ open class LabelSegment: BetterSegmentedControlSegment { public let normalFont: UIFont public let normalTextColor: UIColor public let normalBackgroundColor: UIColor + public let normalAttributes: [NSAttributedString.Key: Any] public let selectedFont: UIFont public let selectedTextColor: UIColor public let selectedBackgroundColor: UIColor + public let selectedAttributes: [NSAttributedString.Key: Any] private let numberOfLines: Int private let accessibilityIdentifier: String? @@ -40,18 +55,22 @@ open class LabelSegment: BetterSegmentedControlSegment { normalBackgroundColor: UIColor? = nil, normalFont: UIFont? = nil, normalTextColor: UIColor? = nil, + normalAttributes: [NSAttributedString.Key: Any]? = nil, selectedBackgroundColor: UIColor? = nil, selectedFont: UIFont? = nil, selectedTextColor: UIColor? = nil, + selectedAttributes: [NSAttributedString.Key: Any]? = nil, accessibilityIdentifier: String? = nil) { self.text = text self.numberOfLines = numberOfLines self.normalBackgroundColor = normalBackgroundColor ?? DefaultValues.normalBackgroundColor self.normalFont = normalFont ?? DefaultValues.normalFont self.normalTextColor = normalTextColor ?? DefaultValues.normalTextColor + self.normalAttributes = normalAttributes ?? DefaultValues.normalAttributes(normalFont, normalTextColor) self.selectedBackgroundColor = selectedBackgroundColor ?? DefaultValues.selectedBackgroundColor self.selectedFont = selectedFont ?? DefaultValues.selectedFont self.selectedTextColor = selectedTextColor ?? DefaultValues.selectedTextColor + self.selectedAttributes = selectedAttributes ?? DefaultValues.selectedAttributes(selectedFont, selectedTextColor) self.accessibilityIdentifier = accessibilityIdentifier } @@ -65,6 +84,7 @@ open class LabelSegment: BetterSegmentedControlSegment { backgroundColor: normalBackgroundColor, font: normalFont, textColor: normalTextColor, + attributes: normalAttributes, accessibilityIdentifier: accessibilityIdentifier) }() public lazy var selectedView: UIView = { @@ -72,12 +92,14 @@ open class LabelSegment: BetterSegmentedControlSegment { backgroundColor: selectedBackgroundColor, font: selectedFont, textColor: selectedTextColor, + attributes: selectedAttributes, accessibilityIdentifier: accessibilityIdentifier) }() open func createLabel(withText text: String?, backgroundColor: UIColor, font: UIFont, textColor: UIColor, + attributes: [NSAttributedString.Key: Any], accessibilityIdentifier: String?) -> UILabel { let label = UILabel() label.text = text @@ -85,6 +107,7 @@ open class LabelSegment: BetterSegmentedControlSegment { label.backgroundColor = backgroundColor label.font = font label.textColor = textColor + label.attributedText = text == nil ? nil : NSAttributedString(string: text!, attributes: attributes) label.lineBreakMode = .byTruncatingTail label.textAlignment = .center label.accessibilityIdentifier = accessibilityIdentifier @@ -98,18 +121,22 @@ public extension LabelSegment { normalBackgroundColor: UIColor? = nil, normalFont: UIFont? = nil, normalTextColor: UIColor? = nil, + normalAttributes: [NSAttributedString.Key: Any]? = nil, selectedBackgroundColor: UIColor? = nil, selectedFont: UIFont? = nil, - selectedTextColor: UIColor? = nil) -> [BetterSegmentedControlSegment] { + selectedTextColor: UIColor? = nil, + selectedAttributes: [NSAttributedString.Key: Any]? = nil) -> [BetterSegmentedControlSegment] { titles.map { LabelSegment(text: $0, numberOfLines: numberOfLines, normalBackgroundColor: normalBackgroundColor, normalFont: normalFont, normalTextColor: normalTextColor, + normalAttributes: normalAttributes, selectedBackgroundColor: selectedBackgroundColor, selectedFont: selectedFont, - selectedTextColor: selectedTextColor) + selectedTextColor: selectedTextColor, + selectedAttributes: selectedAttributes) } } }