Skip to content

Commit

Permalink
Merge pull request #34 from kmcgill88/22-showAsInputView
Browse files Browse the repository at this point in the history
22 show as input view
  • Loading branch information
kmcgill88 authored Mar 10, 2018
2 parents dc7705e + ade6f74 commit c77df78
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 46 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ type_body_length:
- 400 # error
disabled_rules: # rule identifiers to exclude from running
- superfluous_disable_command
- identifier_name
26 changes: 18 additions & 8 deletions Example/McPicker/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="zqw-fC-zaf">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="zqw-fC-zaf">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
Expand All @@ -15,7 +15,7 @@
<objects>
<navigationController id="zqw-fC-zaf" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="UPB-N4-5gx">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
Expand Down Expand Up @@ -46,7 +46,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="a2x-VG-7p3">
<rect key="frame" x="142" y="122" width="90" height="30"/>
<rect key="frame" x="143" y="122" width="90" height="30"/>
<state key="normal" title="Styled Picker"/>
<connections>
<action selector="styledPicker:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="OSN-tI-qZs"/>
Expand All @@ -59,20 +59,29 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="q1a-o6-gzD">
<rect key="frame" x="132" y="172" width="110" height="30"/>
<rect key="frame" x="133" y="172" width="110" height="30"/>
<state key="normal" title="Pop Over Picker"/>
<connections>
<action selector="popOverPicker:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="jtM-7c-1mV"/>
</connections>
</button>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="r6o-nf-hyx" customClass="McTextField" customModule="McPicker">
<rect key="frame" x="50" y="217" width="275" height="30"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="q1a-o6-gzD" firstAttribute="centerX" secondItem="a2x-VG-7p3" secondAttribute="centerX" id="0Tr-Z2-Clx"/>
<constraint firstItem="a2x-VG-7p3" firstAttribute="centerX" secondItem="fEx-GG-5Tp" secondAttribute="centerX" id="30V-vZ-BE4"/>
<constraint firstItem="fEx-GG-5Tp" firstAttribute="top" secondItem="q1a-o6-gzD" secondAttribute="bottom" constant="113" id="FaB-P5-Me3"/>
<constraint firstItem="a2x-VG-7p3" firstAttribute="centerX" secondItem="HnM-Jf-fV9" secondAttribute="centerX" id="HkO-ip-bbF"/>
<constraint firstItem="q1a-o6-gzD" firstAttribute="top" secondItem="a2x-VG-7p3" secondAttribute="bottom" constant="20" id="Nau-eR-b9e"/>
<constraint firstItem="HnM-Jf-fV9" firstAttribute="top" secondItem="jyV-Pf-zRb" secondAttribute="bottom" constant="8" id="RVe-GO-8tZ"/>
<constraint firstItem="q1a-o6-gzD" firstAttribute="centerX" secondItem="a2x-VG-7p3" secondAttribute="centerX" id="UaX-P3-71u"/>
<constraint firstItem="r6o-nf-hyx" firstAttribute="top" secondItem="q1a-o6-gzD" secondAttribute="bottom" constant="15" id="Wyk-uA-cz3"/>
<constraint firstAttribute="trailing" secondItem="r6o-nf-hyx" secondAttribute="trailing" constant="50" id="asj-tJ-RId"/>
<constraint firstItem="r6o-nf-hyx" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading" constant="50" id="bp0-nE-uGj"/>
<constraint firstItem="HnM-Jf-fV9" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="eAp-Rl-KQd"/>
<constraint firstItem="a2x-VG-7p3" firstAttribute="top" secondItem="HnM-Jf-fV9" secondAttribute="bottom" constant="20" id="gBw-qX-R5x"/>
<constraint firstAttribute="trailingMargin" secondItem="fEx-GG-5Tp" secondAttribute="trailing" id="i5v-oE-4aj"/>
Expand All @@ -93,11 +102,12 @@
</navigationItem>
<connections>
<outlet property="label" destination="fEx-GG-5Tp" id="alK-q4-pWv"/>
<outlet property="textField" destination="r6o-nf-hyx" id="rqF-zy-X7O"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="156" y="276"/>
<point key="canvasLocation" x="52" y="240"/>
</scene>
</scenes>
</document>
43 changes: 34 additions & 9 deletions Example/McPicker/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,34 @@ import McPicker

