From 73c57c7aca4b46d8fcc4b143c5e02533797699e3 Mon Sep 17 00:00:00 2001 From: WangWei Date: Thu, 7 May 2020 11:56:59 +0800 Subject: [PATCH] feature: support more customization for selection indicator --- .gitignore | 19 +++++++++++++- SegmentedControl/SegmentedControl.swift | 18 ++++++++----- .../project.pbxproj | 26 +++++++++++++------ 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index ff0bcff..ce052d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,18 @@ -SegmentedControl.xcworkspace/xcuserdata +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +xcuserdata/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. + +Carthage/Checkouts +Carthage/Build diff --git a/SegmentedControl/SegmentedControl.swift b/SegmentedControl/SegmentedControl.swift index faab673..d336d9e 100644 --- a/SegmentedControl/SegmentedControl.swift +++ b/SegmentedControl/SegmentedControl.swift @@ -48,9 +48,12 @@ open class SegmentedControl: UIControl { open var selectionIndicatorStyle: SegmentedControlSelectionIndicatorStyle = .none open var selectionIndicatorColor = UIColor.black open var selectionIndicatorHeight = SelectionIndicator.defaultHeight - /// Only available in fixed layout policy open var selectionIndicatorEdgeInsets = UIEdgeInsets.zero + open var selectionIndicatorCornerRadius: CGFloat = 0 open var titleAttachedIconPositionOffset: (x: CGFloat, y: CGFloat) = (0, 0) + + /// Use center alignment when not fill the width + open var horizontallyCenterIfPossible: Bool = true open fileprivate(set) var titles = [NSAttributedString]() { didSet { @@ -282,7 +285,7 @@ public extension SegmentedControl { scrollView.contentInset = UIEdgeInsets.zero case .dynamic: scrollView.contentSize = CGSize(width: totalSegmentsWidth() + contentInset.left + contentInset.right, height: frame.height) - if (totalSegmentsWidth() + contentInset.left + contentInset.right) < frame.width { + if horizontallyCenterIfPossible && (totalSegmentsWidth() + contentInset.left + contentInset.right) < frame.width { let padding = (frame.width - totalSegmentsWidth()) / 2 scrollView.contentInset = UIEdgeInsets(top: 0, left: padding - contentInset.left, bottom: 0, right: padding - contentInset.right) } else { @@ -571,6 +574,7 @@ public extension SegmentedControl { fileprivate func drawSelectionIndicator() { selectionIndicatorLayer.frame = frameForSelectionIndicator() + selectionIndicatorLayer.cornerRadius = selectionIndicatorCornerRadius if selectionBoxLayer.superlayer == nil { if let _ = selectionIndicatorLayer.superlayer { scrollView.layer.insertSublayer(selectionIndicatorLayer, above: selectionBoxLayer) @@ -694,10 +698,12 @@ public extension SegmentedControl { width: fullRect.width - (selectionIndicatorEdgeInsets.left + selectionIndicatorEdgeInsets.right), height: fullRect.height - (selectionIndicatorEdgeInsets.top + selectionIndicatorEdgeInsets.bottom)) case .dynamic: - return CGRect(x: xPosition, - y: yPosition, - width: singleSegmentWidth(at: selectedIndex), - height: selectionIndicatorHeight) + return CGRect( + x: xPosition, + y: yPosition, + width: singleSegmentWidth(at: selectedIndex), + height: selectionIndicatorHeight + ).inset(by: selectionIndicatorEdgeInsets) } }() return indicatorRect diff --git a/SegmentedControlExample.xcodeproj/project.pbxproj b/SegmentedControlExample.xcodeproj/project.pbxproj index f67e2e7..ff1886f 100644 --- a/SegmentedControlExample.xcodeproj/project.pbxproj +++ b/SegmentedControlExample.xcodeproj/project.pbxproj @@ -7,8 +7,8 @@ objects = { /* Begin PBXBuildFile section */ - D341EB501D1A838400677EAF /* SegmentedControl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D341EB4F1D1A838400677EAF /* SegmentedControl.framework */; }; - D341EB511D1A838400677EAF /* SegmentedControl.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D341EB4F1D1A838400677EAF /* SegmentedControl.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4AA16E482463B4D400547F70 /* SegmentedControl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AA16E472463B4D400547F70 /* SegmentedControl.framework */; }; + 4AA16E492463B4D500547F70 /* SegmentedControl.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4AA16E472463B4D400547F70 /* SegmentedControl.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D3E3B0E31C328316003EAA6E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E3B0E21C328316003EAA6E /* AppDelegate.swift */; }; D3E3B0E51C328316003EAA6E /* ExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E3B0E41C328316003EAA6E /* ExampleViewController.swift */; }; D3E3B0E81C328316003EAA6E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D3E3B0E61C328316003EAA6E /* Main.storyboard */; }; @@ -16,13 +16,13 @@ /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - D341EB521D1A838400677EAF /* Embed Frameworks */ = { + 4AA16E4A2463B4D500547F70 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - D341EB511D1A838400677EAF /* SegmentedControl.framework in Embed Frameworks */, + 4AA16E492463B4D500547F70 /* SegmentedControl.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -30,7 +30,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - D341EB4F1D1A838400677EAF /* SegmentedControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = SegmentedControl.framework; path = "/Users/hongxin/Library/Developer/Xcode/DerivedData/SegmentedControl-fegllupftdbokageotnuxdmypufc/Build/Products/Debug-iphonesimulator/SegmentedControl.framework"; sourceTree = ""; }; + 4AA16E432463B4C100547F70 /* SegmentedControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SegmentedControl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4AA16E472463B4D400547F70 /* SegmentedControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SegmentedControl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D3E3B0DF1C328316003EAA6E /* SegmentedControlExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SegmentedControlExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; D3E3B0E21C328316003EAA6E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; D3E3B0E41C328316003EAA6E /* ExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleViewController.swift; sourceTree = ""; }; @@ -44,19 +45,28 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D341EB501D1A838400677EAF /* SegmentedControl.framework in Frameworks */, + 4AA16E482463B4D400547F70 /* SegmentedControl.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 4AA16E422463B4C100547F70 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4AA16E472463B4D400547F70 /* SegmentedControl.framework */, + 4AA16E432463B4C100547F70 /* SegmentedControl.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; D3E3B0D61C328316003EAA6E = { isa = PBXGroup; children = ( - D341EB4F1D1A838400677EAF /* SegmentedControl.framework */, D3E3B0E11C328316003EAA6E /* SegmentedControlExample */, D3E3B0E01C328316003EAA6E /* Products */, + 4AA16E422463B4C100547F70 /* Frameworks */, ); sourceTree = ""; }; @@ -90,7 +100,7 @@ D3E3B0DB1C328316003EAA6E /* Sources */, D3E3B0DC1C328316003EAA6E /* Frameworks */, D3E3B0DD1C328316003EAA6E /* Resources */, - D341EB521D1A838400677EAF /* Embed Frameworks */, + 4AA16E4A2463B4D500547F70 /* Embed Frameworks */, ); buildRules = ( );