Skip to content

Commit

Permalink
Basic extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
wordlessj committed Nov 2, 2016
0 parents commit de4d639
Show file tree
Hide file tree
Showing 30 changed files with 2,664 additions and 0 deletions.
96 changes: 96 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
### macOS ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk


### Swift ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
build/
DerivedData/

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/

## Other
*.moved-aside
*.xcuserstate

## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
.build/

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output

423 changes: 423 additions & 0 deletions Panda.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions Panda.xcodeproj/project.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 80 additions & 0 deletions Panda.xcodeproj/xcshareddata/xcschemes/Panda.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3B2B90071DC70A3E00B4E92F"
BuildableName = "Panda.framework"
BlueprintName = "Panda"
ReferencedContainer = "container:Panda.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3B2B90071DC70A3E00B4E92F"
BuildableName = "Panda.framework"
BlueprintName = "Panda"
ReferencedContainer = "container:Panda.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3B2B90071DC70A3E00B4E92F"
BuildableName = "Panda.framework"
BlueprintName = "Panda"
ReferencedContainer = "container:Panda.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
75 changes: 75 additions & 0 deletions Panda/Actions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// Actions.swift
// Panda
//
// Created by Javier on 11/1/16.
// Copyright © 2016 Javier. All rights reserved.
//

import UIKit

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

let action: () -> ()

init(action: @escaping () -> ()) {
self.action = action
}

@objc func trigger() {
action()
}
}

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] ?? [:] }
set { objc_setAssociatedObject(self, &actionBoxKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}

@discardableResult
public func action(events: UIControlEvents = .touchUpInside, action: (() -> ())?) -> Self {
if let box = actionBoxes[events] {
removeTarget(box, action: ActionBox.triggerSelector, for: events)
actionBoxes[events] = nil
}

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

return self
}
}

extension UIGestureRecognizer {
private var actionBox: ActionBox? {
get { return objc_getAssociatedObject(self, &actionBoxKey) as? ActionBox }
set { objc_setAssociatedObject(self, &actionBoxKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}

@discardableResult
public func action(_ action: (() -> ())?) -> Self {
if let box = actionBox {
removeTarget(box, action: ActionBox.triggerSelector)
actionBox = nil
}

if let action = action {
let box = ActionBox(action: action)
addTarget(box, action: ActionBox.triggerSelector)
actionBox = box
}

return self
}
}
41 changes: 41 additions & 0 deletions Panda/CGAffineTransformExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// CGAffineTransformExtensions.swift
// Panda
//
// Created by Javier on 9/9/16.
// Copyright © 2016 Javier. All rights reserved.
//

import CoreGraphics

extension CGFloat {
fileprivate var angleRadian: CGFloat { return self / 180 * CGFloat.pi }
}

extension CGAffineTransform {
public var scale: CGPoint {
get { return CGPoint(x: a, y: d) }
set { (a, d) = (newValue.x, newValue.y) }
}

public var translation: CGPoint {
get { return CGPoint(x: tx, y: ty) }
set { (tx, ty) = (newValue.x, newValue.y) }
}

public init(rotationDegree degree: CGFloat) {
self.init(rotationAngle: degree.angleRadian)
}

public init(scale: CGFloat) {
self.init(scaleX: scale, y: scale)
}

public func rotated(byDegree degree: CGFloat) -> CGAffineTransform {
return rotated(by: degree.angleRadian)
}

public func scaled(by scale: CGFloat) -> CGAffineTransform {
return scaledBy(x: scale, y: scale)
}
}
21 changes: 21 additions & 0 deletions Panda/CGContextExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// CGContextExtensions.swift
// Panda
//
// Created by Javier on 9/9/16.
// Copyright © 2016 Javier. All rights reserved.
//

import CoreGraphics

extension CGContext {
public func flipHorizontally(width: CGFloat) {
translateBy(x: width, y: 0)
scaleBy(x: -1, y: 1)
}

public func flipVertically(height: CGFloat) {
translateBy(x: 0, y: height)
scaleBy(x: 1, y: -1)
}
}
Loading

0 comments on commit de4d639

Please sign in to comment.