class ViewController: UIViewController {

@IBOutlet weak var textField: McTextField!
@IBOutlet weak var label: UILabel!
let data: [[String]] = [
["Kevin", "Lauren", "Kibby", "Stella"]
]

override func viewDidLoad() {
let mcInputView = McPicker(data: data)
mcInputView.backgroundColor = .gray
mcInputView.backgroundColorAlpha = 0.25
textField.inputViewMcPicker = mcInputView
textField.doneHandler = { [weak textField] (selections) in
textField?.text = selections[0]!
}
textField.selectionChangedHandler = { [weak textField] (selections, componentThatChanged) in
textField?.text = selections[componentThatChanged]!
}
textField.cancelHandler = { [weak textField] in
textField?.text = "Cancelled."
}
textField.textFieldWillBeginEditingHandler = { [weak textField] (selections) in
if textField?.text == "" {
// Selections always default to the first value per component
textField?.text = selections[0]
}
}
}

@IBAction func showPressed(_ sender: Any) {
/*
McPicker.show(data: data) { [weak self] (selections:[Int: String]) in
Expand Down Expand Up @@ -61,30 +84,32 @@ class ViewController: UIViewController {
}

@IBAction func styledPicker(_ sender: Any) {
let data: [[String]] = [
["Sir", "Mr", "Mrs", "Miss"],
["Kevin", "Lauren", "Kibby", "Stella"]
]
let mcPicker = McPicker(data: data)

let customLabel = UILabel()
customLabel.textAlignment = .center
customLabel.textColor = .white
customLabel.font = UIFont(name:"American Typewriter", size: 30)!
mcPicker.label = customLabel // Set your custom label

let data: [[String]] = [
["Sir", "Mr", "Mrs", "Miss"],
["Kevin", "Lauren", "Kibby", "Stella"]
]

let mcPicker = McPicker(data: data)
let fixedSpace = McPickerBarButtonItem.fixedSpace(width: 20.0)
let flexibleSpace = McPickerBarButtonItem.flexibleSpace()
let fireButton = McPickerBarButtonItem.done(mcPicker: mcPicker, title: "Fire!!!") // Set custom Text
let cancelButton = McPickerBarButtonItem.cancel(mcPicker: mcPicker, barButtonSystemItem: .cancel) // or system items
mcPicker.setToolbarItems(items: [fixedSpace, cancelButton, flexibleSpace, fireButton, fixedSpace])

mcPicker.label = customLabel // Set your custom label
mcPicker.toolbarItemsFont = UIFont(name:"American Typewriter", size: 17)!

mcPicker.toolbarButtonsColor = .white
mcPicker.toolbarBarTintColor = .darkGray
mcPicker.pickerBackgroundColor = .gray
mcPicker.backgroundColor = .gray
mcPicker.backgroundColorAlpha = 0.50

mcPicker.pickerSelectRowsForComponents = [
0: [3: true],
1: [2: true]
Expand All @@ -109,8 +134,8 @@ class ViewController: UIViewController {
}
*/
mcPicker.show(doneHandler: { [weak self] (selections: [Int : String]) -> Void in
if let name = selections[0] {
self?.label.text = name
if let prefix = selections[0], let name = selections[1] {
self?.label.text = "\(prefix) \(name)"
}
}, cancelHandler: {
print("Canceled Styled Picker")
Expand Down
3 changes: 2 additions & 1 deletion Example/Tests/McPickerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class McPickerTests: XCTestCase {
XCTAssertEqual(doneBarButton.target as! TestMcPicker, mcPicker)
XCTAssertEqual(doneBarButton.action!, #selector(TestMcPicker.done))

XCTAssertEqual(mcPicker.backgroundColor, UIColor.black.withAlphaComponent(0.75))
XCTAssertNil(mcPicker.backgroundColor)
XCTAssertEqual(mcPicker._backgroundColorAlpha, McPicker.Constant.backgroundColorAlpha)
XCTAssertEqual(mcPicker.backgroundView.backgroundColor, UIColor.white)

XCTAssertEqual(mcPicker, mcPicker.picker.delegate as! McPicker)
Expand Down
4 changes: 2 additions & 2 deletions McPicker.podspec
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Pod::Spec.new do |s|
s.name = 'McPicker'
s.version = '0.5.2'
s.version = '1.0.0'
s.summary = 'McPicker is a customizable, closure driven UIPickerView drop-in solution with animations that is rotation ready.'

s.description = <<-DESC
McPicker is a UIPickerView drop-in solution with animations that is rotation ready. The more string arrays you pass, the more picker components you'll get. You can set custom label or use the defaults. McPicker can be presented as a Popover on iPhone or iPad using showAsPopover or use the default slide up and down style, show.
McPicker is a UIPickerView drop-in solution with animations that is rotation ready. The more string arrays you pass, the more picker components you'll get. You can set custom label or use the defaults. McPicker can be presented as a Popover on iPhone or iPad using showAsPopover, as an inputView using McTextField or use the default slide up and down style show.
showAsPopover can be used to display from a UIView or UIBarButtonItem. showAsPopover will always be presented as a Popover, even when used on an iPhone.
DESC
Expand Down
43 changes: 29 additions & 14 deletions McPicker/Classes/McPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import UIKit
open class McPicker: UIView {

open var fontSize: CGFloat = 25.0
open var backgroundColorAlpha: CGFloat?

/**
The custom label to use with the picker.
Expand Down Expand Up @@ -102,6 +103,9 @@ open class McPicker: UIView {
internal var popOverContentSize: CGSize {
return CGSize(width: Constant.pickerHeight + Constant.toolBarHeight, height: Constant.pickerHeight + Constant.toolBarHeight)
}
internal var _backgroundColorAlpha: CGFloat {
return self.backgroundColorAlpha ?? Constant.backgroundColorAlpha
}
internal var pickerSelection: [Int:String] = [:]
internal var pickerData: [[String]] = []
internal var numberOfComponents: Int {
Expand All @@ -115,6 +119,13 @@ open class McPicker: UIView {
internal enum AnimationDirection {
case `in`, out // swiftlint:disable:this identifier_name
}
internal enum Constant {
static let backgroundColorAlpha: CGFloat = 0.75
static let pickerHeight: CGFloat = 216.0
static let toolBarHeight: CGFloat = 44.0
static let animationSpeed: TimeInterval = 0.25
static let barButtonFixedSpacePadding: CGFloat = 0.02
}

fileprivate var doneHandler: DoneHandler = {_ in }
fileprivate var cancelHandler: CancelHandler?
Expand All @@ -128,14 +139,6 @@ open class McPicker: UIView {
return window
}

private enum Constant {
static let pickerHeight: CGFloat = 216.0
static let toolBarHeight: CGFloat = 44.0
static let backgroundAlpha: CGFloat = 0.75
static let animationSpeed: TimeInterval = 0.25
static let barButtonFixedSpacePadding: CGFloat = 0.02
}

convenience public init(data: [[String]]) {
self.init(frame: CGRect.zero)
self.pickerData = data
Expand Down Expand Up @@ -300,11 +303,12 @@ open class McPicker: UIView {

internal func animateViews(direction: AnimationDirection) {
var backgroundFrame = backgroundView.frame
let animateColor = self.backgroundColor ?? .black

if direction == .in {
// Start transparent
//
self.backgroundColor = UIColor.black.withAlphaComponent(0)
self.backgroundColor = animateColor.withAlphaComponent(0)

// Start picker off the bottom of the screen
//
Expand All @@ -319,15 +323,15 @@ open class McPicker: UIView {
// Animate things on screen
//
UIView.animate(withDuration: Constant.animationSpeed, animations: {
self.backgroundColor = UIColor.black.withAlphaComponent(Constant.backgroundAlpha)
self.backgroundColor = animateColor.withAlphaComponent(self._backgroundColorAlpha)
backgroundFrame.origin.y = self.appWindow.bounds.size.height - self.backgroundView.bounds.height
self.backgroundView.frame = backgroundFrame
})
} else {
// Animate things off screen
//
UIView.animate(withDuration: Constant.animationSpeed, animations: {
self.backgroundColor = UIColor.black.withAlphaComponent(0)
self.backgroundColor = animateColor.withAlphaComponent(0)
backgroundFrame.origin.y = self.appWindow.bounds.size.height
self.backgroundView.frame = backgroundFrame
}, completion: { _ in
Expand Down Expand Up @@ -355,7 +359,7 @@ open class McPicker: UIView {
setToolbarItems(items: [fixedSpace, McPickerBarButtonItem.cancel(mcPicker: self),
McPickerBarButtonItem.flexibleSpace(), McPickerBarButtonItem.done(mcPicker: self), fixedSpace])

self.backgroundColor = UIColor.black.withAlphaComponent(Constant.backgroundAlpha)
// self.backgroundColor = UIColor.black.withAlphaComponent(Constant.backgroundAlpha)
backgroundView.backgroundColor = UIColor.white

picker.delegate = self
Expand Down Expand Up @@ -442,7 +446,6 @@ extension McPicker : UIPickerViewDelegate {
}

extension McPicker : UIPopoverPresentationControllerDelegate {

public func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
self.cancelHandler?()
}
Expand All @@ -459,11 +462,23 @@ extension McPicker : UIPopoverPresentationControllerDelegate {
}

extension McPicker : UIGestureRecognizerDelegate {

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if let goodView = touch.view {
return goodView == self
}
return false
}
}

extension McPicker : UITextFieldDelegate {
public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if let mcTextField = textField as? McTextField {
mcTextField.textFieldWillBeginEditingHandler?(self.pickerSelection)
self.show(doneHandler: mcTextField.doneHandler,
cancelHandler: mcTextField.cancelHandler,
selectionChangedHandler: mcTextField.selectionChangedHandler)
return false
}
return true
}
}
35 changes: 35 additions & 0 deletions McPicker/Classes/McTextField.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright (c) 2018 Kevin McGill <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

open class McTextField: UITextField {

public var doneHandler: McPicker.DoneHandler = { _ in }
public var cancelHandler: McPicker.CancelHandler?
public var selectionChangedHandler: McPicker.SelectionChangedHandler?
public var textFieldWillBeginEditingHandler: ((_ selections: [Int:String]) -> Void)?

public var inputViewMcPicker: McPicker? {
didSet {
self.delegate = inputViewMcPicker
}
}
}
Loading

0 comments on commit c77df78

Please sign in to comment.