Skip to content

Commit f3e97f6

Browse files
committed
Enhancements ๐ŸŒด
โ€“ย We can now go back by tapping on the same tab. ๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ป(Thanks Nishan) โ€“ Swift 5.0 โœ… โ€“ Updated the example ๐Ÿคธ๐Ÿผโ€โ™‚๏ธ โ€“ย Code refactored nicely ๐Ÿค˜๐Ÿผ
1 parent 75a5ebd commit f3e97f6

File tree

5 files changed

+92
-27
lines changed

5 files changed

+92
-27
lines changed

โ€ŽHHTabBarView/HHTabBarView.xcodeproj/project.pbxprojโ€Ž

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,19 @@
108108
isa = PBXProject;
109109
attributes = {
110110
LastSwiftUpdateCheck = 0830;
111-
LastUpgradeCheck = 1010;
111+
LastUpgradeCheck = 1020;
112112
ORGANIZATIONNAME = "Hemang Shah";
113113
TargetAttributes = {
114114
F1C7BB261F25EE7800D91CAB = {
115115
CreatedOnToolsVersion = 8.3;
116-
LastSwiftMigration = 0830;
116+
LastSwiftMigration = 1020;
117117
ProvisioningStyle = Automatic;
118118
};
119119
};
120120
};
121121
buildConfigurationList = F1C7BB221F25EE7800D91CAB /* Build configuration list for PBXProject "HHTabBarView" */;
122122
compatibilityVersion = "Xcode 3.2";
123-
developmentRegion = English;
123+
developmentRegion = en;
124124
hasScannedForEncodings = 0;
125125
knownRegions = (
126126
en,
@@ -190,6 +190,7 @@
190190
isa = XCBuildConfiguration;
191191
buildSettings = {
192192
ALWAYS_SEARCH_USER_PATHS = NO;
193+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
193194
CLANG_ANALYZER_NONNULL = YES;
194195
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
195196
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -249,6 +250,7 @@
249250
isa = XCBuildConfiguration;
250251
buildSettings = {
251252
ALWAYS_SEARCH_USER_PATHS = NO;
253+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
252254
CLANG_ANALYZER_NONNULL = YES;
253255
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
254256
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -307,7 +309,7 @@
307309
PRODUCT_BUNDLE_IDENTIFIER = com.hemangshah.HHTabBarView;
308310
PRODUCT_NAME = "$(TARGET_NAME)";
309311
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
310-
SWIFT_VERSION = 4.2;
312+
SWIFT_VERSION = 5.0;
311313
};
312314
name = Debug;
313315
};
@@ -320,7 +322,7 @@
320322
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
321323
PRODUCT_BUNDLE_IDENTIFIER = com.hemangshah.HHTabBarView;
322324
PRODUCT_NAME = "$(TARGET_NAME)";
323-
SWIFT_VERSION = 4.2;
325+
SWIFT_VERSION = 5.0;
324326
};
325327
name = Release;
326328
};

โ€ŽHHTabBarView/HHTabBarView/AppDelegate.swiftโ€Ž

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
102102
hhTabBarView.defaultIndex = 0
103103

104104
//Show Animation on Switching Tabs
105-
hhTabBarView.tabChangeAnimationType = .none
105+
hhTabBarView.tabChangeAnimationType = .none
106106

107107
//Handle Tab Changes
108-
hhTabBarView.onTabTapped = { (tabIndex) in
108+
hhTabBarView.onTabTapped = { (tabIndex, isSameTab, controller) in
109+
if isSameTab {
110+
if let navcon = controller as? UINavigationController {
111+
navcon.popToRootViewController(animated: true)
112+
} else if let vc = controller as? UIViewController {
113+
vc.navigationController?.popToRootViewController(animated: true)
114+
}
115+
}
109116
print("Selected Tab Index:\(tabIndex)")
110117
}
111118
}

