Skip to content

Commit

Permalink
Review extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
wordlessj committed Jul 24, 2017
1 parent 333468d commit 1e72b61
Show file tree
Hide file tree
Showing 17 changed files with 413 additions and 459 deletions.
32 changes: 8 additions & 24 deletions Panda.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -156,19 +156,15 @@
3B4081111F20810600F810BE /* CATiledLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B4080EF1F2080F000F810BE /* CATiledLayer.swift */; };
3B4081121F20810600F810BE /* CATransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B4080EC1F2080F000F810BE /* CATransition.swift */; };
3B4081151F22E8FB00F810BE /* SetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B4081141F22E8FB00F810BE /* SetHelper.swift */; };
3B89336E1F25D8480037F115 /* Sub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B89336D1F25D8480037F115 /* Sub.swift */; };
3BB2EE8F1DC99F0E001D7AAB /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE8E1DC99F0E001D7AAB /* UICollectionViewExtensions.swift */; };
3BB2EE911DC9B65B001D7AAB /* UICollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE901DC9B65B001D7AAB /* UICollectionViewFlowLayout.swift */; };
3BB2EE931DC9BF09001D7AAB /* UIStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE921DC9BF09001D7AAB /* UIStackView.swift */; };
3BB2EE951DC9BF46001D7AAB /* UIStackViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE941DC9BF46001D7AAB /* UIStackViewExtensions.swift */; };
3BB2EE991DC9C2B1001D7AAB /* CGGeometryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE981DC9C2B1001D7AAB /* CGGeometryExtensions.swift */; };
3BB2EE9B1DC9C3E2001D7AAB /* CGAffineTransformExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE9A1DC9C3E2001D7AAB /* CGAffineTransformExtensions.swift */; };
3BB2EE9D1DC9C5DE001D7AAB /* CGContextExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE9C1DC9C5DE001D7AAB /* CGContextExtensions.swift */; };
3BB2EE9F1DC9C6B1001D7AAB /* UIEdgeInsetsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EE9E1DC9C6B1001D7AAB /* UIEdgeInsetsExtensions.swift */; };
3BB2EEA11DC9CE7E001D7AAB /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EEA01DC9CE7E001D7AAB /* UIViewControllerExtensions.swift */; };
3BB2EEAB1DC9E891001D7AAB /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EEAA1DC9E891001D7AAB /* Font.swift */; };
3BB2EEAD1DC9E967001D7AAB /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EEAC1DC9E967001D7AAB /* UIFontExtensions.swift */; };
3BB2EEAF1DCA1E67001D7AAB /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EEAE1DCA1E67001D7AAB /* Do.swift */; };
3BB2EEB11DCA24B4001D7AAB /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB2EEB01DCA24B4001D7AAB /* UIButtonExtensions.swift */; };
3BDCEAA71F25BB390098324A /* CALayerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BDCEAA61F25BB390098324A /* CALayerExtensions.swift */; };
3BE220D61F232738005D81E9 /* UIGraphicsPDFRendererContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BE220D51F232716005D81E9 /* UIGraphicsPDFRendererContext.swift */; };
3BF5F3451DC8CE3C0037C598 /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF5F3441DC8CE3C0037C598 /* UIButton.swift */; };
3BF5F3471DC8D1120037C598 /* UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF5F3461DC8D1120037C598 /* UILabel.swift */; };
Expand Down Expand Up @@ -334,19 +330,15 @@
3B4080FD1F2080F000F810BE /* CALayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CALayer.swift; sourceTree = "<group>"; };
3B4080FE1F2080F000F810BE /* CAGradientLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CAGradientLayer.swift; sourceTree = "<group>"; };
3B4081141F22E8FB00F810BE /* SetHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetHelper.swift; sourceTree = "<group>"; };
3B89336D1F25D8480037F115 /* Sub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sub.swift; sourceTree = "<group>"; };
3BB2EE8E1DC99F0E001D7AAB /* UICollectionViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensions.swift; sourceTree = "<group>"; };
3BB2EE901DC9B65B001D7AAB /* UICollectionViewFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewFlowLayout.swift; sourceTree = "<group>"; };
3BB2EE921DC9BF09001D7AAB /* UIStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStackView.swift; sourceTree = "<group>"; };
3BB2EE941DC9BF46001D7AAB /* UIStackViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStackViewExtensions.swift; sourceTree = "<group>"; };
3BB2EE981DC9C2B1001D7AAB /* CGGeometryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGGeometryExtensions.swift; sourceTree = "<group>"; };
3BB2EE9A1DC9C3E2001D7AAB /* CGAffineTransformExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGAffineTransformExtensions.swift; sourceTree = "<group>"; };
3BB2EE9C1DC9C5DE001D7AAB /* CGContextExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGContextExtensions.swift; sourceTree = "<group>"; };
3BB2EE9E1DC9C6B1001D7AAB /* UIEdgeInsetsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIEdgeInsetsExtensions.swift; sourceTree = "<group>"; };
3BB2EEA01DC9CE7E001D7AAB /* UIViewControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensions.swift; sourceTree = "<group>"; };
3BB2EEAA1DC9E891001D7AAB /* Font.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Font.swift; sourceTree = "<group>"; };
3BB2EEAC1DC9E967001D7AAB /* UIFontExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = "<group>"; };
3BB2EEAE1DCA1E67001D7AAB /* Do.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Do.swift; sourceTree = "<group>"; };
3BB2EEB01DCA24B4001D7AAB /* UIButtonExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButtonExtensions.swift; sourceTree = "<group>"; };
3BDCEAA61F25BB390098324A /* CALayerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CALayerExtensions.swift; sourceTree = "<group>"; };
3BE220D51F232716005D81E9 /* UIGraphicsPDFRendererContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGraphicsPDFRendererContext.swift; sourceTree = "<group>"; };
3BF5F3441DC8CE3C0037C598 /* UIButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = "<group>"; };
3BF5F3461DC8D1120037C598 /* UILabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -582,8 +574,8 @@
children = (
3B0A44EC1F1F6C23004757F1 /* PandaChain.swift */,
3B2B901F1DC8530800B4E92F /* Actions.swift */,
3BB2EEAE1DCA1E67001D7AAB /* Do.swift */,
3BB2EEAA1DC9E891001D7AAB /* Font.swift */,
3B89336D1F25D8480037F115 /* Sub.swift */,
3B4081141F22E8FB00F810BE /* SetHelper.swift */,
);
path = Basics;
Expand All @@ -592,13 +584,9 @@
3BB2EE961DC9C1FD001D7AAB /* Extensions */ = {
isa = PBXGroup;
children = (
3BB2EE9A1DC9C3E2001D7AAB /* CGAffineTransformExtensions.swift */,
3BB2EE9C1DC9C5DE001D7AAB /* CGContextExtensions.swift */,
3BB2EE981DC9C2B1001D7AAB /* CGGeometryExtensions.swift */,
3BDCEAA61F25BB390098324A /* CALayerExtensions.swift */,
3BB2EEB01DCA24B4001D7AAB /* UIButtonExtensions.swift */,
3BB2EE8E1DC99F0E001D7AAB /* UICollectionViewExtensions.swift */,
3BB2EE9E1DC9C6B1001D7AAB /* UIEdgeInsetsExtensions.swift */,
3BB2EEAC1DC9E967001D7AAB /* UIFontExtensions.swift */,
3BB2EE941DC9BF46001D7AAB /* UIStackViewExtensions.swift */,
3BF5F3561DC991000037C598 /* UITableViewExtensions.swift */,
3B2B90181DC7770500B4E92F /* UIViewExtensions.swift */,
Expand Down Expand Up @@ -705,6 +693,7 @@
3B4081051F20810600F810BE /* CAEmitterLayer.swift in Sources */,
3B4081061F20810600F810BE /* CAGradientLayer.swift in Sources */,
3B4081071F20810600F810BE /* CAKeyframeAnimation.swift in Sources */,
3B89336E1F25D8480037F115 /* Sub.swift in Sources */,
3B4081081F20810600F810BE /* CALayer.swift in Sources */,
3B4081091F20810600F810BE /* CAMediaTiming.swift in Sources */,
3B4081151F22E8FB00F810BE /* SetHelper.swift in Sources */,
Expand Down Expand Up @@ -759,6 +748,7 @@
3B4080971F20800700F810BE /* UIDocumentMenuViewController.swift in Sources */,
3B4080981F20800700F810BE /* UIDocumentPickerViewController.swift in Sources */,
3B4080991F20800700F810BE /* UIDynamicAnimator.swift in Sources */,
3BDCEAA71F25BB390098324A /* CALayerExtensions.swift in Sources */,
3B40809A1F20800700F810BE /* UIDynamicBehavior.swift in Sources */,
3B40809B1F20800700F810BE /* UIDynamicItem.swift in Sources */,
3B40809C1F20800700F810BE /* UIDynamicItemBehavior.swift in Sources */,
Expand Down Expand Up @@ -839,11 +829,7 @@
3B4080E71F20800700F810BE /* UIVisualEffectView.swift in Sources */,
3B4080E81F20800700F810BE /* UIWebView.swift in Sources */,
3B4080E91F20800700F810BE /* UIWindow.swift in Sources */,
3BB2EE9F1DC9C6B1001D7AAB /* UIEdgeInsetsExtensions.swift in Sources */,
3BB2EE8F1DC99F0E001D7AAB /* UICollectionViewExtensions.swift in Sources */,
3BB2EEAD1DC9E967001D7AAB /* UIFontExtensions.swift in Sources */,
3BB2EE9D1DC9C5DE001D7AAB /* CGContextExtensions.swift in Sources */,
3BB2EE9B1DC9C3E2001D7AAB /* CGAffineTransformExtensions.swift in Sources */,
3BB2EE931DC9BF09001D7AAB /* UIStackView.swift in Sources */,
3BF5F3591DC99E680037C598 /* UICollectionView.swift in Sources */,
3B0A44ED1F1F6C23004757F1 /* PandaChain.swift in Sources */,
Expand All @@ -855,10 +841,8 @@
3BB2EE911DC9B65B001D7AAB /* UICollectionViewFlowLayout.swift in Sources */,
3BB2EEB11DCA24B4001D7AAB /* UIButtonExtensions.swift in Sources */,
3BF5F3491DC8D5600037C598 /* UITextField.swift in Sources */,
3BB2EEAF1DCA1E67001D7AAB /* Do.swift in Sources */,
3BF5F34D1DC8DB220037C598 /* UITextView.swift in Sources */,
3B2B901E1DC8519D00B4E92F /* UIControl.swift in Sources */,
3BB2EE991DC9C2B1001D7AAB /* CGGeometryExtensions.swift in Sources */,
3BB2EE951DC9BF46001D7AAB /* UIStackViewExtensions.swift in Sources */,
3BB2EEA11DC9CE7E001D7AAB /* UIViewControllerExtensions.swift in Sources */,
3BF5F3571DC991000037C598 /* UITableViewExtensions.swift in Sources */,
Expand Down
81 changes: 53 additions & 28 deletions Sources/Basics/Actions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,33 @@
// Actions.swift
// Panda
//
// Created by Javier on 11/1/16.
// Copyright © 2016 Javier. All rights reserved.
// Copyright (c) 2017 Javier Zhang (https://wordlessj.github.io/)
//
// 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.
//

import UIKit

private class ActionBox {
static let triggerSelector = #selector(trigger)

let action: () -> ()
private let action: () -> ()

init(action: @escaping () -> ()) {
self.action = action
Expand All @@ -22,38 +39,41 @@ private class ActionBox {
}
}

extension UIControlEvents: Hashable {
public var hashValue: Int { return Int(rawValue) }
}

private var actionBoxKey: UInt8 = 0

extension UIControl {
private var actionBoxes: [UIControlEvents: ActionBox] {
get { return objc_getAssociatedObject(self, &actionBoxKey) as? [UIControlEvents: ActionBox] ?? [:] }
fileprivate var actionBoxes: [UInt: ActionBox] {
get { return objc_getAssociatedObject(self, &actionBoxKey) as? [UInt: ActionBox] ?? [:] }
set { objc_setAssociatedObject(self, &actionBoxKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}
}

extension PandaChain where Object: UIControl {
/// Associates `action` for `events`.
///
/// - parameters:
/// - events: Defaults to `touchUpInside`.
/// - action: If `nil`, the action associated with `events` will be removed.
@discardableResult
public func action(events: UIControlEvents = .touchUpInside, action: (() -> ())?) -> Self {
if let box = actionBoxes[events] {
removeTarget(box, action: ActionBox.triggerSelector, for: events)
actionBoxes[events] = nil
public func action(for events: UIControlEvents = .touchUpInside, action: (() -> ())?) -> PandaChain {
if let box = object.actionBoxes[events.rawValue] {
object.removeTarget(box, action: ActionBox.triggerSelector, for: events)
object.actionBoxes[events.rawValue] = nil
}

if let action = action {
let box = ActionBox(action: action)
addTarget(box, action: ActionBox.triggerSelector, for: events)
actionBoxes[events] = box
object.addTarget(box, action: ActionBox.triggerSelector, for: events)
object.actionBoxes[events.rawValue] = box
}

return self
}
}

private class ObjectActionBox<Object: AnyObject> {
unowned let object: Object
let action: (Object) -> ()
private unowned let object: Object
private let action: (Object) -> ()

init(object: Object, action: @escaping (Object) -> ()) {
self.object = object
Expand All @@ -68,28 +88,33 @@ private class ObjectActionBox<Object: AnyObject> {
public protocol GestureRecognizer: class {}

extension GestureRecognizer where Self: UIGestureRecognizer {
private var actionBox: ObjectActionBox<Self>? {
fileprivate var actionBox: ObjectActionBox<Self>? {
get { return objc_getAssociatedObject(self, &actionBoxKey) as? ObjectActionBox<Self> }
set { objc_setAssociatedObject(self, &actionBoxKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}
}

extension UIGestureRecognizer: GestureRecognizer {}

extension PandaChain where Object: UIGestureRecognizer {
/// Set `action`.
///
/// - parameter action: If `nil`, the action set before will be removed.
@discardableResult
public func action(_ action: ((Self) -> ())?) -> Self {
let selector = #selector(ObjectActionBox<Self>.trigger)
public func action(_ action: ((Object) -> ())?) -> PandaChain {
let selector = #selector(ObjectActionBox<Object>.trigger)

if let box = actionBox {
removeTarget(box, action: selector)
actionBox = nil
if let box = object.actionBox {
object.removeTarget(box, action: selector)
object.actionBox = nil
}

if let action = action {
let box = ObjectActionBox(object: self, action: action)
addTarget(box, action: selector)
actionBox = box
let box = ObjectActionBox(object: object, action: action)
object.addTarget(box, action: selector)
object.actionBox = box
}

return self
}
}

extension UIGestureRecognizer: GestureRecognizer {}
21 changes: 0 additions & 21 deletions Sources/Basics/Do.swift

This file was deleted.

4 changes: 2 additions & 2 deletions Sources/Basics/Font.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ extension PandaChain where Object: FontContainer {

@available(iOS 8.2, *)
@discardableResult
public func font(size: CGFloat, weight: UIFont.Weight) -> PandaChain {
public func font(size: CGFloat, weight: UIFontWeight) -> PandaChain {
return font(.systemFont(ofSize: size, weight: weight))
}

Expand All @@ -70,7 +70,7 @@ extension PandaChain where Object: FontContainer {

@available(iOS 9.0, *)
@discardableResult
public func font(monospacedDigitSize size: CGFloat, weight: UIFont.Weight) -> PandaChain {
public func font(monospacedDigitSize size: CGFloat, weight: UIFontWeight) -> PandaChain {
return font(.monospacedDigitSystemFont(ofSize: size, weight: weight))
}
}
Expand Down
35 changes: 34 additions & 1 deletion Sources/Basics/PandaChain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,44 @@ public struct PandaChain<Object> {
public var object: Object
}

extension PandaChain {
/// Do something on the object.
///
/// - parameter action: Something to be done.
@discardableResult
public func `do`(_ action: (Object) -> ()) -> PandaChain {
action(object)
return self
}
}

struct ConfigStack {
static var shared = ConfigStack()

private var stack = [[Any]]()

mutating func push() {
stack.append([])
}

mutating func pop() -> [Any] {
return stack.removeLast()
}

mutating func add(_ element: Any) {
guard !stack.isEmpty else { return }
stack[stack.count - 1].append(element)
}
}

public protocol PandaChainable {}

extension PandaChainable {
/// Panda extensions.
public var panda: PandaChain<Self> { return PandaChain(object: self) }
public var pd: PandaChain<Self> {
ConfigStack.shared.add(self)
return PandaChain(object: self)
}
}

extension NSObject: PandaChainable {}
Loading

0 comments on commit 1e72b61

Please sign in to comment.