Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add didSelectPublisher to UITabBar #63

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add didSelectPublisher to UITabBar
  • Loading branch information
KimTaeHyeong17 committed Oct 21, 2021
commit 6269c2c7a47c7601531e85d03bcd2dae1d373636
4 changes: 4 additions & 0 deletions Example/Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
A24C440622F592E800BC2E2B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A24C440522F592E800BC2E2B /* Assets.xcassets */; };
A24C440922F592E800BC2E2B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A24C440722F592E800BC2E2B /* LaunchScreen.storyboard */; };
B9BC1EAD26BAE72B00AE95E5 /* UIScrollViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BC1EAC26BAE72B00AE95E5 /* UIScrollViewTests.swift */; };
CE1E41612721BE980033C23C /* UITabBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1E41602721BE980033C23C /* UITabBarTests.swift */; };
DC8A555624B5ED4B007BCEEC /* UITableViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8A555524B5ED4B007BCEEC /* UITableViewTests.swift */; };
DC8A555E24B60A9A007BCEEC /* UICollectionViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8A555D24B60A9A007BCEEC /* UICollectionViewTests.swift */; };
/* End PBXBuildFile section */
@@ -51,6 +52,7 @@
B84F6B1029BF235509B7F677 /* Pods-Example-ExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-ExampleTests.release.xcconfig"; path = "Target Support Files/Pods-Example-ExampleTests/Pods-Example-ExampleTests.release.xcconfig"; sourceTree = "<group>"; };
B9BC1EAC26BAE72B00AE95E5 /* UIScrollViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollViewTests.swift; sourceTree = "<group>"; wrapsLines = 1; };
BE798B0656978A899BDE50BF /* Pods_Example_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CE1E41602721BE980033C23C /* UITabBarTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITabBarTests.swift; sourceTree = "<group>"; };
DC8A555324B5ED4B007BCEEC /* ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
DC8A555524B5ED4B007BCEEC /* UITableViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewTests.swift; sourceTree = "<group>"; };
DC8A555724B5ED4B007BCEEC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -144,6 +146,7 @@
7822AD1D24E1504600187502 /* UITextViewTests.swift */,
0AEC3D4D25260DC7007EE97C /* UISearchBarTests.swift */,
3F50DED225D6B4B700AC53A7 /* UIPageControlTests.swift */,
CE1E41602721BE980033C23C /* UITabBarTests.swift */,
DC8A555724B5ED4B007BCEEC /* Info.plist */,
);
path = ExampleTests;
@@ -349,6 +352,7 @@
7822AD1E24E1504600187502 /* UITextViewTests.swift in Sources */,
0AEC3D4E25260DC7007EE97C /* UISearchBarTests.swift in Sources */,
DC8A555E24B60A9A007BCEEC /* UICollectionViewTests.swift in Sources */,
CE1E41612721BE980033C23C /* UITabBarTests.swift in Sources */,
B9BC1EAD26BAE72B00AE95E5 /* UIScrollViewTests.swift in Sources */,
3F50DED325D6B4B700AC53A7 /* UIPageControlTests.swift in Sources */,
DC8A555624B5ED4B007BCEEC /* UITableViewTests.swift in Sources */,
4 changes: 3 additions & 1 deletion Example/Example/ControlsViewController.swift
Original file line number Diff line number Diff line change
@@ -19,7 +19,8 @@ class ControlsViewController: UIViewController {
@IBOutlet private var datePicker: UIDatePicker!
@IBOutlet private var console: UITextView!
@IBOutlet private var rightBarButtonItem: UIBarButtonItem!

@IBOutlet private var tabBar: UITabBar!

private var subscriptions = Set<AnyCancellable>()

override func viewDidLoad() {
@@ -50,6 +51,7 @@ class ControlsViewController: UIViewController {
.merge(with: leftSwipe.swipePublisher.map { "Swiped Left with Gesture \($0.memoryAddress)" },
longPress.longPressPublisher.map { "Long Pressed with Gesture \($0.memoryAddress)" },
doubleTap.tapPublisher.map { "Double-tapped view with two fingers with Gesture \($0.memoryAddress)" },
tabBar.didSelectPublisher.map { "tabBar selected title is \($0.title ?? "") and badge is \($0.badgeValue ?? "")"},
console.reachedBottomPublisher().map { _ in "Reached the bottom of the UITextView" })
.scan("") { $0 + "\n" + $1 }
.handleEvents(receiveOutput: { [console] text in
47 changes: 38 additions & 9 deletions Example/Example/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14854.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="4Ib-BL-pNq">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="4Ib-BL-pNq">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14806.4"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -53,7 +55,7 @@
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="P4e-Ie-0W8">
<rect key="frame" x="0.0" y="119" width="382" height="31"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="utR-GO-fQs" userLabel="Tap this button">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="utR-GO-fQs" userLabel="Tap this button">
<rect key="frame" x="0.0" y="0.0" width="325" height="31"/>
<state key="normal" title="Tap this button"/>
</button>
@@ -68,24 +70,39 @@
</subviews>
</stackView>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text="Events:" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="CVe-Hd-do1" userLabel="Debug Text View">
<rect key="frame" x="16" y="514" width="382" height="348"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="textColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
<rect key="frame" x="16" y="514" width="382" height="288"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="textColor" systemColor="labelColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<tabBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="k0l-ab-jMZ">
<rect key="frame" x="0.0" y="812" width="414" height="50"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="uzX-ud-E4R"/>
</constraints>
<items>
<tabBarItem title="first tab" image="1.circle" catalog="system" badgeValue="1" id="NqF-BG-elX"/>
<tabBarItem title="second tab" image="2.circle" catalog="system" badgeValue="2" id="Dwd-8P-Jhm"/>
<tabBarItem title="third tab" image="3.circle" catalog="system" badgeValue="3" id="jZo-uA-PmX"/>
</items>
</tabBar>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="PSG-wD-zhs"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="k0l-ab-jMZ" firstAttribute="top" secondItem="CVe-Hd-do1" secondAttribute="bottom" constant="10" id="382-hP-BZc"/>
<constraint firstItem="PSG-wD-zhs" firstAttribute="trailing" secondItem="7by-4H-6wI" secondAttribute="trailing" constant="16" id="63g-lD-KyA"/>
<constraint firstItem="7by-4H-6wI" firstAttribute="top" secondItem="PSG-wD-zhs" secondAttribute="top" id="FQB-eU-nn2"/>
<constraint firstItem="CVe-Hd-do1" firstAttribute="bottom" secondItem="PSG-wD-zhs" secondAttribute="bottom" id="Gib-yb-1r0"/>
<constraint firstItem="7by-4H-6wI" firstAttribute="leading" secondItem="PSG-wD-zhs" secondAttribute="leading" constant="16" id="ITW-9U-GzR"/>
<constraint firstItem="CVe-Hd-do1" firstAttribute="trailing" secondItem="tm0-m6-nJj" secondAttribute="trailing" id="QfS-va-pHA"/>
<constraint firstItem="k0l-ab-jMZ" firstAttribute="leading" secondItem="PSG-wD-zhs" secondAttribute="leading" id="bcD-CH-ZCE"/>
<constraint firstItem="CVe-Hd-do1" firstAttribute="leading" secondItem="tm0-m6-nJj" secondAttribute="leading" id="iOA-eM-f8x"/>
<constraint firstAttribute="trailing" secondItem="k0l-ab-jMZ" secondAttribute="trailing" id="lab-i5-lIe"/>
<constraint firstItem="CVe-Hd-do1" firstAttribute="top" secondItem="7by-4H-6wI" secondAttribute="bottom" id="tTk-F5-1v3"/>
<constraint firstItem="k0l-ab-jMZ" firstAttribute="bottom" secondItem="PSG-wD-zhs" secondAttribute="bottom" id="vZX-sa-7c8"/>
</constraints>
<viewLayoutGuide key="safeArea" id="PSG-wD-zhs"/>
</view>
<navigationItem key="navigationItem" title="CombineCocoa" largeTitleDisplayMode="always" id="Gpl-hh-ZcW">
<barButtonItem key="rightBarButtonItem" title="Tap Me!" id="bua-r4-BCr"/>
@@ -98,6 +115,7 @@
<outlet property="segmented" destination="Fjj-bk-JKz" id="Tv8-hI-TDa"/>
<outlet property="slider" destination="Cbi-R7-6Un" id="0ch-Ae-cSx"/>
<outlet property="switch" destination="C3j-RG-2yZ" id="d7g-oY-SUh"/>
<outlet property="tabBar" destination="k0l-ab-jMZ" id="ARX-w8-w4U"/>
<outlet property="textField" destination="A4E-5S-bfr" id="KlI-N5-d6X"/>
</connections>
</viewController>
@@ -106,4 +124,15 @@
<point key="canvasLocation" x="192.75362318840581" y="-4.0178571428571423"/>
</scene>
</scenes>
<resources>
<image name="1.circle" catalog="system" width="128" height="121"/>
<image name="2.circle" catalog="system" width="128" height="121"/>
<image name="3.circle" catalog="system" width="128" height="121"/>
<systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
40 changes: 40 additions & 0 deletions Example/ExampleTests/UITabBarTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// UITabBarTests.swift
// ExampleTests
//
// Created by TaeHyeongKim on 2021/10/22.
// Copyright © 2021 Shai Mishali. All rights reserved.
//

import XCTest
import Combine
@testable import CombineCocoa

class UITabBarTests: XCTestCase {
var subscriptions = Set<AnyCancellable>()

override func tearDown() {
subscriptions = .init()
}

func test_didSelect() {
let tab1 = UITabBarItem(title: "testTab_1", image: nil, tag: 0)
let tab2 = UITabBarItem(title: "testTab_2", image: nil, tag: 1)
let tab3 = UITabBarItem(title: "testTab_3", image: nil, tag: 2)
let tabBar = UITabBar()
tabBar.items = [tab1, tab2, tab3]

var resultTabBarItem: UITabBarItem? = nil

tabBar.didSelectPublisher
.sink { resultTabBarItem = $0 }
.store(in: &subscriptions)

let givenTabBarItem = tab2
tabBar.delegate?.tabBar?(tabBar, didSelect: tab2)

XCTAssertEqual(resultTabBarItem, givenTabBarItem)
}


}
36 changes: 36 additions & 0 deletions Sources/CombineCocoa/Controls/UITabBar+Combine.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// UITabBar+Combine.swift
// CombineCocoa
//
// Created by TaeHyeongKim on 2021/10/21.
//


#if !(os(iOS) && (arch(i386) || arch(arm)))
import Combine
import UIKit

@available(iOS 13.0, *)
public extension UITabBar {

/// Combine wrapper for `tabBar(_:didSelect:)`
var didSelectPublisher: AnyPublisher<UITabBarItem, Never> {
let selector = #selector(UITabBarDelegate.tabBar(_:didSelect:))
return delegateProxy.interceptSelectorPublisher(selector)
.map { $0[1] as! UITabBarItem }
.eraseToAnyPublisher()
}

private var delegateProxy: UITabBarProxy {
.createDelegateProxy(for: self)
}

}

@available(iOS 13.0, *)
private class UITabBarProxy: DelegateProxy, UITabBarDelegate, DelegateProxyType {
func setDelegate(to object: UITabBar) {
object.delegate = self
}
}
#endif