โ€ŽHHTabBarView/HHTabBarView/FirstViewController.swiftโ€Ž

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ class FirstViewController: UIViewController {
1515
// Do any additional setup after loading the view.
1616
self.title = "Location"
1717
}
18+
19+
override func viewWillAppear(_ animated: Bool) {
20+
super.viewWillAppear(animated)
21+
// This will be helpful in locking the current tab if we're already in the first view-controller in navigation flow.
22+
HHTabBarView.shared.lockCurrentTab()
23+
}
24+
25+
override func viewWillDisappear(_ animated: Bool) {
26+
super.viewWillDisappear(animated)
27+
// This will be helpful to unlock the locked tab when we're going forward from the first view-controller in navigation flow.
28+
HHTabBarView.shared.unlockAllTabs()
29+
}
1830
}
1931

2032
extension FirstViewController: UITableViewDataSource {
@@ -32,3 +44,13 @@ extension FirstViewController: UITableViewDataSource {
3244
return cell
3345
}
3446
}
47+
48+
extension FirstViewController: UITableViewDelegate {
49+
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
50+
tableView.deselectRow(at: indexPath, animated: false)
51+
let viewController = UIViewController()
52+
viewController.title = "Location \(indexPath.row)"
53+
viewController.view.backgroundColor = UIColor.white
54+
self.navigationController?.pushViewController(viewController, animated: true)
55+
}
56+
}

โ€ŽHHTabBarView/HHTabBarView/Source/HHButton+Extension.swiftโ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public extension HHTabButton {
4848
}
4949

5050
///Set Background Color for various UIButton states.
51-
public func setHHTabBackgroundColor(color: UIColor, forState: UIControl.State) {
51+
func setHHTabBackgroundColor(color: UIColor, forState: UIControl.State) {
5252
UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
5353
UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor)
5454
UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1))

