Skip to content

Commit

Permalink
add tap gesture recognizer to sections (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
mac-gallagher authored Nov 28, 2019
1 parent e8b383b commit c4d9207
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 124 deletions.
13 changes: 8 additions & 5 deletions Example/LanguageExample/LanguageExample.storyboard
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15510"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
Expand Down Expand Up @@ -46,6 +44,7 @@
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="0wb-Cb-WUL" id="uad-jp-Zwy"/>
<outlet property="delegate" destination="0wb-Cb-WUL" id="SS4-fz-to2"/>
</connections>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Aqx-CJ-eFd" customClass="LanguageExampleProgressView" customModule="MultiProgressViewExample" customModuleProvider="target">
Expand Down Expand Up @@ -73,6 +72,7 @@
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="0wb-Cb-WUL" id="oxv-8k-Fp4"/>
<outlet property="delegate" destination="0wb-Cb-WUL" id="gMg-bN-CTQ"/>
</connections>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CWo-Hk-zOo" customClass="LanguageExampleProgressView" customModule="MultiProgressViewExample" customModuleProvider="target">
Expand Down Expand Up @@ -100,6 +100,7 @@
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="0wb-Cb-WUL" id="Fk9-lG-EyR"/>
<outlet property="delegate" destination="0wb-Cb-WUL" id="WJC-E7-xgA"/>
</connections>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="yei-zF-C21" customClass="LanguageExampleProgressView" customModule="MultiProgressViewExample" customModuleProvider="target">
Expand Down Expand Up @@ -127,6 +128,7 @@
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="0wb-Cb-WUL" id="mmq-QZ-Qva"/>
<outlet property="delegate" destination="0wb-Cb-WUL" id="MHC-iU-0sI"/>
</connections>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TJ5-4x-gVc" customClass="LanguageExampleProgressView" customModule="MultiProgressViewExample" customModuleProvider="target">
Expand Down Expand Up @@ -154,6 +156,7 @@
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="0wb-Cb-WUL" id="tIM-3R-UK6"/>
<outlet property="delegate" destination="0wb-Cb-WUL" id="5kH-zF-2Nw"/>
</connections>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Languages" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s77-Sh-QnM">
Expand Down
16 changes: 15 additions & 1 deletion Example/LanguageExample/LanguageExampleViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class LanguageExampleViewController: UIViewController {
}
}

//MARK: - Data Source
//MARK: - MultiProgressViewDataSource

extension LanguageExampleViewController: MultiProgressViewDataSource {
func numberOfSections(in progressView: MultiProgressView) -> Int {
Expand All @@ -98,3 +98,17 @@ extension LanguageExampleViewController: MultiProgressViewDataSource {
return sectionView
}
}

// MARK: - MultiProgressViewDelegate

extension LanguageExampleViewController: MultiProgressViewDelegate {

func progressView(_ progressView: MultiProgressView, didTapSectionAt index: Int) {
for (progressViewIndex, view) in progressViews.enumerated() {
if view === progressView {
print("Tapped progressView \(progressViewIndex) at section \(index)")
break
}
}
}
}
12 changes: 11 additions & 1 deletion Example/StorageExample/StorageExampleViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class StorageExampleViewController: UIViewController {
paddingRight: padding,
height: progressViewHeight)
progressView.dataSource = self
progressView.delegate = self
}

private func setupStackView() {
Expand Down Expand Up @@ -190,7 +191,7 @@ class StorageExampleViewController: UIViewController {
}
}

//MARK: - Data Source
//MARK: - MultiProgressViewDataSource

