Skip to content

Commit

Permalink
Merge pull request #49 from daria-andrioaie/feature/customizable-border
Browse files Browse the repository at this point in the history
Customizable border
  • Loading branch information
Efraim Budusan authored Aug 30, 2023
2 parents 251e9a0 + 291b85e commit bd9b966
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"location" : "https://github.com/dumitruigor/TTSegmentedControl",
"state" : {
"branch" : "swiftPackage",
"revision" : "e2ae5f785e390821e94feda4d2901a032006b8e4"
"revision" : "74c04ff4e98d0a6e8fc8382908279e4d7b841ad1"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,22 @@ extension SwiftUIView {
opacity: 1,
radius: 4
)

let selectionViewInnerShadow = TTSegmentedControlShadow(
color: "000000".color,
offset: .init(width: 0, height: 6),
innerOffset: .init(width: 0, height: -10),
opacity: 0.3,
radius: 4
)
let border = TTSegmentedControlBorder(color: .black, lineWidth: 1)

return TTSwiftUISegmentedControl(titles: firstSegmentControlTitles)
.selectionViewColorType(.color(value:"F59E0B".color))
.bounceAnimationOptions( .init())
.cornerRadius(.constant(value: 8))
.selectionViewPadding(.init(width: 4, height: 4))
.selectionViewBorder(border)
.containerViewBorder(border)
.selectionViewInnerShadow(selectionViewInnerShadow)
.containerViewInnerShadow(containerInnerShadow)
.frame(height: 48)
Expand Down Expand Up @@ -169,6 +171,7 @@ extension SwiftUIView {
opacity: 1,
radius: 4
)

return HStack(spacing: .zero) {
TTSwiftUISegmentedControl(titles: thirdSegmentedControlTitles)
.selectionViewColorType(.colorWithGradient(color: "FFCC00".color, gradient: gradient))
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This project is maintained by Tapptitude, a mobile app development agency specia
- Variable number of items
- Animated transition
- Bounce animation
- Fully configurable (color, gradient, shadow, corner radius)
- Fully configurable (color, gradient, shadow, border, corner radius)
- Designable into Interface Builder

## Requirements
Expand Down
Binary file modified Resources/TTSegmentedControl.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions Sources/TTSegmentedControl/Extensions/UIView+Border.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// UIView+Border.swift
// TTSegmentedControl
//
// Created by Daria Andrioaie on 23.08.2023.
//

import UIKit

extension UIView {
func apply(_ border: TTSegmentedControlBorder) {
layer.borderColor = border.color.cgColor
layer.borderWidth = border.lineWidth
}
}
18 changes: 18 additions & 0 deletions Sources/TTSegmentedControl/Models/TTSegmentedControlBorder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// TTSegmentedControlBorder.swift
// TTSegmentedControl
//
// Created by Daria Andrioaie on 23.08.2023.
//

import UIKit

public struct TTSegmentedControlBorder {
public let color: UIColor
public let lineWidth: CGFloat

public init(color: UIColor, lineWidth: CGFloat = 1) {
self.color = color
self.lineWidth = lineWidth
}
}
12 changes: 12 additions & 0 deletions Sources/TTSegmentedControl/TTSegmentedControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ public final class TTSegmentedControl: UIView {
public var bounceAnimationOptions: TTSegmentedControlBounceOptions?
public var selectionViewShadow: TTSegmentedControlShadow? { didSet { configure() } }
public var selectionViewInnerShadow: TTSegmentedControlShadow? { didSet { reloadView() } }
public var selectionViewBorder: TTSegmentedControlBorder? { didSet { configure() } }
public var titleDistribution: TitleDistribution = .equalSpacing { didSet { reloadView() } }
public var isDragEnabled: Bool = true
public var animationOptions: TTSegmentedControlAnimationOption? = .init()
public var isSizeAdjustEnabled: Bool = true
public var containerViewInnerShadow: TTSegmentedControlShadow? { didSet { reloadView() } }
public var containerViewBorder: TTSegmentedControlBorder? { didSet { reloadView() } }
public var containerColorType: ColorType = .color(value: .white) { didSet { configure() } }
public var selectionViewColorType: ColorType = .color(value: .blue) { didSet { configure() } }
public var selectionViewFillType: SelectionViewFillType = .fillSegment { didSet { updateLayout() } }
Expand Down Expand Up @@ -349,6 +351,7 @@ extension TTSegmentedControl {
extension TTSegmentedControl {
private func configure() {
configureContainerView()
configureContainerViewBorder()
configureContainerGradientLayer()
configureContainerViewInnerShadowLayer()
configureDefaultStateLabels()
Expand Down Expand Up @@ -382,6 +385,12 @@ extension TTSegmentedControl {
containerViewInnerShadowLayer.masksToBounds = true
}

private func configureContainerViewBorder() {
guard let containerBorder = containerViewBorder else { return }
defaultStateView.layer.borderWidth = containerBorder.lineWidth
defaultStateView.layer.borderColor = containerBorder.color.cgColor
}

private func configureDefaultStateLabels() {
for index in 0..<titles.count {
let tag = index + 1
Expand Down Expand Up @@ -420,6 +429,9 @@ extension TTSegmentedControl {
if let shadow = selectionViewShadow {
selectionView.apply(shadow)
}
if let border = selectionViewBorder {
selectionView.apply(border)
}
}

private func configureSwitchSecondSelectionViewGradientLayer() {
Expand Down
16 changes: 16 additions & 0 deletions Sources/TTSegmentedControl/TTSwiftUISegmentedControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ public struct TTSwiftUISegmentedControl: UIViewRepresentable {
private var isSizeAdjustEnabled: Bool = false
private var containerColorType: TTSegmentedControl.ColorType = .color(value: .white)
private var containerViewInnerShadow: TTSegmentedControlShadow? = nil
private var containerViewBorder: TTSegmentedControlBorder? = nil
private var selectionViewColorType: TTSegmentedControl.ColorType = .color(value: .blue)
private var switchSecondSelectionViewColorType: TTSegmentedControl.ColorType?
private var selectionViewShadow: TTSegmentedControlShadow? = nil
private var selectionViewInnerShadow: TTSegmentedControlShadow? = nil
private var selectionViewBorder: TTSegmentedControlBorder? = nil
private var selectionViewFillType: TTSegmentedControl.SelectionViewFillType = .fillSegment
private var bounceAnimationOptions: TTSegmentedControlBounceOptions? = nil
private var cornerRadius: TTSegmentedControl.CornerRadius = .maximum
Expand Down Expand Up @@ -110,12 +112,14 @@ extension TTSwiftUISegmentedControl {
segmentedView.padding = selectionViewPadding
segmentedView.bounceAnimationOptions = bounceAnimationOptions
segmentedView.selectionViewShadow = selectionViewShadow
segmentedView.selectionViewBorder = selectionViewBorder
segmentedView.selectionViewInnerShadow = selectionViewInnerShadow
segmentedView.isDragEnabled = isDragEnabled
segmentedView.animationOptions = animationOptions
segmentedView.isSizeAdjustEnabled = isSizeAdjustEnabled
segmentedView.containerColorType = containerColorType
segmentedView.containerViewInnerShadow = containerViewInnerShadow
segmentedView.containerViewBorder = containerViewBorder
segmentedView.selectionViewColorType = selectionViewColorType
segmentedView.switchSecondSelectionViewColorType = switchSecondSelectionViewColorType
segmentedView.selectionViewFillType = selectionViewFillType
Expand Down Expand Up @@ -189,6 +193,12 @@ extension TTSwiftUISegmentedControl {
view.selectionViewInnerShadow = shadow
return view
}

public func selectionViewBorder(_ border: TTSegmentedControlBorder?) -> TTSwiftUISegmentedControl {
var view = self
view.selectionViewBorder = border
return view
}

public func selectionViewFillType(_ type: TTSegmentedControl.SelectionViewFillType) -> TTSwiftUISegmentedControl {
var view = self
Expand Down Expand Up @@ -243,4 +253,10 @@ extension TTSwiftUISegmentedControl {
view.containerViewInnerShadow = shadow
return view
}

public func containerViewBorder(_ border: TTSegmentedControlBorder?) -> TTSwiftUISegmentedControl {
var view = self
view.containerViewBorder = border
return view
}
}
30 changes: 30 additions & 0 deletions Tests/TTSegmentedControlTests/TTSwiftUISegmentedControlTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ final class TTSwiftUISegmentedControlTests: XCTestCase {
}
}

func testContainerViewBorder() {
// Given
let border = TTSegmentedControlBorder(color: .red, lineWidth: 3)

// When
view = view.containerViewBorder(border)

// Then
verifyAfterDelay { [weak self] in
guard let self else { return }
XCTAssertEqual(self.uiKitSegmentView.containerViewBorder?.color, border.color)
XCTAssertEqual(self.uiKitSegmentView.containerViewBorder?.lineWidth, border.lineWidth)
}
}

func testSelectionViewColorTypeWithColor() {
// When
view = view.selectionViewColorType(.color(value: .black))
Expand Down Expand Up @@ -215,6 +230,21 @@ final class TTSwiftUISegmentedControlTests: XCTestCase {
}
}

func testSelectionViewBorder() {
// Given
let border = TTSegmentedControlBorder(color: .red, lineWidth: 3)

// When
view = view.selectionViewBorder(border)

// Then
verifyAfterDelay { [weak self] in
guard let self else { return }
XCTAssertEqual(self.uiKitSegmentView.selectionViewBorder?.color, border.color)
XCTAssertEqual(self.uiKitSegmentView.selectionViewBorder?.lineWidth, border.lineWidth)
}
}

func testSelectionViewFillType() {
// When
view = view.selectionViewFillType(.fillSegment)
Expand Down

0 comments on commit bd9b966

Please sign in to comment.
  NODES
COMMUNITY 1
Note 1
Project 7
USERS 1
Verify 2