Skip to content
25 changes: 16 additions & 9 deletions Example/BetterSegmentedControl/Base.lproj/LaunchScreen.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
Expand All @@ -11,20 +13,20 @@
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 CocoaPods. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text=" Copyright (c) 2015 CocoaPods. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" systemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="BetterSegmentedControl" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="BetterSegmentedControl" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" systemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
Expand All @@ -38,4 +40,9 @@
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
<resources>
<systemColor name="darkTextColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
18 changes: 18 additions & 0 deletions Example/BetterSegmentedControl/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ class ViewController: UIViewController {
index: -1)
noSelectedSegmentControl.addTarget(self, action: #selector(segmentedControl1ValueChanged(_:)), for: .valueChanged)
view.addSubview(noSelectedSegmentControl)

// Control 8: Icons with labels
let iconWithLabelSegmentControl = BetterSegmentedControl(
frame: CGRect(x: 0, y: 560, width: 200, height: 40),
segments: IconWithLabelSegment.segments(withIconsAndLabels: [IconWithLabel(icon: UIImage(named: "facebook")!, title: "Facebook"), IconWithLabel(icon: UIImage(named: "twitter")!, title: "Twitter")],
iconSize: CGSize(width: 20.0, height: 20.0),
normalIconTintColor: .systemTeal,
normalFont: .systemFont(ofSize: 10),
normalTextColor: .systemTeal,
selectedIconTintColor: #colorLiteral(red: 0.2117647059, green: 0.2705882353, blue: 0.3098039216, alpha: 1),
selectedFont: .systemFont(ofSize: 10)),
index: 1)
iconWithLabelSegmentControl.center.x = view.center.x
iconWithLabelSegmentControl.backgroundColor = #colorLiteral(red: 0.2117647059, green: 0.2705882353, blue: 0.3098039216, alpha: 1)
iconWithLabelSegmentControl.cornerRadius = 10
iconWithLabelSegmentControl.indicatorView.backgroundColor = .systemTeal
iconWithLabelSegmentControl.addTarget(self, action: #selector(segmentedControl1ValueChanged(_:)), for: .valueChanged)
view.addSubview(iconWithLabelSegmentControl)
}

// MARK: - Action handlers
Expand Down
6 changes: 3 additions & 3 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -31,12 +31,12 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
BetterSegmentedControl: ce9b68b81c963991211c561026ed2cf711f9ac63
BetterSegmentedControl: 09607b27861d49cbce48b7673b74f9150a3d371a
iOSSnapshotTestCase: 2d51aa06775e95cecb0a1fb9c5c159ccd1dd4596
Nimble: 051e3d8912d40138fa5591c78594f95fb172af37
Nimble-Snapshots: bbd1ab264bacc24a9ce24a8363bc05aac783aeb0
Quick: 7fb19e13be07b5dfb3b90d4f9824c855a11af40e

PODFILE CHECKSUM: 609c5442f2ad21fe0424eaab055f9caa5c2944a1

COCOAPODS: 1.9.3
COCOAPODS: 1.10.1
18 changes: 18 additions & 0 deletions Pod/Classes/Segments/IconWithLabel/IconWithLabel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// IconWithLabel.swift
// BetterSegmentedControl
//
// Created by Arman Zoghi on 2/15/21.
//

import Foundation
import UIKit

public class IconWithLabel {
let icon: UIImage
let title: String
public init(icon: UIImage, title: String) {
self.icon = icon
self.title = title
}
}
148 changes: 148 additions & 0 deletions Pod/Classes/Segments/IconWithLabel/IconWithLabelSegment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
//
// IconWithLabelSegment.swift
// BetterSegmentedControl
//
// Created by Arman Zoghi on 2/14/21.
//

#if canImport(UIKit)

import UIKit

open class IconWithLabelSegment: BetterSegmentedControlSegment {
// MARK: Constants
private struct DefaultValues {
static let normalBackgroundColor: UIColor = .clear
static let normalTextColor: UIColor = .black
static let normalFont: UIFont = .systemFont(ofSize: 13)
static let selectedBackgroundColor: UIColor = .clear
static let selectedTextColor: UIColor = .black
static let selectedFont: UIFont = .systemFont(ofSize: 13, weight: .medium)
}

// MARK: Properties
public var icon: UIImage
public var iconSize: CGSize
public let text: String?

public var normalIconTintColor: UIColor
public let normalFont: UIFont
public let normalTextColor: UIColor
public var normalBackgroundColor: UIColor

public var selectedIconTintColor: UIColor
public let selectedFont: UIFont
public let selectedTextColor: UIColor
public var selectedBackgroundColor: UIColor

private let numberOfLines: Int
private let accessibilityIdentifier: String?

// MARK: Lifecycle
public init(icon: UIImage,
text: String? = nil,
iconSize: CGSize,
numberOfLines: Int = 1,
normalBackgroundColor: UIColor? = nil,
normalIconTintColor: UIColor,
normalFont: UIFont? = nil,
normalTextColor: UIColor? = nil,
selectedBackgroundColor: UIColor? = nil,
selectedIconTintColor: UIColor,
selectedFont: UIFont? = nil,
selectedTextColor: UIColor? = nil,
accessibilityIdentifier: String? = nil) {
self.icon = icon.withRenderingMode(.alwaysTemplate)
self.text = text
self.iconSize = iconSize
self.numberOfLines = numberOfLines
self.normalBackgroundColor = normalBackgroundColor ?? DefaultValues.normalBackgroundColor
self.normalIconTintColor = normalIconTintColor
self.normalFont = normalFont ?? DefaultValues.normalFont
self.normalTextColor = normalTextColor ?? DefaultValues.normalTextColor
self.selectedBackgroundColor = selectedBackgroundColor ?? DefaultValues.selectedBackgroundColor
self.selectedFont = selectedFont ?? DefaultValues.selectedFont
self.selectedTextColor = selectedTextColor ?? DefaultValues.selectedTextColor
self.selectedIconTintColor = selectedIconTintColor
self.accessibilityIdentifier = accessibilityIdentifier
}

// MARK: BetterSegmentedControlSegment
public var intrinsicContentSize: CGSize? { nil }

public lazy var normalView: UIView = {
return createView(withIcon: icon,
iconSize: iconSize,
backgroundColor: normalBackgroundColor,
iconTintColor: normalIconTintColor,
withText: text,
font: normalFont,
textColor: normalTextColor,
accessibilityIdentifier: accessibilityIdentifier)
}()
public lazy var selectedView: UIView = {
return createView(withIcon: icon,
iconSize: iconSize,
backgroundColor: selectedBackgroundColor,
iconTintColor: selectedIconTintColor,
withText: text,
font: selectedFont,
textColor: selectedTextColor,
accessibilityIdentifier: accessibilityIdentifier)
}()
private func createView(withIcon icon: UIImage,
iconSize: CGSize,
backgroundColor: UIColor,
iconTintColor: UIColor,
withText text: String?,
font: UIFont?,
textColor: UIColor?,
accessibilityIdentifier: String?) -> UIView {
let view = IconWithLabelView()
view.backgroundColor = backgroundColor
view.imageViewConfig(icon: icon,
width: iconSize.width,
height: iconSize.height,
contentMode: .scaleAspectFit,
tintColor: iconTintColor)
view.labelConfig(text: text,
numberOfLines: numberOfLines,
font: font,
textColor: textColor,
lineBreakMode: .byTruncatingTail,
textAlignment: .center,
accessibilityIdentifier: accessibilityIdentifier)
return view
}
}

public extension IconWithLabelSegment {
class func segments(withIconsAndLabels iconsAndLabelS: [IconWithLabel],
iconSize: CGSize,
numberOfLines: Int = 1,
normalBackgroundColor: UIColor? = nil,
normalIconTintColor: UIColor,
normalFont: UIFont? = nil,
normalTextColor: UIColor? = nil,
selectedBackgroundColor: UIColor? = nil,
selectedIconTintColor: UIColor,
selectedFont: UIFont? = nil,
selectedTextColor: UIColor? = nil) -> [BetterSegmentedControlSegment] {
return iconsAndLabelS.map {
IconWithLabelSegment(icon: $0.icon,
text: $0.title,
iconSize: iconSize,
numberOfLines: numberOfLines,
normalBackgroundColor: normalBackgroundColor,
normalIconTintColor: normalIconTintColor,
normalFont: normalFont,
normalTextColor: normalTextColor,
selectedBackgroundColor: selectedBackgroundColor,
selectedIconTintColor: selectedIconTintColor,
selectedFont: selectedFont,
selectedTextColor: selectedTextColor)
}
}
}

#endif
64 changes: 64 additions & 0 deletions Pod/Classes/Segments/IconWithLabel/IconWithLabelView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// IconWithLabelView.swift
// BetterSegmentedControl
//
// Created by Arman Zoghi on 2/14/21.
//

import UIKit

class IconWithLabelView: UIView {
// MARK: Subviews
public var imageView: UIImageView?
public var label: UILabel?

// MARK: Lifecycle
override init(frame: CGRect) {
super.init(frame: frame)
}

public required init?(coder: NSCoder) {
super.init(coder: coder)
}

// MARK: Image View
//config
public func imageViewConfig(icon: UIImage, width: CGFloat, height: CGFloat, contentMode: UIView.ContentMode, tintColor: UIColor) {
self.imageView = UIImageView(image: icon)
self.imageView?.tintColor = tintColor
self.addSubview(self.imageView!)
self.imageViewConstraints(width: width, height: height)
}
//constraints
fileprivate func imageViewConstraints(width: CGFloat, height: CGFloat) {
self.imageView!.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: self.imageView!, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 0.65, constant: 0).isActive = true
NSLayoutConstraint(item: self.imageView!, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: self.imageView!, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0, constant: width).isActive = true
NSLayoutConstraint(item: self.imageView!, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 0, constant: height).isActive = true
}

// MARK: Label
//config
func labelConfig(text: String?, numberOfLines: Int?, font: UIFont?, textColor: UIColor?, lineBreakMode: NSLineBreakMode, textAlignment: NSTextAlignment, accessibilityIdentifier: String?) {
self.label = UILabel()
self.addSubview(self.label!)
self.labelConstraints()
self.label?.sizeToFit()
self.label?.text = text
self.label?.numberOfLines = numberOfLines ?? 1
self.label?.font = font
self.label?.textColor = textColor
self.label?.lineBreakMode = lineBreakMode
self.label?.textAlignment = textAlignment
self.label?.accessibilityIdentifier = accessibilityIdentifier
}
//constraints
fileprivate func labelConstraints() {
self.label!.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: self.label!, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.65, constant: 0).isActive = true
NSLayoutConstraint(item: self.label!, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: self.label!, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1, constant: 0).isActive = true
}

}