extension StorageExampleViewController: MultiProgressViewDataSource {
public func numberOfSections(in progressBar: MultiProgressView) -> Int {
Expand All @@ -203,3 +204,12 @@ extension StorageExampleViewController: MultiProgressViewDataSource {
return bar
}
}

// MARK: - MultiProgressViewDelegate

extension StorageExampleViewController: MultiProgressViewDelegate {

func progressView(_ progressView: MultiProgressView, didTapSectionAt index: Int) {
print("Tapped section \(index)")
}
}
12 changes: 12 additions & 0 deletions MultiProgressView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
/* Begin PBXBuildFile section */
0F33B13D1BCF84BE40120FC5 /* Pods_MultiProgressViewTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E594A8658F530A5575039A4 /* Pods_MultiProgressViewTests.framework */; };
AD0BF7FC2273C0DE0081722E /* CodingLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD0BF7FB2273C0DE0081722E /* CodingLanguage.swift */; };
AD20667B238F5DAE00CAA61D /* MockProgressViewSectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD20667A238F5DAE00CAA61D /* MockProgressViewSectionDelegate.swift */; };
AD20667D238F5EEB00CAA61D /* TestableTapGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD20667C238F5EEB00CAA61D /* TestableTapGestureRecognizer.swift */; };
AD20667F238F8CC200CAA61D /* MockProgressViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD20667E238F8CC200CAA61D /* MockProgressViewDelegate.swift */; };
AD3B3270225146B9006E0F14 /* MultiProgressView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD501273224B0E1600370157 /* MultiProgressView.framework */; };
AD3B329B22514B4E006E0F14 /* MockLayoutProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD3B329122514B4E006E0F14 /* MockLayoutProvider.swift */; };
AD3B329C22514B4E006E0F14 /* MockMultiProgressViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD3B329222514B4E006E0F14 /* MockMultiProgressViewDataSource.swift */; };
Expand Down Expand Up @@ -75,6 +78,9 @@
4E594A8658F530A5575039A4 /* Pods_MultiProgressViewTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MultiProgressViewTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7D3DCEE1FF2C5A9C79322BC2 /* Pods-MultiProgressViewTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MultiProgressViewTests.release.xcconfig"; path = "Target Support Files/Pods-MultiProgressViewTests/Pods-MultiProgressViewTests.release.xcconfig"; sourceTree = "<group>"; };
AD0BF7FB2273C0DE0081722E /* CodingLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodingLanguage.swift; sourceTree = "<group>"; };
AD20667A238F5DAE00CAA61D /* MockProgressViewSectionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockProgressViewSectionDelegate.swift; sourceTree = "<group>"; };
AD20667C238F5EEB00CAA61D /* TestableTapGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableTapGestureRecognizer.swift; sourceTree = "<group>"; };
AD20667E238F8CC200CAA61D /* MockProgressViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockProgressViewDelegate.swift; sourceTree = "<group>"; };
AD3B326B225146B9006E0F14 /* MultiProgressViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MultiProgressViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
AD3B32882251488A006E0F14 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/iOS/Nimble.framework; sourceTree = "<group>"; };
AD3B32892251488A006E0F14 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/iOS/Quick.framework; sourceTree = "<group>"; };
Expand Down Expand Up @@ -168,6 +174,8 @@
children = (
AD3B329122514B4E006E0F14 /* MockLayoutProvider.swift */,
AD3B329222514B4E006E0F14 /* MockMultiProgressViewDataSource.swift */,
AD20667E238F8CC200CAA61D /* MockProgressViewDelegate.swift */,
AD20667A238F5DAE00CAA61D /* MockProgressViewSectionDelegate.swift */,
);
path = Mocks;
sourceTree = "<group>";
Expand All @@ -187,6 +195,7 @@
children = (
AD3B329922514B4E006E0F14 /* TestableProgressViewSection.swift */,
AD3B329A22514B4E006E0F14 /* TestableMultiProgressView.swift */,
AD20667C238F5EEB00CAA61D /* TestableTapGestureRecognizer.swift */,
);
path = Testables;
sourceTree = "<group>";
Expand Down Expand Up @@ -529,10 +538,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AD20667F238F8CC200CAA61D /* MockProgressViewDelegate.swift in Sources */,
AD3B329E22514B4E006E0F14 /* ProgressViewSectionSpec.swift in Sources */,
AD3B329C22514B4E006E0F14 /* MockMultiProgressViewDataSource.swift in Sources */,
AD20667B238F5DAE00CAA61D /* MockProgressViewSectionDelegate.swift in Sources */,
AD3B329D22514B4E006E0F14 /* MultiProgressViewSpec.swift in Sources */,
AD3B329B22514B4E006E0F14 /* MockLayoutProvider.swift in Sources */,
AD20667D238F5EEB00CAA61D /* TestableTapGestureRecognizer.swift in Sources */,
AD3B329F22514B4E006E0F14 /* LayoutProviderSpec.swift in Sources */,
AD3B32A222514B4E006E0F14 /* TestableMultiProgressView.swift in Sources */,
AD3B32A122514B4E006E0F14 /* TestableProgressViewSection.swift in Sources */,
Expand Down
8 changes: 0 additions & 8 deletions Sources/MultiProgressView/AlignmentType.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//
// AlignmentType.swift
// MultiProgressView
//
// Created by Mac Gallagher on 6/19/18.
// Copyright © 2018 Mac Gallagher. All rights reserved.
//