โ€ŽHHTabBarView/HHTabBarView/Source/HHTabBarView.swiftโ€Ž

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public class HHTabBarView: UIView {
3838

3939
///For Internal Navigation
4040
private(set) public var referenceUITabBarController = UITabBarController()
41+
///Current Tab Index: Internal Usage Only.
42+
private(set) var currentTabIndex: Int = 0
4143

4244
// MARK: Setters
4345
///Animation Type. Default: none.
@@ -85,18 +87,18 @@ public class HHTabBarView: UIView {
8587
public func rightToLeft() {
8688
let t = CGAffineTransform.init(scaleX: -1, y: -1)
8789
self.transform = t
88-
_ = self.subviews.map {$0.transform = t }
90+
_ = self.subviews.map { $0.transform = t }
8991
}
9092

9193
///Reverse the Tabs from LeftToRight [Usage English/Arabic UI]
9294
public func leftToRight() {
9395
let t = CGAffineTransform.init(scaleX: 1, y: 1)
9496
self.transform = t
95-
_ = self.subviews.map {$0.transform = t }
97+
_ = self.subviews.map { $0.transform = t }
9698
}
9799

98100
///Completion Handler for Tab Changes
99-
public var onTabTapped:((_ tabIndex: Int) -> Void)! = nil
101+
public var onTabTapped:((_ tabIndex: Int, _ isSameTab: Bool, _ controller: Any?) -> Void)? = nil
100102

101103
// MARK: Init
102104
private override init(frame: CGRect) {
@@ -128,38 +130,57 @@ public class HHTabBarView: UIView {
128130
frame = getHHTabBarViewFrame()
129131
}
130132

131-
//Helper to Select a Particular Tab.
133+
///Helper to Select a Particular Tab.
132134
public func selectTabAtIndex(withIndex tabIndex: Int) {
133135
// Tab Selection/Deselection
134-
_ = tabBarTabs.map {$0.isSelected = ($0.tabIndex == tabIndex) ? true : false}
136+
_ = tabBarTabs.map { $0.isSelected = ($0.tabIndex == tabIndex) ? true : false}
135137
// Apply Tab Changes in UITabBarController
136138
referenceUITabBarController.selectedIndex = tabIndex
137139
// Lock or Unlock the Tabs if requires.
138140
lockUnlockTabs()
139-
// Disable interaction for the current tab.
140-
let currentHHTabButton = tabBarTabs[tabIndex]
141-
currentHHTabButton.isUserInteractionEnabled = false
141+
142+
currentTabIndex = tabIndex
142143
}
143144

144-
///A convenience method to show or hide HHTabBarView.
145+
/// A convenience method to show or hide HHTabBarView.
145146
public func toggleShowOrHide() {
146147
self.isHidden = !isHidden
147148
}
148149

149-
//Overriding Default Properties
150+
// Overriding Default Properties
151+
/// To hide the HHTabBarView.
150152
override public var isHidden: Bool {
151153
willSet {
152154
self.referenceUITabBarController.tabBar.isHidden = !isHidden
153155
}
154156
}
155157

158+
/// Lock Current tab, if don't want to select the same tab again.
159+
public func lockCurrentTab() {
160+
for (index, tab) in tabBarTabs.enumerated() {
161+
if index == currentTabIndex {
162+
if let controllers = self.referenceUITabBarController.viewControllers, let navcon = controllers[currentTabIndex] as? UINavigationController {
163+
if navcon.viewControllers.count == 1 {
164+
tab.isUserInteractionEnabled = false
165+
break
166+
}
167+
}
168+
}
169+
}
170+
}
171+
172+
/// Unlock all of the tabs at once.
173+
public func unlockAllTabs(ignoreAlreadyLocked: Bool = false) {
174+
unlockAllTabs(); if ignoreAlreadyLocked { lockSpecifiedTab() }
175+
}
176+
156177
// MARK: Helpers
157178
private func getHHTabBarViewFrame() -> CGRect {
158179
let screentWidth = UIScreen.width
159180
let screentHeight = UIScreen.height
160181
var tabBarHeight = hhTabBarViewHeight
161182

162-
if self.tabBarViewPosition == .top {
183+
if tabBarViewPosition == .top {
163184
return CGRect.init(x: 0.0, y: tabBarViewTopPositionValue, width: screentWidth, height: tabBarHeight)
164185
} else {
165186
if #available(iOS 11.0, *) {
@@ -174,11 +195,18 @@ public class HHTabBarView: UIView {
174195
return tabBarTabs.isEmpty ? false : true
175196
}
176197

198+
private func unlockAllTabs() {
199+
_ = tabBarTabs.map { $0.isUserInteractionEnabled = true }
200+
}
201+
177202
private func lockUnlockTabs() {
178203
//Unlock All Tabs Before Locking.
179-
_ = tabBarTabs.map {$0.isUserInteractionEnabled = true}
180-
204+
unlockAllTabs()
181205
//Then Lock the provided Tab Indexes.
206+
lockSpecifiedTab()
207+
}
208+
209+
private func lockSpecifiedTab() {
182210
if !lockTabIndexes.isEmpty {
183211
for index in lockTabIndexes {
184212
let hhTabButton = tabBarTabs[index]
@@ -199,24 +227,30 @@ public class HHTabBarView: UIView {
199227
addSubview(hhTabButton)
200228
xPos += width
201229
}
202-
self.defaultIndex = 0
230+
defaultIndex = 0
203231
}
204232

205233
//Actions
206234
@objc private func actionTabTapped(tab: HHTabButton) {
207-
if onTabTapped != nil {
235+
let tappedTabIndex = tab.tabIndex
236+
var isSameTab: Bool = false
237+
let controller = referenceUITabBarController.viewControllers?[tappedTabIndex]
238+
if currentTabIndex == tappedTabIndex {
239+
isSameTab = true
240+
} else {
241+
isSameTab = false
208242
animateTabBarButton(tabBarButton: tab)
209243
selectTabAtIndex(withIndex: tab.tabIndex)
210-
onTabTapped(tab.tabIndex)
211244
}
245+
onTabTapped?(tappedTabIndex, isSameTab, controller)
212246
}
213247

214248
//Perform Animation on Tab Changes.
215249
private func animateTabBarButton(tabBarButton: HHTabButton) {
216250
switch self.tabChangeAnimationType {
217-
case .flash: tabBarButton.flash(); break
218-
case .shake: tabBarButton.shake(); break
219-
case .pulsate: tabBarButton.pulsate(); break
251+
case .flash: tabBarButton.flash()
252+
case .shake: tabBarButton.shake()
253+
case .pulsate: tabBarButton.pulsate()
220254
default: break
221255
}
222256
}

0 commit comments

Comments
ย (0)