Skip to content
This repository was archived by the owner on Apr 11, 2021. It is now read-only.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CD9A24061DD5A64F00B580D0"
BuildableName = "ScrollableSegmentedControlDemo.app"
BlueprintName = "ScrollableSegmentedControlDemo"
ReferencedContainer = "container:ScrollableSegmentedControlDemo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CD9A24061DD5A64F00B580D0"
BuildableName = "ScrollableSegmentedControlDemo.app"
BlueprintName = "ScrollableSegmentedControlDemo"
ReferencedContainer = "container:ScrollableSegmentedControlDemo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CD9A24061DD5A64F00B580D0"
BuildableName = "ScrollableSegmentedControlDemo.app"
BlueprintName = "ScrollableSegmentedControlDemo"
ReferencedContainer = "container:ScrollableSegmentedControlDemo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CD9A24061DD5A64F00B580D0"
BuildableName = "ScrollableSegmentedControlDemo.app"
BlueprintName = "ScrollableSegmentedControlDemo"
ReferencedContainer = "container:ScrollableSegmentedControlDemo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="kHm-QZ-Lrg">
<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="kHm-QZ-Lrg">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand Down Expand Up @@ -145,13 +144,13 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Fixed width" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jhr-fH-pwu">
<rect key="frame" x="16" y="0.0" width="290" height="46"/>
<rect key="frame" x="16" y="0.0" width="290" height="45.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SeK-Hz-YgZ">
<rect key="frame" x="314" y="8" width="51" height="31"/>
<rect key="frame" x="314" y="7.5" width="51" height="31"/>
<connections>
<action selector="toggleFixedWidth:" destination="Ulk-MU-gVx" eventType="valueChanged" id="fwq-np-3Xl"/>
</connections>
Expand All @@ -167,6 +166,39 @@
</constraints>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="AiP-2s-hC8">
<rect key="frame" x="0.0" y="455" width="375" height="46"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="AiP-2s-hC8" id="dil-FW-Au1">
<rect key="frame" x="0.0" y="0.0" width="375" height="45.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Underline height" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e2B-uQ-2dY">
<rect key="frame" x="16" y="0.0" width="126.5" height="45.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="3" minValue="1" maxValue="5" translatesAutoresizingMaskIntoConstraints="NO" id="Xg6-uj-iKM">
<rect key="frame" x="251" y="8" width="118" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="114" id="L20-6U-5ph"/>
</constraints>
<connections>
<action selector="underlineHeightChanged:" destination="Ulk-MU-gVx" eventType="valueChanged" id="y0h-zI-WC9"/>
</connections>
</slider>
</subviews>
<constraints>
<constraint firstItem="e2B-uQ-2dY" firstAttribute="top" secondItem="dil-FW-Au1" secondAttribute="top" id="2KE-FO-ilP"/>
<constraint firstAttribute="trailing" secondItem="Xg6-uj-iKM" secondAttribute="trailing" constant="8" id="4fa-GJ-Lz9"/>
<constraint firstItem="Xg6-uj-iKM" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="e2B-uQ-2dY" secondAttribute="trailing" constant="8" symbolic="YES" id="5Ly-0v-4H5"/>
<constraint firstItem="Xg6-uj-iKM" firstAttribute="centerY" secondItem="dil-FW-Au1" secondAttribute="centerY" id="XgK-q1-oay"/>
<constraint firstAttribute="bottom" secondItem="e2B-uQ-2dY" secondAttribute="bottom" id="ZJg-L8-ea3"/>
<constraint firstItem="e2B-uQ-2dY" firstAttribute="leading" secondItem="dil-FW-Au1" secondAttribute="leading" constant="16" id="qEh-fG-B5y"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
Expand Down Expand Up @@ -213,7 +245,7 @@
<rect key="frame" x="16" y="76" width="343" height="68"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="nt3-Bp-FeH">
<rect key="frame" x="147" y="0.0" width="50" height="68"/>
<rect key="frame" x="146.5" y="0.0" width="50" height="68"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="EhJ-iM-9EU">
<rect key="frame" x="0.0" y="0.0" width="50" height="39.5"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class TableViewController: UITableViewController {
segmentedControl.insertSegment(withTitle: "Seg 4", image: #imageLiteral(resourceName: "segment-4"), at: 3)
segmentedControl.insertSegment(withTitle: "Segment 5", image: #imageLiteral(resourceName: "segment-5"), at: 4)
segmentedControl.insertSegment(withTitle: "Segment 6", image: #imageLiteral(resourceName: "segment-6"), at: 5)
segmentedControl.underlineHeight = 3.0

segmentedControl.underlineSelected = true
segmentedControl.selectedSegmentIndex = 0
Expand All @@ -60,6 +61,9 @@ class TableViewController: UITableViewController {
}
}

@IBAction func underlineHeightChanged(_ sender: UISlider) {
segmentedControl.underlineHeight = CGFloat(sender.value)
}
@IBAction func toggleFixedWidth(_ sender: UISwitch) {
segmentedControl.fixedSegmentWidth = sender.isOn
segmentedControl.setNeedsLayout()
Expand Down
41 changes: 34 additions & 7 deletions ScrollableSegmentedControl/ScrollableSegmentedControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {
reloadSegments()
}
}

fileprivate var _underlineHeight: CGFloat = 4.0
@objc public dynamic var underlineHeight: CGFloat {
get { return _underlineHeight }
set {
_underlineHeight = newValue
reloadSegments()
}
}

fileprivate var _selectedSegmentContentColor:UIColor?
@objc public dynamic var selectedSegmentContentColor:UIColor? {
Expand Down Expand Up @@ -470,7 +479,7 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {

segmentCell = cell
}

segmentCell.underlineHeight = segmentedControl.underlineHeight
segmentCell.showUnderline = segmentedControl.underlineSelected
if segmentedControl.underlineSelected {
segmentCell.tintColor = segmentedControl.tintColor
Expand Down Expand Up @@ -532,6 +541,11 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {
static let defaultTextColor = UIColor.darkGray

var underlineView:UIView?
var underlineHeight: CGFloat = 4.0 {
didSet {
setNeedsUpdateConstraints()
}
}
public var contentColor:UIColor?
public var selectedContentColor:UIColor?

Expand Down Expand Up @@ -581,7 +595,9 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {
private func configureConstraints() {
if let underline = underlineView {
underline.translatesAutoresizingMaskIntoConstraints = false
underline.heightAnchor.constraint(equalToConstant: 4.0).isActive = true
let heightConstrain = underline.heightAnchor.constraint(equalToConstant: underlineHeight)
variableConstraints.append(heightConstrain)
heightConstrain.isActive = true
underline.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
underline.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
underline.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
Expand Down Expand Up @@ -624,7 +640,11 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {

override var isHighlighted: Bool {
didSet {
if let title = (isHighlighted) ? super.highlightedAttributedTitle : super.normalAttributedTitle {
if isHighlighted, let title = super.highlightedAttributedTitle {
titleLabel.attributedText = title
} else if isSelected, let title = super.selectedAttributedTitle {
titleLabel.attributedText = title
} else if let title = super.normalAttributedTitle {
titleLabel.attributedText = title
} else {
titleLabel.isHighlighted = isHighlighted
Expand Down Expand Up @@ -668,7 +688,10 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {
variableConstraints.append(titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor))
variableConstraints.append(titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: BaseSegmentCollectionViewCell.textPadding))
variableConstraints.append(titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -BaseSegmentCollectionViewCell.textPadding))


if let underline = underlineView {
variableConstraints.append(underline.heightAnchor.constraint(equalToConstant: underlineHeight))
}
NSLayoutConstraint.activate(variableConstraints)
}
}
Expand All @@ -684,7 +707,7 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {

override var isHighlighted: Bool {
didSet {
if isHighlighted {
if isHighlighted || isSelected {
imageView.tintColor = (selectedContentColor == nil) ? BaseSegmentCollectionViewCell.defaultTextColor : selectedContentColor!
} else {
imageView.tintColor = (contentColor == nil) ? BaseSegmentCollectionViewCell.defaultTextColor : contentColor!
Expand Down Expand Up @@ -744,13 +767,17 @@ public enum ScrollableSegmentedControlSegmentStyle: Int {

override var isHighlighted: Bool {
didSet {
if let title = (isHighlighted) ? super.highlightedAttributedTitle : super.normalAttributedTitle {
if isHighlighted, let title = super.highlightedAttributedTitle {
titleLabel.attributedText = title
} else if isSelected, let title = super.selectedAttributedTitle {
titleLabel.attributedText = title
} else if let title = super.normalAttributedTitle {
titleLabel.attributedText = title
} else {
titleLabel.isHighlighted = isHighlighted
}

if isHighlighted {
if isHighlighted || isSelected {
imageView.tintColor = (selectedContentColor == nil) ? BaseSegmentCollectionViewCell.defaultTextColor : selectedContentColor!
} else {
imageView.tintColor = (contentColor == nil) ? BaseSegmentCollectionViewCell.defaultTextColor : contentColor!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,32 @@ class ScrollableSegmentedControlTests: XCTestCase {
underlineView = cell?.contentView.viewWithTag(999)
XCTAssertTrue(underlineView?.backgroundColor == color)
}

func testUnderlineHeight() {
segmentedControl.insertSegment(withTitle: "segment 1", image: nil, at: 0)
segmentedControl.underlineSelected = true
segmentedControl.segmentStyle = .textOnly

self.segmentedControl.underlineHeight = 3
segmentedControl.selectedSegmentIndex = 0

var collectionView = self.segmentedControl.viewWithTag(1) as? UICollectionView
var indexPath = collectionView!.indexPathsForSelectedItems?.last
var cell = collectionView?.dataSource?.collectionView(collectionView!, cellForItemAt: indexPath!)
var underlineView = cell?.contentView.viewWithTag(999)
// The underline has only one constraint at its level, the height
XCTAssertTrue(underlineView?.constraints.first?.constant == 3)

self.segmentedControl.underlineHeight = 10

collectionView = self.segmentedControl.viewWithTag(1) as? UICollectionView
indexPath = collectionView!.indexPathsForSelectedItems?.last
cell = collectionView?.dataSource?.collectionView(collectionView!, cellForItemAt: indexPath!)
underlineView = cell?.contentView.viewWithTag(999)
// The underline has only one constraint at its level, the height
XCTAssertTrue(underlineView?.constraints.first?.constant == 10)

}

// func testPerformanceExample() {
// // This is an example of a performance test case.
Expand Down