From df002921dbe27e41727a3391c8efb5101e6f0a47 Mon Sep 17 00:00:00 2001 From: Yoshitaka Seki Date: Tue, 13 Aug 2019 22:20:45 +0900 Subject: [PATCH 1/3] Specialize Extension for UIKit to iOS --- ActionClosurable.xcodeproj/project.pbxproj | 8 +-- ActionClosurable/Extensions_UIKit.swift | 74 ++++++++++++++++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 ActionClosurable/Extensions_UIKit.swift diff --git a/ActionClosurable.xcodeproj/project.pbxproj b/ActionClosurable.xcodeproj/project.pbxproj index f4388bb..e72c64a 100644 --- a/ActionClosurable.xcodeproj/project.pbxproj +++ b/ActionClosurable.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ B61D45B61CBAB1AA00BCADB7 /* ActionClosurableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61D45B51CBAB1AA00BCADB7 /* ActionClosurableTests.swift */; }; B6554A2D1CC24F3D0060DC4B /* ActionClosurable.h in Headers */ = {isa = PBXBuildFile; fileRef = B6554A2C1CC24F3D0060DC4B /* ActionClosurable.h */; settings = {ATTRIBUTES = (Public, ); }; }; B6554A3D1CC258010060DC4B /* ActionClosurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61D45C01CBB30D100BCADB7 /* ActionClosurable.swift */; }; - B6554A3E1CC258080060DC4B /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61D45C61CBB45D000BCADB7 /* Extensions.swift */; }; + B6554A3E1CC258080060DC4B /* Extensions_UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61D45C61CBB45D000BCADB7 /* Extensions_UIKit.swift */; }; B6554A4E1CC25F320060DC4B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6554A4D1CC25F320060DC4B /* AppDelegate.swift */; }; B6554A501CC25F320060DC4B /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6554A4F1CC25F320060DC4B /* ViewController.swift */; }; B6554A531CC25F320060DC4B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6554A511CC25F320060DC4B /* Main.storyboard */; }; @@ -57,7 +57,7 @@ B61D45B51CBAB1AA00BCADB7 /* ActionClosurableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionClosurableTests.swift; sourceTree = ""; }; B61D45B71CBAB1AA00BCADB7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; B61D45C01CBB30D100BCADB7 /* ActionClosurable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionClosurable.swift; sourceTree = ""; }; - B61D45C61CBB45D000BCADB7 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; + B61D45C61CBB45D000BCADB7 /* Extensions_UIKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions_UIKit.swift; sourceTree = ""; }; B6554A2A1CC24F3D0060DC4B /* ActionClosurable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ActionClosurable.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B6554A2C1CC24F3D0060DC4B /* ActionClosurable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActionClosurable.h; sourceTree = ""; }; B6554A4B1CC25F320060DC4B /* ActionClosurable-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ActionClosurable-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -128,7 +128,7 @@ isa = PBXGroup; children = ( B61D45C01CBB30D100BCADB7 /* ActionClosurable.swift */, - B61D45C61CBB45D000BCADB7 /* Extensions.swift */, + B61D45C61CBB45D000BCADB7 /* Extensions_UIKit.swift */, B61D45AC1CBAB1AA00BCADB7 /* Info.plist */, B6554A2C1CC24F3D0060DC4B /* ActionClosurable.h */, ); @@ -302,7 +302,7 @@ buildActionMask = 2147483647; files = ( B6554A3D1CC258010060DC4B /* ActionClosurable.swift in Sources */, - B6554A3E1CC258080060DC4B /* Extensions.swift in Sources */, + B6554A3E1CC258080060DC4B /* Extensions_UIKit.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ActionClosurable/Extensions_UIKit.swift b/ActionClosurable/Extensions_UIKit.swift new file mode 100644 index 0000000..43e3c11 --- /dev/null +++ b/ActionClosurable/Extensions_UIKit.swift @@ -0,0 +1,74 @@ +// +// Extensions_UIKit.swift +// ActionClosurable +// +// Created by Yoshitaka Seki on 2016/04/11. +// Copyright © 2016年 Yoshitaka Seki. All rights reserved. +// + +#if os(iOS) +import UIKit + +extension ActionClosurable where Self: UIControl { + public func on(_ controlEvents: UIControl.Event, closure: @escaping (Self) -> Void) { + convert(closure: closure, toConfiguration: { + self.addTarget($0, action: $1, for: controlEvents) + }) + } +} + +extension ActionClosurable where Self: UIButton { + public func onTap(_ closure: @escaping (Self) -> Void) { + on(.touchUpInside, closure: closure) + } +} + +public extension ActionClosurable where Self: UIRefreshControl { + func onValueChanged(closure: @escaping (Self) -> Void) { + on(.valueChanged, closure: closure) + } + + init(closure: @escaping (Self) -> Void) { + self.init() + onValueChanged(closure: closure) + } +} + + +extension ActionClosurable where Self: UIGestureRecognizer { + public func onGesture(_ closure: @escaping (Self) -> Void) { + convert(closure: closure, toConfiguration: { + self.addTarget($0, action: $1) + }) + } + public init(closure: @escaping (Self) -> Void) { + self.init() + onGesture(closure) + } +} + +extension ActionClosurable where Self: UIBarButtonItem { + public init(title: String, style: UIBarButtonItem.Style, closure: @escaping (Self) -> Void) { + self.init() + self.title = title + self.style = style + self.onTap(closure) + } + public init(image: UIImage?, style: UIBarButtonItem.Style, closure: @escaping (Self) -> Void) { + self.init() + self.image = image + self.style = style + self.onTap(closure) + } + public init(barButtonSystemItem: UIBarButtonItem.SystemItem, closure: @escaping (Self) -> Void) { + self.init(barButtonSystemItem: barButtonSystemItem, target: nil, action: nil) + self.onTap(closure) + } + public func onTap(_ closure: @escaping (Self) -> Void) { + convert(closure: closure, toConfiguration: { + self.target = $0 + self.action = $1 + }) + } +} +#endif From 76740360447e25c836274ccb8196f64001d3c629 Mon Sep 17 00:00:00 2001 From: Yoshitaka Seki Date: Tue, 13 Aug 2019 22:23:14 +0900 Subject: [PATCH 2/3] Add Package.swift --- ActionClosurable.xcodeproj/project.pbxproj | 2 ++ Package.swift | 26 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 Package.swift diff --git a/ActionClosurable.xcodeproj/project.pbxproj b/ActionClosurable.xcodeproj/project.pbxproj index e72c64a..7fad030 100644 --- a/ActionClosurable.xcodeproj/project.pbxproj +++ b/ActionClosurable.xcodeproj/project.pbxproj @@ -67,6 +67,7 @@ B6554A541CC25F320060DC4B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B6554A571CC25F320060DC4B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; B6554A591CC25F320060DC4B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B6E9AC782302EAFF006B49C5 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -98,6 +99,7 @@ B61D45941CBAB1AA00BCADB7 = { isa = PBXGroup; children = ( + B6E9AC782302EAFF006B49C5 /* Package.swift */, B61D45B41CBAB1AA00BCADB7 /* ActionClosurableTests */, B6554A2B1CC24F3D0060DC4B /* ActionClosurable */, B6554A4C1CC25F320060DC4B /* ActionClosurable-Demo */, diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..04c93be --- /dev/null +++ b/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version:5.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "ActionClosurable", + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "ActionClosurable", + targets: ["ActionClosurable"]), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "ActionClosurable", + path: "ActionClosurable" + ), + .testTarget( + name: "ActionClosurableTests", + path: "ActionClosurableTests" + ), + ] +) From 76506057012fc41c2510e24332d41c644a3c99b9 Mon Sep 17 00:00:00 2001 From: Yoshitaka Seki Date: Tue, 13 Aug 2019 22:41:33 +0900 Subject: [PATCH 3/3] Add install guide for SwiftPM in README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 10c93c0..20d818b 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,18 @@ ActionClosurable is available through [Carthage](https://github.com/Carthage/Car github "takasek/ActionClosurable" ``` +ActionClosurable is available through [Swift Package Manager](https://github.com/apple/swift-package-manager). To install it, add dependency in `Package.swift`: + +```swift +let package = Package( + ... + dependencies: [ + .package(url: "git@github.com:takasek/ActionClosurable.git", from: "2.1.0"), + ], + ... +) +``` + ## Author [takasek](https://twitter.com/takasek)