public enum AlignmentType {
case left
case topLeft
Expand Down
12 changes: 2 additions & 10 deletions Sources/MultiProgressView/LayoutProvider.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//
// LayoutProvider.swift
// MultiProgressView
//
// Created by Mac Gallagher on 3/5/19.
// Copyright © 2019 Mac Gallagher. All rights reserved.
//

import UIKit

protocol LayoutProvidable {
Expand Down Expand Up @@ -81,9 +73,9 @@ struct LayoutProvider: LayoutProvidable {
let size = CGSize(width: width, height: trackBounds.height)

var origin: CGPoint = trackBounds.origin
for index in 0..<progressView.progressViewSections.count {
for (bar, index) in progressView.progressViewSections {
if index < section {
origin.x += progressView.progressViewSections[index].frame.width
origin.x += bar.frame.width
}
}

Expand Down
8 changes: 0 additions & 8 deletions Sources/MultiProgressView/LineCapType.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//
// LineCapType.swift
// MultiProgressView
//
// Created by Mac Gallagher on 12/25/18.
// Copyright © 2018 Mac Gallagher. All rights reserved.
//

public enum LineCapType {
case round
case butt
Expand Down
36 changes: 24 additions & 12 deletions Sources/MultiProgressView/MultiProgressView.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//
// MultiProgressView.swift
// MultiProgressView
//
// Created by Mac Gallagher on 6/15/18.
// Copyright © 2018 Mac Gallagher. All rights reserved.
//

import UIKit

@objc public protocol MultiProgressViewDataSource: class {
Expand All @@ -14,6 +6,10 @@ import UIKit
viewForSection section: Int) -> ProgressViewSection
}

@objc public protocol MultiProgressViewDelegate: class {
@objc optional func progressView(_ progressView: MultiProgressView, didTapSectionAt index: Int)
}

@IBDesignable
open class MultiProgressView: UIView {

Expand All @@ -23,6 +19,8 @@ open class MultiProgressView: UIView {
}
}

@IBOutlet public weak var delegate: MultiProgressViewDelegate?

@IBInspectable public var cornerRadius: CGFloat = 0 {
didSet {
updateCornerRadius()
Expand Down Expand Up @@ -107,7 +105,9 @@ open class MultiProgressView: UIView {
return view
}()

var progressViewSections: [ProgressViewSection] = []
/// A map containing the sections of the progress view.
/// The key is the section and the value is the section's index in the progress view.
var progressViewSections: [ProgressViewSection: Int] = [:]

private var numberOfSections: Int = 0
private var currentProgress: [Float] = []
Expand Down Expand Up @@ -158,7 +158,7 @@ open class MultiProgressView: UIView {
}

private func layoutSections() {
for (index, section) in progressViewSections.enumerated() {
for (section, index) in progressViewSections {
section.frame = layoutProvider.sectionFrame(self, index)
track.bringSubviewToFront(section)
}
Expand All @@ -175,7 +175,7 @@ open class MultiProgressView: UIView {
guard let dataSource = dataSource else { return }
numberOfSections = dataSource.numberOfSections(in: self)

progressViewSections.forEach { $0.removeFromSuperview() }
progressViewSections.keys.forEach { $0.removeFromSuperview() }
progressViewSections.removeAll()
currentProgress.removeAll()

Expand All @@ -187,7 +187,8 @@ open class MultiProgressView: UIView {
private func configureSection(withDataSource dataSource: MultiProgressViewDataSource,
_ section: Int) {
let bar = dataSource.progressView(self, viewForSection: section)
progressViewSections.insert(bar, at: section)
bar.delegate = self
progressViewSections[bar] = section
track.addSubview(bar)
currentProgress.insert(0, at: section)
}
Expand Down Expand Up @@ -224,3 +225,14 @@ open class MultiProgressView: UIView {
}
}
}

// MARK: - ProgressViewSectionDelegate

extension MultiProgressView: ProgressViewSectionDelegate {

func didTapSection(_ section: ProgressViewSection) {
if let index = progressViewSections[section] {
delegate?.progressView?(self, didTapSectionAt: index)
}
}
}
28 changes: 20 additions & 8 deletions Sources/MultiProgressView/ProgressViewSection.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
//
// ProgressViewSection.swift
// MultiProgressView
//
// Created by Mac Gallagher on 6/15/18.
// Copyright © 2018 Mac Gallagher. All rights reserved.
//

import UIKit

protocol ProgressViewSectionDelegate: class {
func didTapSection(_ section: ProgressViewSection)
}

open class ProgressViewSection: UIView {

public var titleLabel: UILabel {
Expand All @@ -32,6 +28,15 @@ open class ProgressViewSection: UIView {
return sectionImageView
}

var tapGestureRecognizer: UITapGestureRecognizer {
return tapRecognizer
}

private lazy var tapRecognizer = UITapGestureRecognizer(target: self,
action: #selector(didTap))

weak var delegate: ProgressViewSectionDelegate?

private var sectionImageView: UIImageView = UIImageView()

private var layoutProvider: LayoutProvidable.Type = LayoutProvider.self
Expand All @@ -58,6 +63,13 @@ open class ProgressViewSection: UIView {
layer.masksToBounds = true
addSubview(sectionImageView)
addSubview(sectionTitleLabel)
addGestureRecognizer(tapGestureRecognizer)
}

// MARK: - Tap handler

@objc func didTap() {
delegate?.didTapSection(self)
}

// MARK: - Layout
Expand Down
8 changes: 0 additions & 8 deletions Tests/MultiProgressViewTests/Mocks/MockLayoutProvider.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//
// MockLayoutProvider.swift
// MultiProgressViewTests
//
// Created by Mac Gallagher on 3/6/19.
// Copyright © 2019 Mac Gallagher. All rights reserved.
//

@testable import MultiProgressView

struct MockLayoutProvider: LayoutProvidable {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//
// MockMultiProgressViewDataSource.swift
// MultiProgressViewTests
//
// Created by Mac Gallagher on 3/1/19.
// Copyright © 2019 Mac Gallagher. All rights reserved.
//

import MultiProgressView

class MockMultiProgressViewDataSource: MultiProgressViewDataSource {
Expand Down
12 changes: 12 additions & 0 deletions Tests/MultiProgressViewTests/Mocks/MockProgressViewDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@testable import MultiProgressView

class MockMultiProgressViewDelegate: MultiProgressViewDelegate {

var didTapSectionAtCalled: Bool = false
var didTapSectionIndex: Int?

func progressView(_ progressView: MultiProgressView, didTapSectionAt index: Int) {
didTapSectionAtCalled = true
didTapSectionIndex = index
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@testable import MultiProgressView

class MockProgressViewSectionDelegate: ProgressViewSectionDelegate {

var didTapSectionCalled: Bool = false
func didTapSection(_ section: ProgressViewSection) {
didTapSectionCalled = true
}
}
Loading

0 comments on commit c4d9207

Please sign in to comment.