├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── .travis.yml ├── ButtonClickStyle.podspec ├── ButtonClickStyle ├── .gitignore ├── 1.0.0 │ └── ButtonClickStyle.podspec ├── 1.0.1 │ └── ButtonClickStyle.podspec ├── 1.0.2 │ └── ButtonClickStyle.podspec ├── 1.0.3 │ └── ButtonClickStyle.podspec ├── 1.0.5 │ └── ButtonClickStyle.podspec ├── 1.1.0 │ └── ButtonClickStyle.podspec ├── 1.1.1 │ └── ButtonClickStyle.podspec ├── 1.2.0 │ └── ButtonClickStyle.podspec ├── 1.2.2 │ └── ButtonClickStyle.podspec ├── 1.3.1 │ └── ButtonClickStyle.podspec ├── 1.3.2 │ └── ButtonClickStyle.podspec ├── 1.3.3 │ └── ButtonClickStyle.podspec ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ └── ReplaceMe.swift ├── Example ├── ButtonClickStyle.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ ├── ButtonClickStyle-Example.xcscheme │ │ └── ButtonClickStyle.xcscheme ├── ButtonClickStyle.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── ButtonClickStyle │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── ButtonClickStyle+Buttons.swift │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── 123-1024.png │ │ │ ├── 123-20.png │ │ │ ├── 123-20@2x.png │ │ │ ├── 123-20@3x.png │ │ │ ├── 123-29.png │ │ │ ├── 123-29@2x.png │ │ │ ├── 123-29@3x.png │ │ │ ├── 123-40.png │ │ │ ├── 123-40@2x.png │ │ │ ├── 123-40@3x.png │ │ │ ├── 123-60@2x.png │ │ │ ├── 123-60@3x.png │ │ │ ├── 123-76.png │ │ │ ├── 123-76@2x.png │ │ │ ├── 123-83.5@2x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── icCheck.imageset │ │ │ ├── Contents.json │ │ │ └── icons8-галочка-24 1.png │ │ ├── icDownload.imageset │ │ │ ├── Contents.json │ │ │ └── icons8-скачать-96 (1) 1.png │ │ ├── icGooglePlus.imageset │ │ │ ├── Contents.json │ │ │ └── icGooglePlus.png │ │ ├── icWhitePlus.imageset │ │ │ ├── Contents.json │ │ │ └── icWhitePlus.png │ │ ├── imgDeleteTexture.imageset │ │ │ ├── Contents.json │ │ │ └── DeleteTexture.png │ │ └── imgLaunchStart.imageset │ │ │ ├── Contents.json │ │ │ └── imgLaunchStart.png │ ├── Info.plist │ ├── SceneDelegate.swift │ ├── UI │ │ ├── Button │ │ │ ├── Blue │ │ │ │ ├── BlueButtonView.swift │ │ │ │ └── BlueButtonView.xib │ │ │ ├── BorderGreenDark │ │ │ │ ├── BorderGreenDarkButtonView.swift │ │ │ │ └── BorderGreenDarkButtonView.xib │ │ │ ├── BuyNow │ │ │ │ ├── BuyNowButtonView.swift │ │ │ │ └── BuyNowButtonView.xib │ │ │ ├── Delete │ │ │ │ ├── DeleteButtonView.swift │ │ │ │ └── DeleteButtonView.xib │ │ │ ├── Download │ │ │ │ ├── DownloadButtonView.swift │ │ │ │ └── DownloadButtonView.xib │ │ │ ├── Firefox │ │ │ │ ├── FirefoxButtonView.swift │ │ │ │ └── FirefoxButtonView.xib │ │ │ ├── Google │ │ │ │ ├── GoogleButtonView.swift │ │ │ │ └── GoogleButtonView.xib │ │ │ ├── GradientBlue │ │ │ │ ├── GradientBlueBasicButtonView.swift │ │ │ │ └── GradientBlueBasicButtonView.xib │ │ │ ├── JustPink │ │ │ │ ├── JustPinkButtonView.swift │ │ │ │ └── JustPinkButtonView.xib │ │ │ ├── Neomorphism │ │ │ │ ├── NeomorphismButtonView.swift │ │ │ │ └── NeomorphismButtonView.xib │ │ │ ├── Search │ │ │ │ ├── SearchButtonView.swift │ │ │ │ └── SearchButtonView.xib │ │ │ ├── Subscribe │ │ │ │ ├── SubscribeButtonView.swift │ │ │ │ └── SubscribeButtonView.xib │ │ │ ├── TestDemoBlur │ │ │ │ ├── TestDemoBlurButtonView.swift │ │ │ │ └── TestDemoBlurButtonView.xib │ │ │ ├── TestDemoGradient │ │ │ │ ├── TestDemoGradientButtonView.swift │ │ │ │ └── TestDemoGradientButtonView.xib │ │ │ └── TestDemoSquares │ │ │ │ ├── TestDemoSquaresButtonView.swift │ │ │ │ └── TestDemoSquaresButtonView.xib │ │ ├── Cell │ │ │ └── ButtonListCell │ │ │ │ ├── ButtonListCell.swift │ │ │ │ └── ButtonListCell.xib │ │ ├── ScreenIPad │ │ │ ├── ExampleButtons │ │ │ │ ├── ExampleButtonsViewController.storyboard │ │ │ │ └── ExampleButtonsViewController.swift │ │ │ ├── ExampleClickStyleAnimations │ │ │ │ ├── ExampleAnimationsViewController.storyboard │ │ │ │ └── ExampleAnimationsViewController.swift │ │ │ ├── Test │ │ │ │ ├── TestViewController.storyboard │ │ │ │ └── TestViewController.swift │ │ │ ├── Test2 │ │ │ │ ├── Test2ViewController.storyboard │ │ │ │ └── Test2ViewController.swift │ │ │ └── TestDemo │ │ │ │ ├── TestDemoViewController.storyboard │ │ │ │ └── TestDemoViewController.swift │ │ ├── ScreenIPhone │ │ │ ├── ButtonList │ │ │ │ ├── ButtonListViewController.storyboard │ │ │ │ └── ButtonListViewController.swift │ │ │ ├── ButtonProgram │ │ │ │ ├── ButtonProgramViewController.storyboard │ │ │ │ └── ButtonProgramViewController.swift │ │ │ └── ButtonTableList │ │ │ │ ├── ButtonTableListViewController.storyboard │ │ │ │ └── ButtonTableListViewController.swift │ │ └── View │ │ │ └── ButtonLayerExample │ │ │ ├── ButtonLayerExampleView.swift │ │ │ └── ButtonLayerExampleView.xib │ ├── Utils │ │ ├── LoadNib │ │ │ ├── BtnView.swift │ │ │ ├── StoryboardController.swift │ │ │ └── XibView.swift │ │ └── TableAdapterView │ │ │ ├── Cell │ │ │ ├── TableAdapterCell.swift │ │ │ ├── TableAdapterCellData.swift │ │ │ ├── TableAdapterItem.swift │ │ │ └── TitleTextCell │ │ │ │ ├── TitleTextCell.swift │ │ │ │ └── TitleTextCell.xib │ │ │ ├── TableAdapterView+AddGradient.swift │ │ │ ├── TableAdapterView+CallbackTypes.swift │ │ │ ├── TableAdapterView+DataSource.swift │ │ │ ├── TableAdapterView+Delegate.swift │ │ │ ├── TableAdapterView+ScrollDelegate.swift │ │ │ ├── TableAdapterView+Set.swift │ │ │ ├── TableAdapterView+UpdateRows.swift │ │ │ └── TableAdapterView.swift │ └── ViewController.swift ├── Podfile ├── Podfile.lock └── Pods │ ├── FBSnapshotTestCase │ ├── FBSnapshotTestCase │ │ ├── Categories │ │ │ ├── UIApplication+StrictKeyWindow.h │ │ │ ├── UIApplication+StrictKeyWindow.m │ │ │ ├── UIImage+Compare.h │ │ │ ├── UIImage+Compare.m │ │ │ ├── UIImage+Diff.h │ │ │ ├── UIImage+Diff.m │ │ │ ├── UIImage+Snapshot.h │ │ │ └── UIImage+Snapshot.m │ │ ├── FBSnapshotTestCase.h │ │ ├── FBSnapshotTestCase.m │ │ ├── FBSnapshotTestCasePlatform.h │ │ ├── FBSnapshotTestCasePlatform.m │ │ ├── FBSnapshotTestController.h │ │ ├── FBSnapshotTestController.m │ │ └── SwiftSupport.swift │ ├── LICENSE │ └── README.md │ ├── Local Podspecs │ └── ButtonClickStyle.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ └── project.pbxproj │ └── Target Support Files │ ├── ButtonClickStyle │ ├── ButtonClickStyle-Info.plist │ ├── ButtonClickStyle-dummy.m │ ├── ButtonClickStyle-prefix.pch │ ├── ButtonClickStyle-umbrella.h │ ├── ButtonClickStyle.debug.xcconfig │ ├── ButtonClickStyle.modulemap │ └── ButtonClickStyle.release.xcconfig │ ├── FBSnapshotTestCase │ ├── FBSnapshotTestCase-Info.plist │ ├── FBSnapshotTestCase-dummy.m │ ├── FBSnapshotTestCase-prefix.pch │ ├── FBSnapshotTestCase-umbrella.h │ ├── FBSnapshotTestCase.debug.xcconfig │ ├── FBSnapshotTestCase.modulemap │ └── FBSnapshotTestCase.release.xcconfig │ ├── Pods-ButtonClickStyle_Example │ ├── Pods-ButtonClickStyle_Example-Info.plist │ ├── Pods-ButtonClickStyle_Example-acknowledgements.markdown │ ├── Pods-ButtonClickStyle_Example-acknowledgements.plist │ ├── Pods-ButtonClickStyle_Example-dummy.m │ ├── Pods-ButtonClickStyle_Example-frameworks.sh │ ├── Pods-ButtonClickStyle_Example-umbrella.h │ ├── Pods-ButtonClickStyle_Example.debug.xcconfig │ ├── Pods-ButtonClickStyle_Example.modulemap │ └── Pods-ButtonClickStyle_Example.release.xcconfig │ └── Pods-ButtonClickStyle_Tests │ ├── Pods-ButtonClickStyle_Tests-Info.plist │ ├── Pods-ButtonClickStyle_Tests-acknowledgements.markdown │ ├── Pods-ButtonClickStyle_Tests-acknowledgements.plist │ ├── Pods-ButtonClickStyle_Tests-dummy.m │ ├── Pods-ButtonClickStyle_Tests-frameworks.sh │ ├── Pods-ButtonClickStyle_Tests-umbrella.h │ ├── Pods-ButtonClickStyle_Tests.debug.xcconfig │ ├── Pods-ButtonClickStyle_Tests.modulemap │ └── Pods-ButtonClickStyle_Tests.release.xcconfig ├── LICENSE ├── Package.swift ├── README.md ├── Sources └── ButtonClickStyle │ ├── Animations │ ├── ButtonClickStyleAnim+UIView.swift │ ├── ButtonClickStyleAnim+UIViewAlpha.swift │ ├── ButtonClickStyleAnim+UIViewAndroidPulse.swift │ ├── ButtonClickStyleAnim+UIViewColor.swift │ ├── ButtonClickStyleAnim+UIViewColorFlat.swift │ ├── ButtonClickStyleAnim+UIViewFlash.swift │ ├── ButtonClickStyleAnim+UIViewGlare.swift │ ├── ButtonClickStyleAnim+UIViewPress.swift │ ├── ButtonClickStyleAnim+UIViewPulsate.swift │ ├── ButtonClickStyleAnim+UIViewPulse.swift │ ├── ButtonClickStyleAnim+UIViewShadow.swift │ └── ButtonClickStyleAnim+UIViewSnake.swift │ ├── ButtonClicClosure.swift │ ├── ButtonClick.swift │ ├── ButtonClickState.swift │ ├── ButtonClickStyle+UIButtonAddAnimation.swift │ ├── ButtonClickStyle.swift │ ├── ButtonClickStyleButton.swift │ ├── ButtonClickStyleGestureRecognizer.swift │ ├── ButtonClickStyleView.swift │ ├── Style │ ├── ButtonClickStyleBase.swift │ ├── ButtonClickStyleEmoji.swift │ ├── ButtonClickStyleShort.swift │ └── ButtonClickStyles.swift │ └── UIDesignable │ ├── ButtonClickStyleDesignLabel.swift │ ├── ButtonClickStyleDesignTest.swift │ └── ButtonClickStyleDesignView.swift ├── _Pods.xcodeproj └── logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | # Pods/ 38 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/ButtonClickStyle.xcworkspace -scheme ButtonClickStyle-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.3.3' 12 | s.summary = 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Sources/ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.0.0/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.0.0' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.0.1/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.0.1' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.0.2/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.0.2' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.0.3/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.0.3' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.0.5/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.0.5' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Source/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.1.0/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.1.0' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 9 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Source/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.1.1/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.1.1' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 15 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 15 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Source/ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.2.0/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.2.0' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 15 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 15 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Source/ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.2.2/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.2.2' 12 | s.summary = 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 15 click animation styles' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable designable button view. Inside layer you can style button, create your own subviews. Choose 15 click animation styles' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Sources/ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.3.1/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.3.1' 12 | s.summary = 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Sources/ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.3.2/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.3.2' 12 | s.summary = 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Sources/ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/1.3.3/ButtonClickStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ButtonClickStyle.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ButtonClickStyle' 11 | s.version = '1.3.3' 12 | s.summary = 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 'This is a customizable/designable Button-view, with 15 animated click styles, allows design custom buttons from subviews, in xib storyboard' 22 | DESC 23 | 24 | s.homepage = 'https://github.com/mrustaa/ButtonClickStyle' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'mrustaa' => 'rustamburger@gmail.com' } 28 | s.source = { :git => 'https://github.com/mrustaa/ButtonClickStyle.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = "5.0" 31 | 32 | # s.ios.deployment_target = '14.0' 33 | s.platform = :ios, "14.0" 34 | 35 | s.source_files = 'Sources/ButtonClickStyle/**/*.{swift}' 36 | 37 | # s.resource_bundles = { 38 | # 'ButtonClickStyle' => ['ButtonClickStyle/Assets/*.png'] 39 | # } 40 | 41 | # s.public_header_files = 'Pod/Classes/**/*.h' 42 | # s.frameworks = 'UIKit', 'MapKit' 43 | # s.dependency 'AFNetworking', '~> 2.3' 44 | end 45 | -------------------------------------------------------------------------------- /ButtonClickStyle/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/ButtonClickStyle/Assets/.gitkeep -------------------------------------------------------------------------------- /ButtonClickStyle/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/ButtonClickStyle/Classes/.gitkeep -------------------------------------------------------------------------------- /ButtonClickStyle/Classes/ReplaceMe.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/ButtonClickStyle/Classes/ReplaceMe.swift -------------------------------------------------------------------------------- /Example/ButtonClickStyle.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 05.04.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | // setupWindowIfNeeded() 18 | 19 | return true 20 | } 21 | 22 | private func setupWindowIfNeeded() { 23 | let window = UIWindow(frame: UIScreen.main.bounds) 24 | 25 | // let vc = TestViewController.instantiate() 26 | let vc = ExampleAnimationsViewController.instantiate() 27 | let nav = UINavigationController(rootViewController: vc) 28 | nav.setNavigationBarHidden(false, animated: false) 29 | window.rootViewController = nav 30 | window.makeKeyAndVisible() 31 | window.tintColor = #colorLiteral(red: 0.2, green: 0.2, blue: 0.2, alpha: 1) 32 | self.window = window 33 | } 34 | 35 | // MARK: UISceneSession Lifecycle 36 | 37 | @available(iOS 13.0, *) 38 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 39 | // Called when a new scene session is being created. 40 | // Use this method to select a configuration to create the new scene with. 41 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 42 | } 43 | 44 | @available(iOS 13.0, *) 45 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 46 | // Called when the user discards a scene session. 47 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 48 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 49 | } 50 | 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-1024.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-20.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-20@2x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-20@3x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-29.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-29@2x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-29@3x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-40.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-40@2x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-40@3x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-60@2x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-60@3x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-76.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-76@2x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/123-83.5@2x.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom": "iphone", 6 | "filename" : "123-20@2x.png", 7 | "scale": "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom": "iphone", 12 | "filename" : "123-20@3x.png", 13 | "scale": "3x" 14 | }, 15 | { 16 | "size" : "20x20", 17 | "idiom": "ipad", 18 | "filename" : "123-20.png", 19 | "scale": "1x" 20 | }, 21 | { 22 | "size" : "20x20", 23 | "idiom": "ipad", 24 | "filename" : "123-20@2x.png", 25 | "scale": "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "123-29@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "29x29", 35 | "idiom" : "iphone", 36 | "filename" : "123-29@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "123-40@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "40x40", 47 | "idiom" : "iphone", 48 | "filename" : "123-40@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "123-60@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "123-60@3x.png", 61 | "scale" : "3x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "123-29.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "123-29@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "123-40.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "123-40@2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "123-76.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "123-76@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "123-83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "123-1024.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icCheck.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons8-галочка-24 1.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icCheck.imageset/icons8-галочка-24 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/icCheck.imageset/icons8-галочка-24 1.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icDownload.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons8-скачать-96 (1) 1.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icDownload.imageset/icons8-скачать-96 (1) 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/icDownload.imageset/icons8-скачать-96 (1) 1.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icGooglePlus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icGooglePlus.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icGooglePlus.imageset/icGooglePlus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/icGooglePlus.imageset/icGooglePlus.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icWhitePlus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icWhitePlus.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/icWhitePlus.imageset/icWhitePlus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/icWhitePlus.imageset/icWhitePlus.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/imgDeleteTexture.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "DeleteTexture.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/imgDeleteTexture.imageset/DeleteTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/imgDeleteTexture.imageset/DeleteTexture.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/imgLaunchStart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "imgLaunchStart.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Images.xcassets/imgLaunchStart.imageset/imgLaunchStart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/Example/ButtonClickStyle/Images.xcassets/imgLaunchStart.imageset/imgLaunchStart.png -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ButtonClickStyle 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UIApplicationSceneManifest 28 | 29 | UIApplicationSupportsMultipleScenes 30 | 31 | UISceneConfigurations 32 | 33 | UIWindowSceneSessionRoleApplication 34 | 35 | 36 | UISceneConfigurationName 37 | Default Configuration 38 | UISceneDelegateClassName 39 | $(PRODUCT_MODULE_NAME).SceneDelegate 40 | UISceneStoryboardFile 41 | Main 42 | 43 | 44 | 45 | 46 | UILaunchStoryboardName 47 | LaunchScreen 48 | UIMainStoryboardFile 49 | Main 50 | UIRequiredDeviceCapabilities 51 | 52 | armv7 53 | 54 | UISupportedInterfaceOrientations 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationPortraitUpsideDown 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 05.04.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | @available(iOS 13.0, *) 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | // guard let winScene = (scene as? UIWindowScene) else { return } 20 | // window = UIWindow(windowScene: winScene) 21 | 22 | guard let _ = (scene as? UIWindowScene) else { return } 23 | 24 | // let vc = TestViewController.instantiate() 25 | // let vc = ExampleAnimationsViewController.instantiate() 26 | // let nav = UINavigationController(rootViewController: vc) 27 | // nav.setNavigationBarHidden(false, animated: false) 28 | // window?.rootViewController = nav 29 | // window?.makeKeyAndVisible() 30 | // window?.tintColor = #colorLiteral(red: 0.2, green: 0.2, blue: 0.2, alpha: 1) 31 | 32 | } 33 | 34 | @available(iOS 13.0, *) 35 | func sceneDidDisconnect(_ scene: UIScene) { 36 | // Called as the scene is being released by the system. 37 | // This occurs shortly after the scene enters the background, or when its session is discarded. 38 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 39 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 40 | } 41 | 42 | @available(iOS 13.0, *) 43 | func sceneDidBecomeActive(_ scene: UIScene) { 44 | // Called when the scene has moved from an inactive state to an active state. 45 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 46 | } 47 | 48 | @available(iOS 13.0, *) 49 | func sceneWillResignActive(_ scene: UIScene) { 50 | // Called when the scene will move from an active state to an inactive state. 51 | // This may occur due to temporary interruptions (ex. an incoming phone call). 52 | } 53 | 54 | @available(iOS 13.0, *) 55 | func sceneWillEnterForeground(_ scene: UIScene) { 56 | // Called as the scene transitions from the background to the foreground. 57 | // Use this method to undo the changes made on entering the background. 58 | } 59 | 60 | @available(iOS 13.0, *) 61 | func sceneDidEnterBackground(_ scene: UIScene) { 62 | // Called as the scene transitions from the foreground to the background. 63 | // Use this method to save data, release shared resources, and store enough scene-specific state information 64 | // to restore the scene back to its current state. 65 | } 66 | 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Blue/BlueButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | 4 | class BlueButtonView: BtnView { 5 | 6 | @IBOutlet var mainView: ButtonClickStyleDesignView! 7 | @IBOutlet private weak var titleLabel: UILabel? 8 | 9 | @IBOutlet var backColor: ButtonClickStyleDesignView! 10 | override func fill(state: ButtonClick.State?) { 11 | guard let state = state else { return } 12 | self.state = state 13 | 14 | 15 | if !state.addBackgrondColor { 16 | backgroundColor = .clear 17 | } 18 | backColor.isHidden = !state.addBackgrondColor 19 | 20 | if let _ = state.animationType { 21 | let fr: CGRect = .init(x: 28, y: 22, width: 146, height: 49) 22 | let viewAn = ButtonClickStyleView( 23 | state: state, 24 | frame: fr, 25 | radius: 24 26 | ) 27 | viewAn.insertSubview(mainView, at: 0) 28 | viewAn.updateSubviews() 29 | 30 | 31 | addSubview(viewAn) 32 | viewAn.translatesAutoresizingMaskIntoConstraints = false 33 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 34 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 35 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 36 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 37 | 38 | self.btnClickStyleView?.removeFromSuperview() 39 | self.btnClickStyleView = viewAn 40 | 41 | 42 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 43 | } 44 | 45 | titleLabel?.text = state.titleText 46 | 47 | } 48 | } 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/BorderGreenDark/BorderGreenDarkButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class BorderGreenDarkButtonView: BtnView { 4 | 5 | @IBOutlet var mainView: UIView! 6 | @IBOutlet var borderGradientView: ButtonClickStyleDesignView! 7 | @IBOutlet var borderView: ButtonClickStyleDesignView! 8 | @IBOutlet var textLabel: UILabel! 9 | 10 | @IBOutlet var backColor: UIView! 11 | 12 | override func fill(state: ButtonClick.State?) { 13 | guard let state = state else { return } 14 | self.state = state 15 | 16 | if let type = state.animationType { 17 | 18 | var views: [UIView]? = [mainView] 19 | 20 | if type == ButtonClick._Style.color.rawValue { 21 | views = [borderView, textLabel] 22 | } else if type == ButtonClick._Style.androidClickable.rawValue || 23 | type == ButtonClick._Style.androidClickableDark.rawValue { 24 | views = nil 25 | } 26 | 27 | if !state.addBackgrondColor { 28 | backgroundColor = .clear 29 | } 30 | backColor.isHidden = !state.addBackgrondColor 31 | 32 | let fr: CGRect = .init(x: 33 , y: 21, width: 135, height: 51) 33 | let viewAn = ButtonClickStyleView( 34 | state: state, 35 | frame: fr, 36 | radius: 2, 37 | addViews: views 38 | ) 39 | viewAn.insertSubview(mainView, at: 0) 40 | viewAn.updateSubviews() 41 | 42 | addSubview(viewAn) 43 | viewAn.translatesAutoresizingMaskIntoConstraints = false 44 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 45 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 46 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 47 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 48 | 49 | self.btnClickStyleView?.removeFromSuperview() 50 | self.btnClickStyleView = viewAn 51 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 52 | } 53 | 54 | textLabel.text = state.titleText 55 | 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/BuyNow/BuyNowButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | 4 | class BuyNowButtonView: BtnView { 5 | 6 | @IBOutlet var mainView: UIView! 7 | @IBOutlet var borderView: ButtonClickStyleDesignView! 8 | @IBOutlet var textLabel: UILabel! 9 | 10 | override func fill(state: ButtonClick.State?) { 11 | guard let state = state else { return } 12 | self.state = state 13 | 14 | if let type = state.animationType { 15 | 16 | var views: [UIView]? = [mainView] 17 | 18 | if type == ButtonClick._Style.color.rawValue { 19 | views = [borderView, textLabel] 20 | } else if type == ButtonClick._Style.androidClickable.rawValue || 21 | type == ButtonClick._Style.androidClickableDark.rawValue { 22 | views = nil 23 | } 24 | 25 | let fr: CGRect = .init(x: 23 , y: 22, width: 156, height: 48) 26 | let viewAn = ButtonClickStyleView( 27 | state: state, 28 | frame: fr, 29 | radius: 20, 30 | addViews: views 31 | ) 32 | viewAn.insertSubview(mainView, at: 0) 33 | viewAn.updateSubviews() 34 | 35 | addSubview(viewAn) 36 | viewAn.translatesAutoresizingMaskIntoConstraints = false 37 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 38 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 39 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 40 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 41 | 42 | self.btnClickStyleView?.removeFromSuperview() 43 | self.btnClickStyleView = viewAn 44 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 45 | } 46 | 47 | textLabel.text = state.titleText 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Delete/DeleteButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class DeleteButtonView: BtnView { 4 | 5 | @IBOutlet var mainView: UIView! 6 | @IBOutlet var designImageView: ButtonClickStyleDesignView! 7 | @IBOutlet private weak var subtitleLabel: UILabel? 8 | 9 | @IBOutlet var backColor: ButtonClickStyleDesignView! 10 | 11 | 12 | override func fill(state: ButtonClick.State?) { 13 | guard let state = state else { return } 14 | self.state = state 15 | 16 | if let _ = state.animationType { 17 | let fr: CGRect = .init(x: 18 , y: 22, width: 166, height: 49) 18 | let viewAn = ButtonClickStyleView( 19 | state: state, 20 | frame: fr, 21 | radius: 24 22 | ) 23 | viewAn.insertSubview(mainView, at: 0) 24 | viewAn.updateSubviews() 25 | 26 | if !state.addBackgrondColor { 27 | backgroundColor = .clear 28 | } 29 | backColor.isHidden = !state.addBackgrondColor 30 | 31 | addSubview(viewAn) 32 | viewAn.translatesAutoresizingMaskIntoConstraints = false 33 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 34 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 35 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 36 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 37 | 38 | self.btnClickStyleView?.removeFromSuperview() 39 | self.btnClickStyleView = viewAn 40 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 41 | } 42 | // firstImageView?.image = state.firstImage 43 | // designImageView?.layer.cornerRadius = 24 44 | subtitleLabel?.text = state.titleText 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Download/DownloadButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | 4 | class DownloadButtonView: BtnView { 5 | 6 | @IBOutlet private weak var titleLabel: UILabel? 7 | @IBOutlet var mainView: ButtonClickStyleDesignView! 8 | @IBOutlet var shadowView: ButtonClickStyleDesignView! 9 | @IBOutlet var mainTitleLabel: UILabel! 10 | 11 | @IBOutlet var backColor: ButtonClickStyleDesignView! 12 | @IBOutlet var fillView: UIView! 13 | 14 | override func fill(state: ButtonClick.State?) { 15 | guard let state = state else { return } 16 | self.state = state 17 | 18 | 19 | if !state.addBackgrondColor { 20 | backgroundColor = .clear 21 | } 22 | backColor.isHidden = !state.addBackgrondColor 23 | 24 | if let type = state.animationType { 25 | var addViews: [UIView]? = [] 26 | if type == ButtonClick._Style.press.rawValue { 27 | addViews = [fillView, shadowView] 28 | mainView.fillColor = .clear 29 | mainView.setNeedsLayout() 30 | } else if type == ButtonClick._Style.androidClickable.rawValue || 31 | type == ButtonClick._Style.androidClickableDark.rawValue { 32 | addViews = nil 33 | } else if type == ButtonClick._Style.color.rawValue { 34 | addViews = nil 35 | 36 | } else { 37 | addViews = [mainView] 38 | } 39 | 40 | let fr: CGRect = .init(x: 14 , y: 19, width: 174, height: 57) 41 | let radius = 3.0 42 | fillView.layer.cornerRadius = radius 43 | fillView.clipsToBounds = true 44 | let viewAn = ButtonClickStyleView( 45 | state: state, 46 | frame: fr, 47 | radius: radius, 48 | addViews: addViews 49 | ) 50 | viewAn.insertSubview(mainView, at: 0) 51 | viewAn.updateSubviews() 52 | 53 | addSubview(viewAn) 54 | viewAn.translatesAutoresizingMaskIntoConstraints = false 55 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 56 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 57 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 58 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 59 | 60 | self.btnClickStyleView?.removeFromSuperview() 61 | self.btnClickStyleView = viewAn 62 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 63 | } 64 | mainTitleLabel?.text = state.titleText 65 | // secondImageView?.image = state.secondImage 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Firefox/FirefoxButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class FirefoxButtonView: BtnView { 4 | @IBOutlet var mainView: UIView! 5 | @IBOutlet var titleLabel: UILabel! 6 | @IBOutlet var backColor: ButtonClickStyleDesignView! 7 | @IBOutlet var gradientView: ButtonClickStyleDesignView! 8 | @IBOutlet var gradientBackView: ButtonClickStyleDesignView! 9 | 10 | override func fill(state: ButtonClick.State?) { 11 | guard let state = state else { return } 12 | self.state = state 13 | 14 | mainView.layer.cornerRadius = 24 15 | mainView.clipsToBounds = true 16 | 17 | if let type = state.animationType { 18 | 19 | var addViews: [UIView]? = [] 20 | if type == ButtonClick.Style.colorFlat(0.5, color: .red).indx() { 21 | addViews = [gradientView] 22 | } else if type == ButtonClick._Style.androidClickable.rawValue || 23 | type == ButtonClick._Style.androidClickableDark.rawValue { 24 | addViews = [gradientView] 25 | } else if type == ButtonClick._Style.color.rawValue { 26 | addViews = nil 27 | 28 | } else { 29 | addViews = [mainView] 30 | } 31 | 32 | backColor.isHidden = !state.addBackgrondColor 33 | 34 | let fr: CGRect = .init(x: 28, y: 22, width: 146, height: 49) 35 | let radius: CGFloat = 24 36 | let viewAn = ButtonClickStyleView( 37 | state: state, 38 | frame: fr, 39 | radius: radius, 40 | addViews: addViews 41 | ) 42 | viewAn.insertSubview(mainView, at: 0) 43 | viewAn.updateSubviews() 44 | 45 | addSubview(viewAn) 46 | viewAn.translatesAutoresizingMaskIntoConstraints = false 47 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 48 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 49 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 50 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 51 | 52 | self.btnClickStyleView?.removeFromSuperview() 53 | self.btnClickStyleView = viewAn 54 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 55 | } 56 | titleLabel?.text = state.titleText 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Google/GoogleButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class GoogleButtonView: BtnView { 4 | 5 | @IBOutlet var mainView: UIView! 6 | @IBOutlet var shadowVieww: ButtonClickStyleDesignView! 7 | @IBOutlet var cardView: UIView! 8 | @IBOutlet var fillView: ButtonClickStyleDesignView! 9 | @IBOutlet private weak var titleLabel: UILabel? 10 | @IBOutlet private weak var secondImageView: UIImageView? 11 | 12 | @IBOutlet var backColor: UIView! 13 | 14 | override func fill(state: ButtonClick.State?) { 15 | guard let state = state else { return } 16 | self.state = state 17 | 18 | 19 | if let type = state.animationType { 20 | 21 | var addViews: [UIView]? = [] 22 | if type == ButtonClick._Style.press.rawValue { 23 | addViews = [cardView, shadowVieww] 24 | } else if type == ButtonClick._Style.androidClickable.rawValue || 25 | type == ButtonClick._Style.androidClickableDark.rawValue { 26 | addViews = nil 27 | } else if type == ButtonClick._Style.color.rawValue { 28 | addViews = nil 29 | 30 | } else { 31 | addViews = [mainView] 32 | } 33 | 34 | if !state.addBackgrondColor { 35 | backgroundColor = .clear 36 | } 37 | backColor.isHidden = !state.addBackgrondColor 38 | 39 | let fr: CGRect = .init(x: 35.5, y: 22.5, width: 131, height: 48) 40 | let radius: CGFloat = 24 41 | let viewAn = ButtonClickStyleView( 42 | state: state, 43 | frame: fr, 44 | radius: radius, 45 | addViews: addViews 46 | ) 47 | viewAn.insertSubview(mainView, at: 0) 48 | viewAn.updateSubviews() 49 | 50 | addSubview(viewAn) 51 | viewAn.translatesAutoresizingMaskIntoConstraints = false 52 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 53 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 54 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 55 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 56 | 57 | self.btnClickStyleView?.removeFromSuperview() 58 | self.btnClickStyleView = viewAn 59 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 60 | } 61 | 62 | 63 | titleLabel?.text = state.titleText 64 | // secondImageView?.image = state.secondImage 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/GradientBlue/GradientBlueBasicButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class GradientBlueBasicButtonView: BtnView { 4 | 5 | @IBOutlet var mainView: ButtonClickStyleDesignView! 6 | @IBOutlet var mainH: NSLayoutConstraint! 7 | @IBOutlet var mainW: NSLayoutConstraint! 8 | @IBOutlet var fillView: ButtonClickStyleDesignView! 9 | @IBOutlet var groupView: ButtonClickStyleDesignView! 10 | @IBOutlet private weak var titleLabel: UILabel? 11 | 12 | @IBOutlet var backColor: UIView! 13 | 14 | override func fill(state: ButtonClick.State?) { 15 | guard let state = state else { return } 16 | self.state = state 17 | 18 | if let type = state.animationType { 19 | 20 | var origin: CGPoint = .init(x: 22, y: 16.5) 21 | var addViews: [UIView]? = [groupView] 22 | // if type == 2 { 23 | // addViews = [fillView] 24 | // } 25 | 26 | mainH.constant = 60 27 | mainW.constant = 158 28 | 29 | if (type == ButtonClick._Style.shadow.rawValue) || 30 | (type == ButtonClick._Style.shadowColor.rawValue ) 31 | { 32 | addViews = [mainView] 33 | mainView.fillColor = .clear 34 | origin = .init(x: 12, y: 6.5) 35 | mainH.constant = 80 36 | mainW.constant = 178 37 | mainView.setNeedsLayout() 38 | } else if (type == ButtonClick._Style.colorFlat.rawValue) { 39 | addViews = [mainView] 40 | } else if type == ButtonClick._Style.androidClickable.rawValue || 41 | type == ButtonClick._Style.androidClickableDark.rawValue { 42 | addViews = nil 43 | } else { 44 | mainView.fillColor = .clear 45 | mainView.setNeedsLayout() 46 | } 47 | 48 | 49 | if !state.addBackgrondColor { 50 | backgroundColor = .clear 51 | } 52 | backColor.isHidden = !state.addBackgrondColor 53 | 54 | 55 | let fr: CGRect = .init(x: origin.x, y: origin.y, width: mainW.constant, height: mainH.constant) 56 | let radius: CGFloat = 30 57 | let viewAn = ButtonClickStyleView( 58 | state: state, 59 | frame: fr, 60 | radius: radius, 61 | addViews: addViews 62 | ) 63 | viewAn.insertSubview(mainView, at: 0) 64 | viewAn.updateSubviews() 65 | 66 | addSubview(viewAn) 67 | viewAn.translatesAutoresizingMaskIntoConstraints = false 68 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 69 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 70 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 71 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 72 | 73 | self.btnClickStyleView?.removeFromSuperview() 74 | self.btnClickStyleView = viewAn 75 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 76 | } 77 | 78 | titleLabel?.text = state.titleText 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Neomorphism/NeomorphismButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class NeomorphismButtonView: BtnView { 4 | 5 | @IBOutlet var mainView: UIView! 6 | @IBOutlet var fillView: ButtonClickStyleDesignView! 7 | @IBOutlet private weak var titleLabel: UILabel? 8 | 9 | @IBOutlet var backColor: UIView! 10 | // MARK: Initialize 11 | 12 | override func awakeFromNib() { } 13 | @IBOutlet var cardView: ButtonClickStyleDesignView! 14 | 15 | override func fill(state: ButtonClick.State?) { 16 | guard let state = state else { return } 17 | self.state = state 18 | 19 | mainView.layer.cornerRadius = 14 20 | 21 | if let type = state.animationType { 22 | 23 | 24 | if !state.addBackgrondColor { 25 | backgroundColor = .clear 26 | cardView.fillColor = .white 27 | cardView.setNeedsLayout() 28 | } 29 | backColor.isHidden = !state.addBackgrondColor 30 | 31 | let fr: CGRect = .init(x: 25.5, y: 22.5, width: 151, height: 48) 32 | let radius: CGFloat = 14 33 | 34 | var addViews: [UIView]? = [mainView] 35 | // if (type == 2) || (type == 8) || (type == 9) || (type == 10) { 36 | // addViews = [fillView] 37 | // } 38 | 39 | if type == ButtonClick._Style.color.rawValue || 40 | (type == ButtonClick._Style.shadow.rawValue) || 41 | (type == ButtonClick._Style.shadowColor.rawValue ) 42 | // type == ButtonClick._Style.androidClickable.rawValue || 43 | // type == ButtonClick._Style.androidClickableDark.rawValue 44 | { 45 | addViews = [fillView] 46 | } else if type == ButtonClick._Style.androidClickable.rawValue || 47 | type == ButtonClick._Style.androidClickableDark.rawValue { 48 | addViews = nil 49 | } 50 | 51 | 52 | let viewAn = ButtonClickStyleView( 53 | state: state, 54 | frame: fr, 55 | radius: radius, 56 | addViews: addViews 57 | ) 58 | viewAn.insertSubview(mainView, at: 0) 59 | viewAn.updateSubviews() 60 | 61 | addSubview(viewAn) 62 | viewAn.translatesAutoresizingMaskIntoConstraints = false 63 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 64 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 65 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 66 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 67 | 68 | self.btnClickStyleView?.removeFromSuperview() 69 | self.btnClickStyleView = viewAn 70 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 71 | } 72 | 73 | titleLabel?.text = state.titleText 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Search/SearchButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | 4 | class SearchButtonView: BtnView { 5 | 6 | @IBOutlet var mainView: UIView! 7 | @IBOutlet private weak var titleLabel: UILabel? 8 | 9 | override func fill(state: ButtonClick.State?) { 10 | guard let state = state else { return } 11 | self.state = state 12 | 13 | 14 | if let _ = state.animationType { 15 | let fr: CGRect = .init(x: 17 , y: 22, width: 168, height: 49) 16 | let viewAn = ButtonClickStyleView( 17 | state: state, 18 | frame: fr, 19 | radius: 24 20 | ) 21 | viewAn.insertSubview(mainView, at: 0) 22 | viewAn.updateSubviews() 23 | 24 | addSubview(viewAn) 25 | viewAn.translatesAutoresizingMaskIntoConstraints = false 26 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 27 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 28 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 29 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 30 | 31 | self.btnClickStyleView?.removeFromSuperview() 32 | self.btnClickStyleView = viewAn 33 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 34 | } 35 | titleLabel?.text = state.titleText 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/Subscribe/SubscribeButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class SubscribeButtonView: BtnView { 4 | 5 | @IBOutlet var mainView: UIView! 6 | @IBOutlet private weak var titleLabel: UILabel? 7 | @IBOutlet private weak var secondImageView: UIImageView? 8 | 9 | 10 | @IBOutlet var backColor: ButtonClickStyleDesignView! 11 | @IBOutlet var shadowVieww: ButtonClickStyleDesignView! 12 | @IBOutlet var cardView: UIView! 13 | @IBOutlet var fillView: ButtonClickStyleDesignView! 14 | 15 | override func fill(state: ButtonClick.State?) { 16 | guard let state = state else { return } 17 | self.state = state 18 | 19 | if let type = state.animationType { 20 | 21 | var addViews: [UIView]? = [] 22 | if type == ButtonClick._Style.press.rawValue { 23 | addViews = [cardView, shadowVieww] 24 | } else if type == ButtonClick._Style.androidClickable.rawValue || 25 | type == ButtonClick._Style.androidClickableDark.rawValue { 26 | addViews = nil 27 | } else if type == ButtonClick._Style.color.rawValue { 28 | addViews = nil 29 | 30 | } else { 31 | addViews = [mainView] 32 | } 33 | 34 | 35 | if !state.addBackgrondColor { 36 | backgroundColor = .clear 37 | } 38 | backColor.isHidden = !state.addBackgrondColor 39 | 40 | 41 | let fr: CGRect = .init(x: 15 , y: 20.5, width: 172, height: 52) 42 | let viewAn = ButtonClickStyleView( 43 | state: state, 44 | frame: fr, 45 | radius: 26, 46 | addViews: addViews 47 | ) 48 | viewAn.insertSubview(mainView, at: 0) 49 | viewAn.updateSubviews() 50 | 51 | addSubview(viewAn) 52 | viewAn.translatesAutoresizingMaskIntoConstraints = false 53 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 54 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 55 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 56 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 57 | 58 | self.btnClickStyleView?.removeFromSuperview() 59 | self.btnClickStyleView = viewAn 60 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 61 | } 62 | titleLabel?.text = state.titleText 63 | // secondImageView?.image = state.secondImage 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/TestDemoBlur/TestDemoBlurButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | 4 | 5 | 6 | 7 | class TestDemoBlurButtonView: BtnView { 8 | 9 | @IBOutlet var shadowwView: ButtonClickStyleDesignView! 10 | @IBOutlet var mainView: ButtonClickStyleDesignView! 11 | @IBOutlet var groupView: ButtonClickStyleDesignView! 12 | @IBOutlet var mainH: NSLayoutConstraint! 13 | @IBOutlet var mainW: NSLayoutConstraint! 14 | @IBOutlet var fillView: ButtonClickStyleDesignView! 15 | @IBOutlet private weak var titleLabel: UILabel? 16 | 17 | override func fill(state: ButtonClick.State?) { 18 | guard let state = state else { return } 19 | self.state = state 20 | 21 | if let type = state.animationType { 22 | 23 | var fr: CGRect = .init(x: 50, y: 29, width: 140, height: 51) 24 | var addViews: [UIView]? = [groupView] 25 | 26 | 27 | mainH.constant = fr.size.height 28 | mainW.constant = fr.size.width 29 | 30 | if (type == ButtonClick._Style.shadow.rawValue) || 31 | (type == ButtonClick._Style.shadowColor.rawValue ) 32 | { 33 | addViews = [mainView] 34 | mainView.fillColor = .clear 35 | let sizee: CGFloat = 30 36 | 37 | // fr = .init(x: 40, y: 19, width: 160, height: 91 ) 38 | 39 | fr = .init(x: (fr.origin.x - sizee), y: (fr.origin.y - sizee), width: (fr.width + (sizee * 2)), height: (fr.height + (sizee * 2))) 40 | 41 | mainH.constant = fr.size.height 42 | mainW.constant = fr.size.width 43 | mainView.setNeedsLayout() 44 | 45 | // mainView.setNeedsLayout() 46 | } else if (type == ButtonClick._Style.colorFlat.rawValue) { 47 | 48 | addViews = [mainView] 49 | } else if type == ButtonClick._Style.androidClickable.rawValue || 50 | type == ButtonClick._Style.androidClickableDark.rawValue { 51 | addViews = [fillView] 52 | } else { 53 | mainView.fillColor = .clear 54 | mainView.setNeedsLayout() 55 | } 56 | 57 | 58 | 59 | let viewAn = ButtonClickStyleView( 60 | state: state, 61 | frame: fr, 62 | radius: 14, 63 | addViews: addViews 64 | ) 65 | viewAn.insertSubview(mainView, at: 0) 66 | viewAn.updateSubviews() 67 | 68 | 69 | addSubview(viewAn) 70 | viewAn.translatesAutoresizingMaskIntoConstraints = false 71 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 72 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 73 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 74 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 75 | 76 | self.btnClickStyleView?.removeFromSuperview() 77 | self.btnClickStyleView = viewAn 78 | 79 | var frr = mainView.frame 80 | frr.origin = .zero 81 | mainView.frame = frr 82 | } 83 | 84 | titleLabel?.text = state.titleText 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/TestDemoGradient/TestDemoGradientButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | 4 | 5 | 6 | 7 | class TestDemoGradientButtonView: BtnView { 8 | 9 | @IBOutlet var shadowwView: ButtonClickStyleDesignView! 10 | @IBOutlet var fillView: ButtonClickStyleDesignView! 11 | @IBOutlet var mainView: UIView! 12 | @IBOutlet private weak var titleLabel: UILabel? 13 | 14 | @IBOutlet var backColor: ButtonClickStyleDesignView! 15 | override func fill(state: ButtonClick.State?) { 16 | guard let state = state else { return } 17 | self.state = state 18 | 19 | if let type = state.animationType { 20 | 21 | 22 | var addViews: [UIView]? = nil 23 | if type == ButtonClick._Style.androidClickable.rawValue || 24 | type == ButtonClick._Style.androidClickableDark.rawValue { 25 | addViews = [fillView] 26 | } else if (type == ButtonClick._Style.color.rawValue) { 27 | addViews = [fillView] 28 | } 29 | 30 | 31 | let fr: CGRect = .init(x: 45, y: 20, width: 161, height: 58) 32 | let viewAn = ButtonClickStyleView( 33 | state: state, 34 | frame: fr, 35 | radius: 20, 36 | addViews: addViews 37 | ) 38 | viewAn.insertSubview(mainView, at: 0) 39 | viewAn.updateSubviews() 40 | 41 | if !state.addBackgrondColor { 42 | backgroundColor = .clear 43 | } 44 | backColor.isHidden = !state.addBackgrondColor 45 | 46 | addSubview(viewAn) 47 | viewAn.translatesAutoresizingMaskIntoConstraints = false 48 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 49 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 50 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 51 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 52 | 53 | self.btnClickStyleView?.removeFromSuperview() 54 | self.btnClickStyleView = viewAn 55 | 56 | var frr = mainView.frame 57 | frr.origin = .zero 58 | mainView.frame = frr 59 | } 60 | 61 | titleLabel?.text = state.titleText 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Button/TestDemoSquares/TestDemoSquaresButtonView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | 4 | 5 | 6 | 7 | class TestDemoSquaresButtonView: BtnView { 8 | 9 | @IBOutlet var mainView: UIView! 10 | 11 | @IBOutlet var firstView: ButtonClickStyleDesignView! 12 | override func fill(state: ButtonClick.State?) { 13 | guard let state = state else { return } 14 | self.state = state 15 | 16 | if let type = state.animationType { 17 | 18 | var addViews: [UIView]? = nil 19 | if type == ButtonClick._Style.androidClickable.rawValue || 20 | type == ButtonClick._Style.androidClickableDark.rawValue { 21 | addViews = [firstView] 22 | } 23 | 24 | 25 | let fr: CGRect = .init(x: 0, y: 0, width: 240, height: 93) 26 | let viewAn = ButtonClickStyleView( 27 | state: state, 28 | frame: fr, 29 | radius: 0, 30 | addViews: addViews 31 | ) 32 | viewAn.insertSubview(mainView, at: 0) 33 | viewAn.updateSubviews() 34 | 35 | 36 | addSubview(viewAn) 37 | viewAn.translatesAutoresizingMaskIntoConstraints = false 38 | viewAn.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 39 | viewAn.topAnchor.constraint(equalTo: self.topAnchor, constant: fr.origin.y).isActive = true 40 | viewAn.widthAnchor.constraint(equalToConstant: fr.width).isActive = true 41 | viewAn.heightAnchor.constraint(equalToConstant: fr.height).isActive = true 42 | 43 | self.btnClickStyleView?.removeFromSuperview() 44 | self.btnClickStyleView = viewAn 45 | var frr = mainView.frame;frr.origin = .zero;mainView.frame = frr 46 | } 47 | 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/Cell/ButtonListCell/ButtonListCell.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | // MARK: - State 4 | 5 | extension ButtonListItem { 6 | struct State { 7 | var buttonState: ButtonClick.State? 8 | var clickAnimType: ButtonClick.Full? 9 | var buttonType: Int? 10 | var titleText: String? 11 | var subtitleText: String? 12 | var text2: String? 13 | var text3: String? 14 | var text4: String? 15 | var handlers: Handlers = .init() 16 | } 17 | struct Handlers { 18 | var onClickAt: (()->(Void))? 19 | } 20 | } 21 | 22 | // MARK: - Item 23 | 24 | class ButtonListItem: TableAdapterItem { 25 | init(state: ButtonListItem.State) { 26 | let cellData = ButtonListCellData(state: state) 27 | super.init(cellClass: ButtonListCell.self, cellData: cellData) 28 | } 29 | } 30 | 31 | // MARK: - Data 32 | 33 | class ButtonListCellData: TableAdapterCellData { 34 | 35 | var state: ButtonListItem.State 36 | 37 | init(state: ButtonListItem.State) { 38 | self.state = state 39 | super.init() 40 | // self.cellClickCallback = state.handlers.onClickAt 41 | } 42 | 43 | override public func cellHeight() -> CGFloat { 44 | // let calcHeight = calculateLabel( 45 | // text: state.titleText, 46 | // padding: 16, 47 | // titleFont: SFProText.regular.size(.headline) 48 | // ) 49 | return Self.cHeight() 50 | } 51 | 52 | public static func cHeight() -> CGFloat { 53 | return 93.0 54 | } 55 | 56 | override public func canEditing() -> Bool { 57 | return editing 58 | } 59 | } 60 | 61 | // MARK: - Cell 62 | 63 | class ButtonListCell: TableAdapterCell { 64 | 65 | public var data: ButtonListCellData? 66 | 67 | @IBOutlet private weak var titleLabel: UILabel? 68 | @IBOutlet private weak var subtitleLabel: UILabel? 69 | @IBOutlet private weak var label2: UILabel? 70 | @IBOutlet private weak var label3: UILabel? 71 | @IBOutlet private weak var label4: UILabel? 72 | 73 | @IBOutlet var buttonClickView: JustPinkButtonView? 74 | @IBOutlet override var selectedView: UIView? { didSet { } } 75 | @IBOutlet var cardView: UIView? 76 | @IBOutlet var button: UIButton? 77 | 78 | var buttonsAdded: [BtnView] = [] 79 | var labelsAdded: [UILabel] = [] 80 | 81 | override func awakeFromNib() { 82 | separator(hide: true) 83 | // button?.tapHideAnimation( 84 | // view: cardView, 85 | // type: .alpha(0.5), 86 | // callback: { [weak self] type in 87 | // if type == .touchUpInside { 88 | // self?.data?.state.handlers.onClickAt?() 89 | // } 90 | // } 91 | // ) 92 | } 93 | 94 | 95 | override func fill(data: TableAdapterCellData?) { 96 | guard let data = data as? ButtonListCellData else { return } 97 | self.data = data 98 | guard let state = data.state.buttonState else { return } 99 | guard let clickAnimType = data.state.clickAnimType else { return } 100 | guard let buttonType = data.state.buttonType else { return } 101 | 102 | buttonClickView?.removeFromSuperview() 103 | 104 | // titleLabel?.text = data.state.titleText 105 | // subtitleLabel?.text = data.state.subtitleText 106 | // label2?.text = data.state.text2 107 | // label3?.text = data.state.text3 108 | // label4?.text = data.state.text4 109 | 110 | 111 | buttonsAdded.forEach { $0.removeFromSuperview() } 112 | buttonsAdded.removeAll() 113 | 114 | labelsAdded.forEach { $0.removeFromSuperview() } 115 | labelsAdded.removeAll() 116 | 117 | 118 | let child: BtnView? = ButtonClick.Buttons.newBtnView(buttonType) 119 | 120 | self.subtitleLabel?.text = ButtonClick.Buttons.allNameFull[buttonType] // .name 121 | self.titleLabel?.text = clickAnimType.base 122 | 123 | if let child = child { 124 | child.fill(state: state) 125 | child.frame = .init( 126 | x: 0, 127 | y: 0, 128 | width: 202, 129 | height: 93 130 | ) 131 | self.addSubview(child) 132 | buttonsAdded.append(child) 133 | } 134 | 135 | // let state: ButtonClick.State = getState() 136 | // buttonClickView.fill(state: state) 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/ScreenIPad/Test/TestViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | //MARK: - Test ViewController 4 | 5 | class TestViewController: StoryboardController { 6 | 7 | // @IBOutlet var allSubviewsSwitch: UISwitch? 8 | // @IBOutlet var counterTypeStepper: UIStepper? 9 | 10 | // @IBOutlet var buttonAnim1View: ButtonClickStyleView? 11 | // @IBOutlet var buttonAnim2View: ButtonClickStyleView? 12 | @IBOutlet var buttonAnim3View: ButtonClickStyleView? 13 | 14 | @IBOutlet var typeLabel: UILabel! 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | navigationItem.backBarButtonItem = UIBarButtonItem( 20 | title: "", 21 | style: .plain, 22 | target: nil, 23 | action: nil 24 | ) 25 | 26 | // title = "Test" 27 | 28 | update() 29 | } 30 | 31 | @IBAction func allSubviewsSwitchAction(_ sender: UISwitch) { 32 | update() 33 | } 34 | 35 | @IBAction func counterAction(_ sender: UIStepper) { 36 | update() 37 | } 38 | 39 | func update() { 40 | // let type: Int = Int(counterTypeStepper.value) 41 | // let allSubv: Bool = allSubviewsSwitch.isOn 42 | // 43 | // typeLabel.text = "\(ButtonClick.Style.allCases[type].str())" 44 | // 45 | // buttonAnim1View?.update(animationType: type, allSubviews: allSubv) 46 | // buttonAnim2View?.update(animationType: type, allSubviews: allSubv) 47 | // buttonAnim3View?.update(animationType: type, allSubviews: true) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/ScreenIPad/Test2/Test2ViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/ScreenIPad/Test2/Test2ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | //MARK: - Test ViewController 4 | 5 | class Test2ViewController: StoryboardController { 6 | 7 | // @IBOutlet var allSubviewsSwitch: UISwitch? 8 | @IBOutlet var buttonAnim3View: ButtonClickStyleView? 9 | 10 | @IBOutlet var typeLabel: UILabel! 11 | 12 | override func viewDidLoad() { 13 | super.viewDidLoad() 14 | 15 | navigationItem.backBarButtonItem = UIBarButtonItem( 16 | title: "", 17 | style: .plain, 18 | target: nil, 19 | action: nil 20 | ) 21 | 22 | // title = "Test" 23 | 24 | update() 25 | } 26 | 27 | @IBAction func allSubviewsSwitchAction(_ sender: UISwitch) { 28 | update() 29 | } 30 | 31 | @IBAction func counterAction(_ sender: UIStepper) { 32 | update() 33 | } 34 | 35 | func update() { 36 | // let type: Int = Int(counterTypeStepper.value) 37 | // let allSubv: Bool = allSubviewsSwitch.isOn 38 | // 39 | // typeLabel.text = "\(ButtonClick.Style.allCases[type].str())" 40 | // 41 | // buttonAnim1View?.update(animationType: type, allSubviews: allSubv) 42 | // buttonAnim2View?.update(animationType: type, allSubviews: allSubv) 43 | // buttonAnim3View?.update(animationType: type, allSubviews: true) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/ScreenIPhone/ButtonProgram/ButtonProgramViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/UI/ScreenIPhone/ButtonProgram/ButtonProgramViewController.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | import UIKit 4 | 5 | //MARK: - ButtonProgram ViewController 6 | 7 | 8 | class ButtonProgramViewController: StoryboardController { 9 | 10 | var prgmButtonClickStyleView: ButtonClickStyleView? 11 | var prgmFigureView: UIView! 12 | var prgmRectangleView: UIView! 13 | 14 | override func viewDidAppear(_ animated: Bool) { 15 | super.viewDidAppear(animated) 16 | 17 | 18 | } 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | 23 | title = "Init Programmatically" 24 | 25 | 26 | createProgrammaticaly(type: 2) { event in 27 | 28 | } 29 | 30 | self.prgmButtonClickStyleView?.update(animationType: 1, allSubviews: true) 31 | 32 | self.prgmButtonClickStyleView?.click = { event in 33 | 34 | } 35 | } 36 | 37 | 38 | func createProgrammaticaly(type: Int = 0, clickAt: ButtonClick.ClosureEvent? = nil) { 39 | 40 | let figureView = UIView(frame: .init(x: 50, y: 10, width: 80, height: 40)) 41 | figureView.backgroundColor = .green 42 | figureView.layer.cornerRadius = 20 43 | self.prgmFigureView = figureView 44 | 45 | let rectangleView = UIView(frame: .init(x: 15, y: 50, width: 50, height: 60)) 46 | rectangleView.backgroundColor = .systemPurple 47 | self.prgmRectangleView = rectangleView 48 | 49 | let state = ButtonClick.State( 50 | titleText: "Hello", 51 | allSubviews: true, 52 | animationType: type, 53 | animationTypeValue: 0.5, 54 | animationDuration: nil, 55 | new: false, 56 | color: UIColor.green, 57 | startClick: true, 58 | debugButtonShow: false, 59 | addBackgrondColor: true 60 | ) 61 | 62 | let btnView = ButtonClickStyleView( 63 | state: state, 64 | frame: .init(x: 0, y: 200, width: 240, height: 128), 65 | radius: 20, 66 | addViews: [figureView], 67 | click: { event in 68 | 69 | } 70 | ) 71 | btnView.backgroundColor = .yellow.withAlphaComponent(0.5) 72 | 73 | btnView.updateSubviews() 74 | self.prgmButtonClickStyleView = btnView 75 | 76 | btnView.addSubview(figureView) 77 | btnView.addSubview(rectangleView) 78 | self.view.addSubview(btnView) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/LoadNib/BtnView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BtnView.swift 3 | // ButtonCustomButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 26.03.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class BtnView: XibView { 11 | 12 | // MARK: Properties 13 | 14 | var state: ButtonClick.State? 15 | var btnClickStyleView: ButtonClickStyleView? 16 | 17 | func fill(state: ButtonClick.State?) { 18 | 19 | guard let state = state else { return } 20 | self.state = state 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/LoadNib/StoryboardController.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | class StoryboardController: UIViewController { 5 | 6 | class func instantiate() -> UIViewController { 7 | return fromStoryboardController() 8 | } 9 | 10 | class func fromStoryboardController() -> UIViewController { 11 | let className = String(describing: self) 12 | let storyboard = UIStoryboard.init(name: className, bundle: nil) 13 | return storyboard.instantiateViewController(withIdentifier: className) 14 | } 15 | } 16 | 17 | extension StoryboardController: UIGestureRecognizerDelegate { 18 | 19 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 20 | shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { 21 | return true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/LoadNib/XibView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XibView.swift 3 | // PatternsSwift 4 | // 5 | // Created by mrustaa on 19/04/2020. 6 | // Copyright © 2020 mrustaa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class XibView: UIView { 12 | 13 | // MARK: - Properties 14 | 15 | public weak var contentView: UIView? 16 | 17 | private (set) var activated = false 18 | 19 | // MARK: - Initialize 20 | 21 | required public init?(coder aDecoder: NSCoder) { 22 | super.init(coder: aDecoder) 23 | contentView = fromNib() 24 | setup() 25 | } 26 | 27 | public init() { 28 | super.init(frame: .zero) 29 | contentView = fromNib() 30 | frame = contentView?.frame ?? frame 31 | setup() 32 | } 33 | 34 | 35 | func activate() { 36 | guard !activated else { return } 37 | updateConstraints() 38 | activated = true 39 | } 40 | 41 | // MARK: - Load Nib 42 | 43 | func fromNibWithoutConstraints() -> UIView? { 44 | guard let contentView = Bundle(for: type(of: self)).loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)?.first as? UIView else { 45 | return nil 46 | } 47 | 48 | contentView.translatesAutoresizingMaskIntoConstraints = false 49 | addSubview(contentView) 50 | 51 | return contentView 52 | } 53 | 54 | func fromNib() -> UIView? { 55 | guard let contentView = fromNibWithoutConstraints() else { return nil } 56 | 57 | contentView.backgroundColor = .clear 58 | contentView.leftAnchor.constraint(equalTo: super.leftAnchor).isActive = true 59 | contentView.rightAnchor.constraint(equalTo: super.rightAnchor).isActive = true 60 | contentView.topAnchor.constraint(equalTo: super.topAnchor).isActive = true 61 | contentView.bottomAnchor.constraint(equalTo: super.bottomAnchor).isActive = true 62 | 63 | return contentView 64 | } 65 | 66 | } 67 | 68 | extension XibView: XibViewInitialization { 69 | func setup() {} 70 | } 71 | 72 | @objc 73 | protocol XibViewInitialization { 74 | func setup() 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/Cell/TableAdapterCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterCell.swift 3 | // PatternsSwift 4 | // 5 | // Created by mrustaa on 17/04/2020. 6 | // Copyright © 2020 mrustaa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class TableAdapterCell: UITableViewCell { 12 | 13 | open var didScrollCallback: (() -> ())? = nil 14 | open var cellClickCallback: ((UIControl.Event) -> ())? 15 | 16 | @IBInspectable var hideAnimation: Bool = false 17 | open var selectedView: UIView? 18 | 19 | public var cellData: TableAdapterCellData? 20 | 21 | public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 22 | super.init(style: style, reuseIdentifier: reuseIdentifier) 23 | setup() 24 | } 25 | 26 | public required init?(coder aDecoder: NSCoder) { 27 | super.init(coder: aDecoder) 28 | setup() 29 | } 30 | 31 | public func setup() {} 32 | 33 | open func fill(data: TableAdapterCellData?) { 34 | guard let data = data else { return } 35 | 36 | self.hideAnimation = data.touchAnimationHide 37 | separator(hide: !data.separatorVisible) 38 | } 39 | 40 | let selAlpha: CGFloat = 0.2 41 | 42 | open override func setSelected(_ selected: Bool, animated: Bool) { 43 | 44 | if selected { 45 | cellData?.cellClickCallback?() 46 | cellClickCallback?(.touchUpInside) 47 | } 48 | 49 | if hideAnimation { 50 | 51 | if selected { 52 | alpha = 0.5 53 | 54 | UIView.animate(withDuration: 0.45, animations: { 55 | self.alpha = 1 56 | }) 57 | } else { 58 | alpha = 1 59 | } 60 | 61 | } else { 62 | if let selectedView = selectedView { 63 | if selected { 64 | selectedView.alpha = selAlpha 65 | UIView.animate(withDuration: 0.45, animations: { 66 | selectedView.alpha = 0.0 67 | }) 68 | } else { 69 | selectedView.alpha = 0.0 70 | } 71 | } else { 72 | super.setSelected(selected, animated: animated) 73 | } 74 | } 75 | 76 | } 77 | 78 | open override func setHighlighted(_ highlighted: Bool, animated: Bool) { 79 | 80 | cellClickCallback?(.touchDown) 81 | 82 | if hideAnimation { 83 | if highlighted { 84 | UIView.animate(withDuration: 0.1, animations: { 85 | self.alpha = 0.5 86 | }) 87 | } else { 88 | UIView.animate(withDuration: 0.45, animations: { 89 | self.alpha = 1 90 | }) 91 | } 92 | } else { 93 | if let selectedView = selectedView { 94 | if highlighted { 95 | UIView.animate(withDuration: 0.1, animations: { 96 | selectedView.alpha = self.selAlpha 97 | }) 98 | } else { 99 | UIView.animate(withDuration: 0.45, animations: { 100 | selectedView.alpha = 0.0 101 | }) 102 | } 103 | } else { 104 | super.setHighlighted(highlighted, animated: animated) 105 | } 106 | } 107 | 108 | } 109 | 110 | 111 | } 112 | 113 | extension UITableViewCell { 114 | 115 | func separator(hide: Bool) { 116 | separatorInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: hide ? CGFloat(Double.greatestFiniteMagnitude) : 0.0) 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/Cell/TableAdapterCellData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterCellData.swift 3 | // PatternsSwift 4 | // 5 | // Created by mrustaa on 17/04/2020. 6 | // Copyright © 2020 mrustaa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | open class TableAdapterCellData: NSObject { 13 | 14 | // MARK: Properties 15 | 16 | open var separatorVisible: Bool = false 17 | open var touchAnimationHide: Bool = false 18 | open var editing: Bool = false 19 | open var cellClickCallback: (() -> ())? 20 | 21 | // MARK: Init 22 | 23 | init(_ separator: Bool? = false, 24 | _ touchAnimationHide: Bool? = false, 25 | _ editing: Bool? = false, 26 | _ clickCallback: (() -> ())? = nil) { 27 | 28 | self.separatorVisible = separator ?? false 29 | self.touchAnimationHide = touchAnimationHide ?? false 30 | self.editing = editing ?? false 31 | self.cellClickCallback = clickCallback 32 | } 33 | 34 | // MARK: Methods 35 | 36 | open func calculateLabel(text: String?, font: UIFont? = nil, x: CGFloat = 16.0) -> CGFloat { 37 | type(of: self).classCalculateLabel(text: text, font: font, x: x).height 38 | } 39 | 40 | open class func classCalculateLabel(text: String?, font: UIFont? = nil, lines: Int = 99, x: CGFloat = 16.0) -> CGRect { 41 | if let text = text { 42 | let titleLabel = UILabel(frame: CGRect(x: x, y: 0, width: (UIScreen.main.bounds.size.width - (x * 2)), height: 10)) 43 | titleLabel.tag = 0 44 | titleLabel.font = font ?? UIFont.systemFont(ofSize: 18) 45 | titleLabel.text = text 46 | titleLabel.numberOfLines = lines 47 | titleLabel.textAlignment = .center 48 | titleLabel.sizeToFit() 49 | 50 | return titleLabel.frame 51 | } else { 52 | return .zero 53 | } 54 | } 55 | 56 | 57 | open func calculateLabelClassic( 58 | text: String? 59 | ) -> CGFloat { 60 | return type(of: self).calculateLabelCls(text: text, padding: 16, titleFont: UIFont.systemFont(ofSize: 18)) 61 | } 62 | 63 | open func calculateLabel( 64 | text: String?, 65 | padding: CGFloat? = nil, 66 | percent: CGFloat? = nil, 67 | fixedWidth: CGFloat? = nil, 68 | titleFont: UIFont? = nil 69 | ) -> CGFloat { 70 | return type(of: self).calculateLabelCls(text: text, padding: padding, titleFont: titleFont) 71 | } 72 | 73 | class func calculateLabelCls( 74 | text: String?, 75 | padding: CGFloat? = nil, 76 | percent: CGFloat? = nil, 77 | fixedWidth: CGFloat? = nil, 78 | titleFont: UIFont? = nil, 79 | numberOfLines: Int = 99 80 | ) -> CGFloat { 81 | 82 | if let text = text { 83 | 84 | var width: CGFloat = 0 85 | if let padding = padding { 86 | width = (UIScreen.main.bounds.size.width - (padding * 2)) 87 | } 88 | if let percent = percent { 89 | width = (UIScreen.main.bounds.size.width * percent) 90 | } 91 | if let fixedWidth = fixedWidth { 92 | width = fixedWidth 93 | } 94 | 95 | let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: 10)) 96 | titleLabel.tag = 0 97 | titleLabel.font = titleFont ?? UIFont.systemFont(ofSize: 18) 98 | titleLabel.text = text 99 | titleLabel.numberOfLines = numberOfLines 100 | titleLabel.textAlignment = .center 101 | titleLabel.sizeToFit() 102 | 103 | return titleLabel.frame.height 104 | } else { 105 | return 0 106 | } 107 | } 108 | 109 | open func cellHeight() -> CGFloat { 110 | return UITableView.automaticDimension 111 | } 112 | 113 | open func canEditing() -> Bool { 114 | return false 115 | } 116 | 117 | open func equals(compareTo data: TableAdapterCellData) -> Bool { 118 | return false 119 | } 120 | 121 | open func dataStr() -> String { 122 | return "" 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/Cell/TableAdapterItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterItem.swift 3 | // PatternsSwift 4 | // 5 | // Created by mrustaa on 17/04/2020. 6 | // Copyright © 2020 mrustaa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class TableAdapterItem: NSObject { 12 | 13 | enum SelectedanimationType { 14 | case button, cell 15 | } 16 | 17 | // MARK: Properties 18 | 19 | public let cellClass: AnyClass 20 | public let cellData: TableAdapterCellData? 21 | 22 | // MARK: Init 23 | 24 | public init(cellClass: AnyClass, cellData: TableAdapterCellData? = nil) { 25 | self.cellClass = cellClass 26 | self.cellData = cellData 27 | } 28 | 29 | // MARK: Methods 30 | 31 | public var cellReuseIdentifier: String { 32 | return String(describing: cellClass) 33 | } 34 | 35 | public func height() -> CGFloat { 36 | return cellData?.cellHeight() ?? UITableView.automaticDimension 37 | } 38 | 39 | public func canEditing() -> Bool { 40 | return cellData?.canEditing() ?? false 41 | } 42 | public func equals(compareTo item: TableAdapterItem) -> Bool { 43 | guard let itemData = item.cellData, 44 | let cellData = self.cellData else { return false } 45 | return cellData.equals(compareTo: itemData) 46 | } 47 | 48 | public func search(toArray: [TableAdapterItem]) -> Int? { 49 | for i in 0.. ())? = nil) { 20 | 21 | let cellData = TitleTextCellData(title, subtitle, clss, separator, touchAnimationHide, editing, clickCallback) 22 | 23 | super.init(cellClass: TitleTextCell.self, cellData: cellData) 24 | } 25 | 26 | 27 | init(title: String? = nil, 28 | subtitle: String? = nil, 29 | clickCallback: (() -> ())? = nil) { 30 | 31 | let cellData = TitleTextCellData(title, subtitle, nil, false, false, false, clickCallback) 32 | 33 | super.init(cellClass: TitleTextCell.self, cellData: cellData) 34 | } 35 | } 36 | 37 | // MARK: - Data 38 | 39 | class TitleTextCellData: TableAdapterCellData { 40 | 41 | // MARK: Properties 42 | 43 | var title: String? 44 | var subtitle: String? 45 | 46 | var clss: AnyClass? 47 | 48 | // MARK: Inits 49 | 50 | init(_ title: String? = nil, 51 | _ subtitle: String? = nil, 52 | _ clss: AnyClass? = nil, 53 | _ separator: Bool, 54 | _ touchAnimationHide: Bool, 55 | _ editing: Bool, 56 | _ clickCallback: (() -> ())?) { 57 | 58 | self.title = title 59 | self.subtitle = subtitle 60 | 61 | self.clss = clss 62 | 63 | super.init(separator, touchAnimationHide, editing, clickCallback) 64 | } 65 | 66 | override public func cellHeight() -> CGFloat { 67 | return title != nil ? 64 : 44 68 | } 69 | 70 | override public func canEditing() -> Bool { 71 | return editing 72 | } 73 | } 74 | 75 | // MARK: - Cell 76 | 77 | class TitleTextCell: TableAdapterCell { 78 | 79 | // MARK: Properties 80 | 81 | public var data: TitleTextCellData? 82 | 83 | // MARK: Outlets 84 | 85 | @IBOutlet override var selectedView: UIView? { didSet { } } 86 | 87 | @IBOutlet private weak var titleLabel: UILabel? 88 | @IBOutlet private weak var subtitleLabel: UILabel? 89 | 90 | @IBOutlet private weak var separatorView: UIView? 91 | @IBOutlet private weak var separatorHeightConstraint: NSLayoutConstraint? 92 | 93 | // MARK: Initialize 94 | 95 | override func awakeFromNib() { 96 | separatorView?.backgroundColor = .clear 97 | separatorHeightConstraint?.constant = 0.5 98 | } 99 | 100 | override func fill(data: TableAdapterCellData?) { 101 | guard let data = data as? TitleTextCellData else { return } 102 | self.data = data 103 | 104 | let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) 105 | view.backgroundColor = .green 106 | editingAccessoryView = view 107 | 108 | self.hideAnimation = data.touchAnimationHide 109 | 110 | titleLabel?.text = data.title 111 | subtitleLabel?.text = data.subtitle 112 | 113 | if let clss = data.clss { 114 | subtitleLabel?.text = String(describing: type(of: clss)) 115 | } else { 116 | subtitleLabel?.text = data.subtitle 117 | } 118 | 119 | separatorView?.isHidden = !data.separatorVisible 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView+AddGradient.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterView+AddGradient.swift 3 | // PlusBank 4 | // 5 | // Created by Рустам Мотыгуллин on 05.06.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | private let gradientTopTag = 15125 11 | private let gradientBottomTag = 15126 12 | 13 | extension TableAdapterView { 14 | 15 | public func addGradientEdges(color: UIColor, top: CGFloat?, bottom: CGFloat?) { 16 | addGradientWhite(table: self, color: color, top: top, bottom: bottom) 17 | } 18 | } 19 | 20 | extension UIView { 21 | 22 | public func addGradientWhite(table: TableAdapterView, color: UIColor, top: CGFloat?, bottom: CGFloat?) { // .background 50 23 | 24 | let width: CGFloat = table.frame.width 25 | 26 | let topView = viewWithTag(gradientTopTag) 27 | if let height = top { 28 | if topView == nil { 29 | let topView = UIView(frame: CGRect(x: 0, y: table.frame.origin.y, width: width, height: height)) 30 | topView.tag = gradientTopTag 31 | // _ = topView.addG( 32 | // gradient: color.withAlphaComponent(1), 33 | // color2: color.withAlphaComponent(0), 34 | // pointStart: .zero, 35 | // pointEnd: .init(x: 0, y: 1), 36 | // cornerRadius: 0 37 | // ) 38 | 39 | addSubview(topView) 40 | } 41 | } else { 42 | topView?.removeFromSuperview() 43 | } 44 | 45 | let bottomView = viewWithTag(gradientBottomTag) 46 | if let height = top { 47 | if bottomView == nil { 48 | let bottomView = UIView(frame: CGRect(x: 0, y: table.frame.height - height, width: width, height: height)) 49 | bottomView.tag = gradientBottomTag 50 | // _ = bottomView.add( 51 | // gradient: color.withAlphaComponent(0), 52 | // color2: color.withAlphaComponent(1), 53 | // pointStart: .zero, 54 | // pointEnd: .init(x: 0, y: 1), 55 | // cornerRadius: 0 56 | // ) 57 | 58 | addSubview(bottomView) 59 | } 60 | } else { 61 | bottomView?.removeFromSuperview() 62 | } 63 | } 64 | } 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView+CallbackTypes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterTypes.swift 3 | // PatternsSwift 4 | // 5 | // Created by mrustaa on 21/04/2020. 6 | // Copyright © 2020 mrustaa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public typealias TableAdapterCountCallback = ()-> Int 12 | public typealias TableAdapterCellIndexCallback = (_ index: Int) -> UITableViewCell 13 | public typealias TableAdapterHeightIndexCallback = (_ index: Int) -> CGFloat 14 | public typealias TableAdapterSelectIndexCallback = (_ index: Int) -> () 15 | public typealias TableAdapterDidScrollCallback = () -> () 16 | public typealias TableAdapterDeleteIndexCallback = (_ index: Int) -> () 17 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView+DataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterView+DataSource.swift 3 | // PlusBank 4 | // 5 | // Created by Рустам Мотыгуллин on 05.06.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: - DataSource 11 | 12 | extension TableAdapterView: UITableViewDataSource { 13 | 14 | /// count 15 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 16 | if !items.isEmpty { 17 | return items.count 18 | } 19 | if let countCallback = countCallback { 20 | return countCallback() 21 | } 22 | return 0 23 | } 24 | 25 | /// cell 26 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 27 | if !items.isEmpty { 28 | let item = items[indexPath.row] 29 | let cell = cellAt(indexPath) 30 | cell?.fill(data: item.cellData) 31 | return cell ?? UITableViewCell() 32 | } 33 | if let cellIndexCallback = cellIndexCallback { 34 | return cellIndexCallback(indexPath.row) 35 | } 36 | return UITableViewCell() 37 | } 38 | 39 | 40 | public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 41 | if !items.isEmpty { 42 | let item: TableAdapterItem = items[indexPath.row] 43 | return item.canEditing() 44 | } 45 | return false 46 | } 47 | 48 | public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 49 | 50 | if editingStyle == .delete { 51 | items.remove(at: indexPath.row) 52 | self.beginUpdates() 53 | self.deleteRows(at: [indexPath], with: .automatic) 54 | self.endUpdates() 55 | 56 | deleteIndexCallback?(indexPath.row) 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView+Delegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterView+Delegate.swift 3 | // PlusBank 4 | // 5 | // Created by Рустам Мотыгуллин on 05.06.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: - Delegate 11 | 12 | extension TableAdapterView: UITableViewDelegate { 13 | 14 | /// height 15 | public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 16 | if !items.isEmpty { 17 | return items[indexPath.row].height() 18 | } 19 | if let heightIndexCallback = heightIndexCallback { 20 | return heightIndexCallback(indexPath.row) 21 | } 22 | return 0 23 | } 24 | 25 | /// select 26 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 27 | tableView.deselectRow(at: indexPath, animated: true) 28 | selectIndexCallback?(indexPath.row) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView+ScrollDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterView+ScrollDelegate.swift 3 | // PlusBank 4 | // 5 | // Created by Рустам Мотыгуллин on 05.06.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | extension TableAdapterView: UIScrollViewDelegate { 11 | 12 | public func scrollViewDidScroll(_ scrollView: UIScrollView) { 13 | didScrollCallback?() 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView+Set.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterView+Set.swift 3 | // PlusBank 4 | // 5 | // Created by Рустам Мотыгуллин on 05.06.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | extension TableAdapterView { 11 | 12 | // MARK: Set Items 13 | 14 | public func set(items: [TableAdapterItem], animated: Bool = false, reload: Bool = true) { 15 | self.clear() 16 | items.forEach { 17 | self.unsafeAdd(item: $0) 18 | } 19 | if reload { reloadData(animated: animated) } 20 | } 21 | 22 | // MARK: - Set Rows 23 | 24 | public func set(rows items: [TableAdapterItem], with animation: UITableView.RowAnimation = .fade) { 25 | _ = setFull(rows: items, with: animation) 26 | } 27 | 28 | // MARK: Reload Data 29 | 30 | public func reloadData(animated: Bool = false) { 31 | animated 32 | ? reloadSections(IndexSet(integer: 0), with: .automatic) 33 | : reloadData() 34 | } 35 | 36 | // MARK: Clear 37 | 38 | public func clear() { 39 | items.removeAll() 40 | } 41 | 42 | // MARK: Scroll To Top 43 | 44 | public func scrollToTop() { 45 | self.setContentOffset(.zero, animated: true) 46 | } 47 | 48 | 49 | func scrollToBottom(){ 50 | 51 | DispatchQueue.main.async { 52 | let indexPath = IndexPath( 53 | row: self.numberOfRows(inSection: self.numberOfSections-1) - 1, 54 | section: self.numberOfSections - 1) 55 | if self.hasRowAtIndexPath(indexPath: indexPath) { 56 | self.scrollToRow(at: indexPath, at: .bottom, animated: true) 57 | } 58 | } 59 | } 60 | 61 | func hasRowAtIndexPath(indexPath: IndexPath) -> Bool { 62 | return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section) 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView+UpdateRows.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterView+UpdateRows.swift 3 | // PlusBank 4 | // 5 | // Created by Рустам Мотыгуллин on 31.05.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | extension TableAdapterView { 11 | 12 | // MARK: - Set Rows 13 | 14 | public func setFull(rows items: [TableAdapterItem], with animation: UITableView.RowAnimation = .fade) -> (insert: [IndexPath], delete: [IndexPath]) { 15 | 16 | let newItems = items 17 | let oldItems = self.items 18 | 19 | set(items: items, animated: false, reload: false) 20 | 21 | var insertRows: [IndexPath] = [] 22 | var deleteRows: [IndexPath] = [] 23 | 24 | var i = 0 25 | for old in oldItems { 26 | 27 | let findIndex = old.search(toArray: newItems) 28 | if findIndex == nil { 29 | deleteRows.append( IndexPath(row: i, section: 0) ) 30 | } 31 | i += 1 32 | } 33 | 34 | i = 0 35 | for new in newItems { 36 | let findIndex = new.search(toArray: oldItems) 37 | if findIndex == nil { 38 | insertRows.append( IndexPath(row: i, section: 0) ) 39 | } 40 | i += 1 41 | } 42 | 43 | let delete = (0 < deleteRows.count) 44 | let insert = (0 < insertRows.count) 45 | 46 | if (delete && insert) { 47 | self.reloadSections(IndexSet(integersIn: 0...0), with: animation) 48 | } else { 49 | if delete { 50 | self.deleteRows(at: deleteRows, with: animation) 51 | } else if insert { 52 | self.insertRows(at: insertRows, with: animation) 53 | } 54 | } 55 | 56 | return (insertRows, deleteRows) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Example/ButtonClickStyle/Utils/TableAdapterView/TableAdapterView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableAdapterView.swift 3 | // PatternsSwift 4 | // 5 | // Created by mrustaa on 16/04/2020. 6 | // Copyright © 2020 mrustaa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class TableAdapterView: UITableView { 12 | 13 | @IBInspectable var separatorClr: UIColor? 14 | 15 | // MARK: Callbacks 16 | 17 | public var countCallback: TableAdapterCountCallback? 18 | public var cellIndexCallback: TableAdapterCellIndexCallback? 19 | public var heightIndexCallback: TableAdapterHeightIndexCallback? 20 | public var selectIndexCallback: TableAdapterSelectIndexCallback? 21 | public var deleteIndexCallback: TableAdapterDeleteIndexCallback? 22 | public var didScrollCallback: TableAdapterDidScrollCallback? 23 | public var touchBeganCallback: (() -> ())? 24 | public var didRefreshCallback: (() -> ())? 25 | 26 | var canEditing: Bool = false 27 | 28 | public var items: [TableAdapterItem] = [] 29 | 30 | // MARK: - Init 31 | 32 | required public init?(coder: NSCoder) { 33 | super.init(coder: coder) 34 | update() 35 | } 36 | 37 | public override init(frame: CGRect, style: UITableView.Style) { 38 | super.init(frame: frame, style: style) 39 | update() 40 | } 41 | 42 | open override func draw(_ rect: CGRect) { 43 | if let color = separatorClr { 44 | separatorColor = color 45 | } 46 | } 47 | 48 | public func update() { 49 | delegate = self 50 | dataSource = self 51 | 52 | tableFooterView = UIView() 53 | backgroundColor = .clear 54 | } 55 | 56 | // MARK: Touches Began Event 57 | 58 | open override func touchesBegan(_ touches: Set, with event: UIEvent?) { 59 | super.touchesBegan(touches, with: event) 60 | 61 | touchBeganCallback?() 62 | } 63 | 64 | // MARK: Bussines Logic 65 | 66 | public func unsafeAdd(item: TableAdapterItem) { 67 | items.append(item) 68 | registerNibIfNeeded(for: item) 69 | } 70 | 71 | public func registerNibIfNeeded(for item: TableAdapterItem) { 72 | let nib = UINib(nibName: item.cellReuseIdentifier, bundle: nil) 73 | self.register(nib, forCellReuseIdentifier: item.cellReuseIdentifier) 74 | } 75 | 76 | public func cellAt(_ indexPath: IndexPath) -> TableAdapterCell? { 77 | let item = items[indexPath.row] 78 | let cellIdentifier = item.cellReuseIdentifier 79 | let cell = self.dequeueReusableCell(withIdentifier: cellIdentifier) as? TableAdapterCell 80 | cell?.cellData = item.cellData 81 | return cell 82 | } 83 | 84 | func searchTable(cellClass: AnyClass) -> [(indxPath: IndexPath, cell: TableAdapterCell)]? { 85 | var index = 0 86 | var findItems: [(indxPath: IndexPath, cell: TableAdapterCell)] = [] 87 | for cell in self.visibleCells { 88 | if let adCell = cell as? TableAdapterCell { 89 | if type(of: adCell) == cellClass { 90 | let path = IndexPath(row: index, section: 0) 91 | findItems.append((path, adCell)) 92 | } 93 | } 94 | index += 1 95 | } 96 | if findItems.isEmpty { 97 | return nil 98 | } 99 | return findItems 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | platform :ios, '9.0' 4 | 5 | target 'ButtonClickStyle_Example' do 6 | pod 'ButtonClickStyle', :path => '../' 7 | 8 | target 'ButtonClickStyle_Tests' do 9 | inherit! :search_paths 10 | 11 | pod 'FBSnapshotTestCase' , '~> 2.1.4' 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ButtonClickStyle (0.1.0) 3 | - FBSnapshotTestCase (2.1.4): 4 | - FBSnapshotTestCase/SwiftSupport (= 2.1.4) 5 | - FBSnapshotTestCase/Core (2.1.4) 6 | - FBSnapshotTestCase/SwiftSupport (2.1.4): 7 | - FBSnapshotTestCase/Core 8 | 9 | DEPENDENCIES: 10 | - ButtonClickStyle (from `../`) 11 | - FBSnapshotTestCase (~> 2.1.4) 12 | 13 | SPEC REPOS: 14 | trunk: 15 | - FBSnapshotTestCase 16 | 17 | EXTERNAL SOURCES: 18 | ButtonClickStyle: 19 | :path: "../" 20 | 21 | SPEC CHECKSUMS: 22 | ButtonClickStyle: 301678baae9fa299dcb47f256eeb57876a9afc94 23 | FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a 24 | 25 | PODFILE CHECKSUM: c55351212e74dce90f1f9cb6abd7e864c2307765 26 | 27 | COCOAPODS: 1.11.2 28 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIApplication+StrictKeyWindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | @interface UIApplication (StrictKeyWindow) 14 | 15 | /** 16 | @return The receiver's @c keyWindow. Raises an assertion if @c nil. 17 | */ 18 | - (UIWindow *)fb_strictKeyWindow; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIApplication+StrictKeyWindow.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | @implementation UIApplication (StrictKeyWindow) 14 | 15 | - (UIWindow *)fb_strictKeyWindow 16 | { 17 | UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; 18 | if (!keyWindow) { 19 | [NSException raise:@"FBSnapshotTestCaseNilKeyWindowException" 20 | format:@"Snapshot tests must be hosted by an application with a key window. Please ensure your test" 21 | " host sets up a key window at launch (either via storyboards or programmatically) and doesn't" 22 | " do anything to remove it while snapshot tests are running."]; 23 | } 24 | return keyWindow; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gabriel Handford on 3/1/09. 3 | // Copyright 2009-2013. All rights reserved. 4 | // Created by John Boiles on 10/20/11. 5 | // Copyright (c) 2011. All rights reserved 6 | // Modified by Felix Schulze on 2/11/13. 7 | // Copyright 2013. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | #import 32 | 33 | @interface UIImage (Compare) 34 | 35 | - (BOOL)fb_compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gabriel Handford on 3/1/09. 3 | // Copyright 2009-2013. All rights reserved. 4 | // Created by John Boiles on 10/20/11. 5 | // Copyright (c) 2011. All rights reserved 6 | // Modified by Felix Schulze on 2/11/13. 7 | // Copyright 2013. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | #import 32 | 33 | @interface UIImage (Diff) 34 | 35 | - (UIImage *)fb_diffWithImage:(UIImage *)image; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gabriel Handford on 3/1/09. 3 | // Copyright 2009-2013. All rights reserved. 4 | // Created by John Boiles on 10/20/11. 5 | // Copyright (c) 2011. All rights reserved 6 | // Modified by Felix Schulze on 2/11/13. 7 | // Copyright 2013. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | #import 32 | 33 | @implementation UIImage (Diff) 34 | 35 | - (UIImage *)fb_diffWithImage:(UIImage *)image 36 | { 37 | if (!image) { 38 | return nil; 39 | } 40 | CGSize imageSize = CGSizeMake(MAX(self.size.width, image.size.width), MAX(self.size.height, image.size.height)); 41 | UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0); 42 | CGContextRef context = UIGraphicsGetCurrentContext(); 43 | [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; 44 | CGContextSetAlpha(context, 0.5); 45 | CGContextBeginTransparencyLayer(context, NULL); 46 | [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; 47 | CGContextSetBlendMode(context, kCGBlendModeDifference); 48 | CGContextSetFillColorWithColor(context,[UIColor whiteColor].CGColor); 49 | CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height)); 50 | CGContextEndTransparencyLayer(context); 51 | UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); 52 | UIGraphicsEndImageContext(); 53 | return returnImage; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | @interface UIImage (Snapshot) 14 | 15 | /// Uses renderInContext: to get a snapshot of the layer. 16 | + (UIImage *)fb_imageForLayer:(CALayer *)layer; 17 | 18 | /// Uses renderInContext: to get a snapshot of the view layer. 19 | + (UIImage *)fb_imageForViewLayer:(UIView *)view; 20 | 21 | /// Uses drawViewHierarchyInRect: to get a snapshot of the view and adds the view into a window if needed. 22 | + (UIImage *)fb_imageForView:(UIView *)view; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | #import 13 | 14 | @implementation UIImage (Snapshot) 15 | 16 | + (UIImage *)fb_imageForLayer:(CALayer *)layer 17 | { 18 | CGRect bounds = layer.bounds; 19 | NSAssert1(CGRectGetWidth(bounds), @"Zero width for layer %@", layer); 20 | NSAssert1(CGRectGetHeight(bounds), @"Zero height for layer %@", layer); 21 | 22 | UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); 23 | CGContextRef context = UIGraphicsGetCurrentContext(); 24 | NSAssert1(context, @"Could not generate context for layer %@", layer); 25 | CGContextSaveGState(context); 26 | [layer layoutIfNeeded]; 27 | [layer renderInContext:context]; 28 | CGContextRestoreGState(context); 29 | 30 | UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); 31 | UIGraphicsEndImageContext(); 32 | return snapshot; 33 | } 34 | 35 | + (UIImage *)fb_imageForViewLayer:(UIView *)view 36 | { 37 | [view layoutIfNeeded]; 38 | return [self fb_imageForLayer:view.layer]; 39 | } 40 | 41 | + (UIImage *)fb_imageForView:(UIView *)view 42 | { 43 | CGRect bounds = view.bounds; 44 | NSAssert1(CGRectGetWidth(bounds), @"Zero width for view %@", view); 45 | NSAssert1(CGRectGetHeight(bounds), @"Zero height for view %@", view); 46 | 47 | // If the input view is already a UIWindow, then just use that. Otherwise wrap in a window. 48 | UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *)view : view.window; 49 | BOOL removeFromSuperview = NO; 50 | if (!window) { 51 | window = [[UIApplication sharedApplication] fb_strictKeyWindow]; 52 | } 53 | 54 | if (!view.window && view != window) { 55 | [window addSubview:view]; 56 | removeFromSuperview = YES; 57 | } 58 | 59 | UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); 60 | [view layoutIfNeeded]; 61 | [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; 62 | 63 | UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); 64 | UIGraphicsEndImageContext(); 65 | 66 | if (removeFromSuperview) { 67 | [view removeFromSuperview]; 68 | } 69 | 70 | return snapshot; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | /** 18 | Returns a Boolean value that indicates whether the snapshot test is running in 64Bit. 19 | This method is a convenience for creating the suffixes set based on the architecture 20 | that the test is running. 21 | 22 | @returns @c YES if the test is running in 64bit, otherwise @c NO. 23 | */ 24 | BOOL FBSnapshotTestCaseIs64Bit(void); 25 | 26 | /** 27 | Returns a default set of strings that is used to append a suffix based on the architectures. 28 | @warning Do not modify this function, you can create your own and use it with @c FBSnapshotVerifyViewWithOptions() 29 | 30 | @returns An @c NSOrderedSet object containing strings that are appended to the reference images directory. 31 | */ 32 | NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void); 33 | 34 | /** 35 | Returns a fully «normalized» file name. 36 | Strips punctuation and spaces and replaces them with @c _. Also appends the device model, running OS and screen size to the file name. 37 | 38 | @returns An @c NSString object containing the passed @c fileName with the device model, OS and screen size appended at the end. 39 | */ 40 | NSString *FBDeviceAgnosticNormalizedFileName(NSString *fileName); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | BOOL FBSnapshotTestCaseIs64Bit(void) 16 | { 17 | #if __LP64__ 18 | return YES; 19 | #else 20 | return NO; 21 | #endif 22 | } 23 | 24 | NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void) 25 | { 26 | NSMutableOrderedSet *suffixesSet = [[NSMutableOrderedSet alloc] init]; 27 | [suffixesSet addObject:@"_32"]; 28 | [suffixesSet addObject:@"_64"]; 29 | if (FBSnapshotTestCaseIs64Bit()) { 30 | return [suffixesSet reversedOrderedSet]; 31 | } 32 | return [suffixesSet copy]; 33 | } 34 | 35 | NSString *FBDeviceAgnosticNormalizedFileName(NSString *fileName) 36 | { 37 | UIDevice *device = [UIDevice currentDevice]; 38 | UIWindow *keyWindow = [[UIApplication sharedApplication] fb_strictKeyWindow]; 39 | CGSize screenSize = keyWindow.bounds.size; 40 | NSString *os = device.systemVersion; 41 | 42 | fileName = [NSString stringWithFormat:@"%@_%@%@_%.0fx%.0f", fileName, device.model, os, screenSize.width, screenSize.height]; 43 | 44 | NSMutableCharacterSet *invalidCharacters = [NSMutableCharacterSet new]; 45 | [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]]; 46 | [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]]; 47 | NSArray *validComponents = [fileName componentsSeparatedByCharactersInSet:invalidCharacters]; 48 | fileName = [validComponents componentsJoinedByString:@"_"]; 49 | 50 | return fileName; 51 | } -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | For the FBSnapshotTestCase software 4 | 5 | Copyright (c) 2013, Facebook, Inc. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | * Neither the name Facebook nor the names of its contributors may be used to 17 | endorse or promote products derived from this software without specific 18 | prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/README.md: -------------------------------------------------------------------------------- 1 | FBSnapshotTestCase 2 | ====================== 3 | 4 | [![Build Status](https://travis-ci.org/facebook/ios-snapshot-test-case.svg)](https://travis-ci.org/facebook/ios-snapshot-test-case) [![Cocoa Pod Version](https://cocoapod-badges.herokuapp.com/v/FBSnapshotTestCase/badge.svg)](http://cocoadocs.org/docsets/FBSnapshotTestCase/) 5 | 6 | What it does 7 | ------------ 8 | 9 | A "snapshot test case" takes a configured `UIView` or `CALayer` and uses the 10 | `renderInContext:` method to get an image snapshot of its contents. It 11 | compares this snapshot to a "reference image" stored in your source code 12 | repository and fails the test if the two images don't match. 13 | 14 | Why? 15 | ---- 16 | 17 | At Facebook we write a lot of UI code. As you might imagine, each type of 18 | feed story is rendered using a subclass of `UIView`. There are a lot of edge 19 | cases that we want to handle correctly: 20 | 21 | - What if there is more text than can fit in the space available? 22 | - What if an image doesn't match the size of an image view? 23 | - What should the highlighted state look like? 24 | 25 | It's straightforward to test logic code, but less obvious how you should test 26 | views. You can do a lot of rectangle asserts, but these are hard to understand 27 | or visualize. Looking at an image diff shows you exactly what changed and how 28 | it will look to users. 29 | 30 | We developed `FBSnapshotTestCase` to make snapshot tests easy. 31 | 32 | Installation with CocoaPods 33 | --------------------------- 34 | 35 | 1. Add the following lines to your Podfile: 36 | 37 | ``` 38 | target "Tests" do 39 | pod 'FBSnapshotTestCase' 40 | end 41 | ``` 42 | 43 | If you support iOS 7 use `FBSnapshotTestCase/Core` instead, which doesn't contain Swift support. 44 | 45 | Replace "Tests" with the name of your test project. 46 | 47 | 2. There are [three ways](https://github.com/facebook/ios-snapshot-test-case/blob/master/FBSnapshotTestCase/FBSnapshotTestCase.h#L19-L29) of setting reference image directories, the recommended one is to define `FB_REFERENCE_IMAGE_DIR` in your scheme. This should point to the directory where you want reference images to be stored. At Facebook, we normally use this: 48 | 49 | |Name|Value| 50 | |:---|:----| 51 | |`FB_REFERENCE_IMAGE_DIR`|`$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages`| 52 | 53 | 54 | ![](FBSnapshotTestCaseDemo/Scheme_FB_REFERENCE_IMAGE_DIR.png) 55 | 56 | Creating a snapshot test 57 | ------------------------ 58 | 59 | 1. Subclass `FBSnapshotTestCase` instead of `XCTestCase`. 60 | 2. From within your test, use `FBSnapshotVerifyView`. 61 | 3. Run the test once with `self.recordMode = YES;` in the test's `-setUp` 62 | method. (This creates the reference images on disk.) 63 | 4. Remove the line enabling record mode and run the test. 64 | 65 | Features 66 | -------- 67 | 68 | - Automatically names reference images on disk according to test class and 69 | selector. 70 | - Prints a descriptive error message to the console on failure. (Bonus: 71 | failure message includes a one-line command to see an image diff if 72 | you have [Kaleidoscope](http://www.kaleidoscopeapp.com) installed.) 73 | - Supply an optional "identifier" if you want to perform multiple snapshots 74 | in a single test method. 75 | - Support for `CALayer` via `FBSnapshotVerifyLayer`. 76 | - `usesDrawViewHierarchyInRect` to handle cases like `UIVisualEffect`, `UIAppearance` and Size Classes. 77 | - `isDeviceAgnostic` to allow appending the device model (`iPhone`, `iPad`, `iPod Touch`, etc), OS version and screen size to the images (allowing to have multiple tests for the same «snapshot» for different `OS`s and devices). 78 | 79 | Notes 80 | ----- 81 | 82 | Your unit test must be an "application test", not a "logic test." (That is, it 83 | must be run within the Simulator so that it has access to UIKit.) In Xcode 5 84 | and later new projects only offer application tests, but older projects will 85 | have separate targets for the two types. 86 | 87 | Authors 88 | ------- 89 | 90 | `FBSnapshotTestCase` was written at Facebook by 91 | [Jonathan Dann](https://facebook.com/j.p.dann) with significant contributions by 92 | [Todd Krabach](https://facebook.com/toddkrabach). 93 | 94 | License 95 | ------- 96 | 97 | `FBSnapshotTestCase` is BSD-licensed. See `LICENSE`. 98 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/ButtonClickStyle.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ButtonClickStyle", 3 | "version": "0.1.0", 4 | "summary": "A short description of ButtonClickStyle.", 5 | "description": "TODO: Add long description of the pod here.", 6 | "homepage": "https://github.com/mrusta/ButtonClickStyle", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "mrusta": "rustamburger@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/mrusta/ButtonClickStyle.git", 16 | "tag": "0.1.0" 17 | }, 18 | "platforms": { 19 | "ios": "9.0" 20 | }, 21 | "source_files": "ButtonClickStyle/Classes/**/*" 22 | } 23 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ButtonClickStyle (0.1.0) 3 | - FBSnapshotTestCase (2.1.4): 4 | - FBSnapshotTestCase/SwiftSupport (= 2.1.4) 5 | - FBSnapshotTestCase/Core (2.1.4) 6 | - FBSnapshotTestCase/SwiftSupport (2.1.4): 7 | - FBSnapshotTestCase/Core 8 | 9 | DEPENDENCIES: 10 | - ButtonClickStyle (from `../`) 11 | - FBSnapshotTestCase (~> 2.1.4) 12 | 13 | SPEC REPOS: 14 | trunk: 15 | - FBSnapshotTestCase 16 | 17 | EXTERNAL SOURCES: 18 | ButtonClickStyle: 19 | :path: "../" 20 | 21 | SPEC CHECKSUMS: 22 | ButtonClickStyle: 301678baae9fa299dcb47f256eeb57876a9afc94 23 | FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a 24 | 25 | PODFILE CHECKSUM: c55351212e74dce90f1f9cb6abd7e864c2307765 26 | 27 | COCOAPODS: 1.11.2 28 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ButtonClickStyle/ButtonClickStyle-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ButtonClickStyle/ButtonClickStyle-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_ButtonClickStyle : NSObject 3 | @end 4 | @implementation PodsDummy_ButtonClickStyle 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ButtonClickStyle/ButtonClickStyle-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ButtonClickStyle/ButtonClickStyle-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double ButtonClickStyleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char ButtonClickStyleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ButtonClickStyle/ButtonClickStyle.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ButtonClickStyle/ButtonClickStyle.modulemap: -------------------------------------------------------------------------------- 1 | framework module ButtonClickStyle { 2 | umbrella header "ButtonClickStyle-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ButtonClickStyle/ButtonClickStyle.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.1.4 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FBSnapshotTestCase : NSObject 3 | @end 4 | @implementation PodsDummy_FBSnapshotTestCase 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "FBSnapshotTestCase.h" 14 | #import "FBSnapshotTestCasePlatform.h" 15 | #import "FBSnapshotTestController.h" 16 | 17 | FOUNDATION_EXPORT double FBSnapshotTestCaseVersionNumber; 18 | FOUNDATION_EXPORT const unsigned char FBSnapshotTestCaseVersionString[]; 19 | 20 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase 3 | ENABLE_BITCODE = NO 4 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" 5 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 6 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 7 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT} 12 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FBSnapshotTestCase 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 15 | SKIP_INSTALL = YES 16 | SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" 17 | SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" 18 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 19 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.modulemap: -------------------------------------------------------------------------------- 1 | framework module FBSnapshotTestCase { 2 | umbrella header "FBSnapshotTestCase-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase 3 | ENABLE_BITCODE = NO 4 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" 5 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 6 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 7 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT} 12 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FBSnapshotTestCase 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 15 | SKIP_INSTALL = YES 16 | SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" 17 | SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" 18 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 19 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## ButtonClickStyle 5 | 6 | Copyright (c) 2022 mrusta 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2022 mrusta <rustamburger@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | ButtonClickStyle 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ButtonClickStyle_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ButtonClickStyle_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_ButtonClickStyle_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ButtonClickStyle_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle/ButtonClickStyle.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "ButtonClickStyle" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ButtonClickStyle_Example { 2 | umbrella header "Pods-ButtonClickStyle_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Example/Pods-ButtonClickStyle_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle/ButtonClickStyle.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "ButtonClickStyle" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FBSnapshotTestCase 5 | 6 | BSD License 7 | 8 | For the FBSnapshotTestCase software 9 | 10 | Copyright (c) 2013, Facebook, Inc. 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright notice, 19 | this list of conditions and the following disclaimer in the documentation 20 | and/or other materials provided with the distribution. 21 | * Neither the name Facebook nor the names of its contributors may be used to 22 | endorse or promote products derived from this software without specific 23 | prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 29 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | Generated by CocoaPods - https://cocoapods.org 37 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | BSD License 18 | 19 | For the FBSnapshotTestCase software 20 | 21 | Copyright (c) 2013, Facebook, Inc. 22 | All rights reserved. 23 | 24 | Redistribution and use in source and binary forms, with or without 25 | modification, are permitted provided that the following conditions are met: 26 | 27 | * Redistributions of source code must retain the above copyright notice, 28 | this list of conditions and the following disclaimer. 29 | * Redistributions in binary form must reproduce the above copyright notice, 30 | this list of conditions and the following disclaimer in the documentation 31 | and/or other materials provided with the distribution. 32 | * Neither the name Facebook nor the names of its contributors may be used to 33 | endorse or promote products derived from this software without specific 34 | prior written permission. 35 | 36 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 37 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 40 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 42 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 43 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | 47 | License 48 | BSD 49 | Title 50 | FBSnapshotTestCase 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | FooterText 56 | Generated by CocoaPods - https://cocoapods.org 57 | Title 58 | 59 | Type 60 | PSGroupSpecifier 61 | 62 | 63 | StringsTable 64 | Acknowledgements 65 | Title 66 | Acknowledgements 67 | 68 | 69 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ButtonClickStyle_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ButtonClickStyle_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_ButtonClickStyle_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ButtonClickStyle_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle/ButtonClickStyle.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "ButtonClickStyle" -framework "FBSnapshotTestCase" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ButtonClickStyle_Tests { 2 | umbrella header "Pods-ButtonClickStyle_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ButtonClickStyle_Tests/Pods-ButtonClickStyle_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ButtonClickStyle/ButtonClickStyle.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "ButtonClickStyle" -framework "FBSnapshotTestCase" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 mrusta 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.5 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "ButtonClickStyle", 8 | platforms: [ 9 | // Add support for all platforms starting from a specific version. 10 | .iOS(.v9), 11 | ], 12 | products: [ 13 | // Products define the executables and libraries a package produces, and make them visible to other packages. 14 | .library( 15 | name: "ButtonClickStyle", 16 | targets: ["ButtonClickStyle"]), 17 | ], 18 | dependencies: [ 19 | // Dependencies declare other packages that this package depends on. 20 | // .package(url: /* package url */, from: "1.0.0"), 21 | ], 22 | targets: [ 23 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 24 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 25 | .target( 26 | name: "ButtonClickStyle", 27 | dependencies: []), 28 | ] 29 | ) 30 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonClickStyleAnim+UIView.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 19.04.2022. 6 | // Copyright © 2022 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | //MARK: - extensions 12 | 13 | extension UIView { 14 | 15 | public func snapshot() -> UIImage { 16 | if #available(iOS 10.0, *) { 17 | let renderer = UIGraphicsImageRenderer(bounds: bounds) 18 | return renderer.image { rendererContext in 19 | layer.render(in: rendererContext.cgContext) 20 | } 21 | } else { 22 | UIGraphicsBeginImageContext(self.frame.size) 23 | self.layer.render(in:UIGraphicsGetCurrentContext()!) 24 | let image = UIGraphicsGetImageFromCurrentImageContext() 25 | UIGraphicsEndImageContext() 26 | return UIImage(cgImage: image!.cgImage!) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewAlpha.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | import UIKit 4 | 5 | extension UIView { 6 | 7 | // MARK: - Alpha 8 | 9 | public func buttonClickStyleAlpha(with views: [UIView], visible: Bool, value: CGFloat, duration: CGFloat?) { 10 | 11 | var alpha: CGFloat = 1.0 12 | if visible != true { 13 | alpha = value 14 | } 15 | 16 | if let duration = duration { 17 | UIView.animate(withDuration: duration, animations: { 18 | for view in views { 19 | view.alpha = alpha 20 | } 21 | }) 22 | } else { 23 | for view in views { 24 | view.alpha = alpha 25 | } 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewAndroidPulse.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | extension UIView { 5 | 6 | // MARK: - Android Pulse 7 | 8 | public func buttonClickStyleAndroidPulse(radius: CGFloat, duration: CGFloat, color: UIColor? = nil, value: CGFloat? = nil, position: CGPoint) { 9 | 10 | var rcolor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.2786076018) 11 | 12 | if let color = color { 13 | rcolor = color .withAlphaComponent(0.75) 14 | } 15 | 16 | if let alpha = value { 17 | rcolor = rcolor.withAlphaComponent(alpha) 18 | } 19 | 20 | let to = 0 + (radius * 400) // 200 21 | 22 | let pulse = ButtonClickStylePulseAnimation(numberOfPulse: 1, radius: to, postion: position) 23 | pulse.animationDuration = duration 24 | pulse.backgroundColor = rcolor.cgColor 25 | layer.insertSublayer(pulse, below: layer) 26 | } 27 | 28 | } 29 | 30 | //MARK: - extensions 31 | 32 | 33 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewFlash.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | extension UIView { 5 | 6 | // MARK: - Flash 7 | 8 | public func buttonClickStyleFlash(value: CGFloat, duration: CGFloat) { 9 | 10 | let flash = CABasicAnimation(keyPath: "opacity") 11 | flash.duration = duration 12 | flash.fromValue = 1 13 | let to = (1.0 - value) 14 | flash.toValue = to // 0.1 15 | flash.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) 16 | flash.autoreverses = true 17 | flash.repeatCount = 3 18 | 19 | layer.add(flash, forKey: nil) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewGlare.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+AnimationGlare\.swift 3 | // ButtonClickStyle_Example 4 | // 5 | // Created by Рустам Мотыгуллин on 11.04.2022. 6 | // Copyright © 2022 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | 13 | public func buttonClickStyleGlare(alpha: CGFloat, color: UIColor? = nil, duration: CGFloat? = nil) { 14 | 15 | // let snapshot = self.asImage().withRenderingMode(.alwaysTemplate) 16 | let snapshot = self.snapshot().withRenderingMode(.alwaysTemplate) 17 | let imageView = UIImageView(image: snapshot) 18 | 19 | var clr: UIColor = UIColor(white: 0.9, alpha: alpha) 20 | if let color = color { 21 | clr = color.withAlphaComponent(alpha) 22 | } 23 | imageView.tintColor = clr 24 | let image = imageView.snapshot() 25 | // let image = imageView.asImage()// else { return } 26 | 27 | let width = image.size.width 28 | let height = image.size.height 29 | let shineLayer = CALayer() 30 | shineLayer.contents = image.cgImage 31 | shineLayer.frame = bounds 32 | 33 | let gradientLayer = CAGradientLayer() 34 | gradientLayer.colors = [UIColor.clear.cgColor, 35 | UIColor.black.withAlphaComponent(0.55).cgColor, 36 | UIColor.black.cgColor, 37 | UIColor.black.withAlphaComponent(0.55).cgColor, 38 | UIColor.clear.cgColor] 39 | gradientLayer.locations = [0.0, 0.35, 0.50, 0.65, 0.0] 40 | gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) 41 | gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.15) 42 | 43 | gradientLayer.frame = CGRect(x: -width, y: 0, width: width, height: height) 44 | let animation = CABasicAnimation(keyPath: "position.x") 45 | animation.byValue = width * 2 46 | animation.duration = duration ?? 1.25 47 | animation.repeatCount = Float.greatestFiniteMagnitude 48 | animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) 49 | 50 | layer.addSublayer(shineLayer) 51 | shineLayer.mask = gradientLayer 52 | 53 | gradientLayer.add(animation, forKey: "shine") 54 | } 55 | 56 | public func buttonClickStyleGlareStop() { 57 | layer.sublayers?.forEach { 58 | $0.mask?.removeAnimation(forKey: "shine") 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewPress.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | extension UIView { 5 | 6 | // MARK: - Press 7 | 8 | public func buttonClickStylePress(duration: CGFloat, cornRadius: CGFloat? = nil, value: CGFloat, shadow: Bool, visible: Bool) { 9 | if visible { 10 | animate(duration: duration, view: self, transform: .identity) 11 | if shadow { 12 | buttonClickStyleShadow(with: [self], superView: false, cornRadius: cornRadius, visible: true, value: value, duration: duration) 13 | } 14 | } else { 15 | 16 | if shadow { 17 | let to = 1.0 - (value * 0.05) 18 | animate(duration: duration, view: self, transform: .identity.scaledBy(x: to, y: to)) 19 | buttonClickStyleShadow(with: [self], superView: false, cornRadius: cornRadius, visible: false, value: value / 3 , duration: duration / 3) 20 | } else { 21 | let to = 0.45 + ((value) * 5.0) 22 | animate(duration: duration, view: self, transform: .identity.translatedBy(x: 0, y: to)) 23 | 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewPulsate.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | extension UIView { 5 | 6 | public func buttonClickStyleFave(mainView: UIView, secondView: UIView, color: UIColor? = nil, value: CGFloat, duration: CGFloat) { 7 | 8 | let maxSize = max(mainView.frame.size.width, mainView.frame.size.height) * 0.85 9 | let _y = (mainView.frame.size.height / 2) - (maxSize / 2) 10 | let _x = (mainView.frame.size.width / 2) - (maxSize / 2) 11 | 12 | mainView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01) 13 | 14 | let clr = color ?? UIColor.black 15 | 16 | let circle = UIView(frame: .init(x: _x, y: _y, width: maxSize, height: maxSize)) 17 | circle.layer.cornerRadius = maxSize / 2 18 | circle.backgroundColor = .clear // color ?? UIColor.black 19 | circle.layer.borderWidth = maxSize / 2 20 | circle.layer.borderColor = clr.cgColor 21 | circle.alpha = 0.35 22 | 23 | secondView .addSubview(circle) 24 | 25 | let durr = 0.35 26 | 27 | let borderWidthAnimation: CABasicAnimation = CABasicAnimation(keyPath: "borderWidth") 28 | borderWidthAnimation.fromValue = circle.layer.borderWidth 29 | borderWidthAnimation.toValue = 0 30 | borderWidthAnimation.duration = durr // * 0.8 31 | circle.layer.add(borderWidthAnimation, forKey: "borderWidth") 32 | circle.layer.borderWidth = 0 33 | 34 | circle.transform = CGAffineTransform(scaleX: 0.01, y: 0.01) 35 | 36 | UIView.animate(withDuration: durr , 37 | delay: 0.00, 38 | usingSpringWithDamping: 2.8, 39 | initialSpringVelocity: 4, 40 | options: [.curveEaseOut], 41 | animations: { 42 | circle.transform = .identity 43 | }, completion: nil) 44 | 45 | UIView.animate(withDuration: 0.35, // 0.4, 46 | delay: 0.3,// 0.23, 47 | usingSpringWithDamping: 0.38, 48 | initialSpringVelocity: 10.0, 49 | options: [.allowUserInteraction], 50 | animations: { 51 | mainView.transform = .identity 52 | mainView.alpha = 1.0 53 | circle.alpha = 0.0 54 | }, completion: { fin in 55 | 56 | 57 | circle.removeFromSuperview() 58 | }) 59 | } 60 | } 61 | 62 | 63 | extension UIView { 64 | 65 | 66 | // MARK: - Pulsate 67 | 68 | public func buttonClickStylePulsate(value: CGFloat, duration: CGFloat) { 69 | 70 | let pulse = CASpringAnimation(keyPath: "transform.scale") 71 | pulse.duration = duration 72 | pulse.fromValue = 1.0 73 | let to = 0.45 + ((1.0 - value) * 0.8) 74 | pulse.toValue = to // 0.85 75 | pulse.autoreverses = true 76 | pulse.repeatCount = 2 77 | pulse.initialVelocity = 0.5 78 | 79 | 80 | layer.add(pulse, forKey: "pulse") 81 | } 82 | 83 | // MARK: - Pulsate 2 84 | 85 | public func buttonClickStylePulsateNew(duration: CGFloat, value: CGFloat, visible: Bool) { 86 | let to = 0.45 + ((1.0 - value) * 0.8) 87 | self.layer.removeAllAnimations() 88 | if visible { 89 | self.transform = CGAffineTransform.identity.scaledBy(x: to, y: to) 90 | self.animate(duration: duration, view: self, transform: .identity) 91 | 92 | 93 | } else { 94 | animate(duration: duration, view: self, transform: CGAffineTransform.identity.scaledBy(x: to, y: to)) 95 | } 96 | } 97 | 98 | public func animate(duration: CGFloat, view: UIView, transform: CGAffineTransform) { 99 | UIView.animate(withDuration: duration, // 0.4, 100 | delay: 0, 101 | usingSpringWithDamping: 0.5, 102 | initialSpringVelocity: 3, 103 | options: [.curveEaseInOut], 104 | animations: { 105 | view.transform = transform 106 | }, completion: nil) 107 | } 108 | 109 | 110 | 111 | } 112 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewPulse.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PulseAnimation.swift 3 | // ButtonLayersButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 09.03.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | //MARK: - Pulse Animation 11 | 12 | public class ButtonClickStylePulseAnimation: CALayer { 13 | 14 | var animationGroup = CAAnimationGroup() 15 | var animationDuration: TimeInterval = 1.5 16 | var radius: CGFloat = 200 17 | var numebrOfPulse: Float = Float.infinity 18 | 19 | override init(layer: Any) { 20 | super.init(layer: layer) 21 | } 22 | 23 | required init?(coder aDecoder: NSCoder) { 24 | fatalError("init(coder:) has not been implemented") 25 | } 26 | 27 | init(numberOfPulse: Float = Float.infinity, radius: CGFloat, postion: CGPoint){ 28 | super.init() 29 | self.backgroundColor = UIColor.black.cgColor 30 | self.contentsScale = UIScreen.main.scale 31 | self.opacity = 0 32 | self.radius = radius 33 | self.numebrOfPulse = numberOfPulse 34 | self.position = postion 35 | 36 | self.bounds = CGRect(x: 0, y: 0, width: radius*2, height: radius*2) 37 | self.cornerRadius = radius 38 | 39 | DispatchQueue.global(qos: .default).async { 40 | self.setupAnimationGroup() 41 | DispatchQueue.main.async { 42 | self.add(self.animationGroup, forKey: "pulse") 43 | } 44 | } 45 | } 46 | 47 | public func scaleAnimation() -> CABasicAnimation { 48 | let scaleAnimaton = CABasicAnimation(keyPath: "transform.scale.xy") 49 | scaleAnimaton.fromValue = NSNumber(value: 0) 50 | scaleAnimaton.toValue = NSNumber(value: 1) 51 | scaleAnimaton.duration = animationDuration 52 | return scaleAnimaton 53 | } 54 | 55 | public func createOpacityAnimation() -> CAKeyframeAnimation { 56 | let opacityAnimiation = CAKeyframeAnimation(keyPath: "opacity") 57 | opacityAnimiation.duration = animationDuration 58 | opacityAnimiation.values = [0.4,0.8,0] 59 | opacityAnimiation.keyTimes = [0,0.3,1] 60 | return opacityAnimiation 61 | } 62 | 63 | public func setupAnimationGroup() { 64 | self.animationGroup.duration = animationDuration 65 | self.animationGroup.repeatCount = numebrOfPulse 66 | let defaultCurve = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default) 67 | self.animationGroup.timingFunction = defaultCurve 68 | self.animationGroup.animations = [scaleAnimation(),createOpacityAnimation()] 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewShadow.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | private let shTag = 31 5 | private let shColor: UIColor = .init(red: 10.0 / 255.0, green: 13.0 / 255.0, blue: 38.0 / 255.0, alpha: 1.0) 6 | 7 | extension UIView { 8 | 9 | // MARK: - Layer Gray 10 | 11 | private func buttonClickStyleGetShadowView(superView: Bool) -> UIView? { 12 | guard let mainView = (superView ? self.superview : self) else { return nil } 13 | 14 | var shadowView: UIView? 15 | for v in mainView.subviews { 16 | if v.tag == shTag { 17 | shadowView = v 18 | } 19 | } 20 | return shadowView 21 | } 22 | 23 | // MARK: - Add Shadow View 24 | 25 | public func buttonClickStyleAddShadowView(with views: [UIView], 26 | superView: Bool = false, 27 | shadowColor: UIColor?, 28 | value: CGFloat = 1.0 29 | ) -> UIView? { 30 | 31 | guard let mainView = (superView ? self.superview : self) else { return nil } 32 | 33 | mainView.clipsToBounds = false 34 | 35 | if mainView.viewWithTag(shTag) != nil { return nil } 36 | 37 | let shadowView = UIView(frame: self.bounds)// mainView.bounds) 38 | shadowView.tag = shTag 39 | shadowView.clipsToBounds = false 40 | var wMax: CGFloat = 0 41 | var hMax: CGFloat = 0 42 | 43 | let shadowContentView = UIView(frame: self.bounds) 44 | shadowContentView.alpha = value 45 | shadowContentView.clipsToBounds = false 46 | shadowView.addSubview(shadowContentView) 47 | 48 | views.forEach { 49 | let clip = $0.superview?.clipsToBounds ?? false 50 | 51 | if wMax < ($0.frame.origin.x + frame.size.width) { wMax = ($0.frame.origin.x + frame.size.width) } 52 | if hMax < ($0.frame.origin.y + frame.size.height) { hMax = ($0.frame.origin.y + frame.size.height) } 53 | 54 | let frame = $0.convert($0.bounds, to: mainView) 55 | let imgBtn = UIButton(frame: frame) 56 | let image: UIImage! 57 | 58 | let tinttColor = shadowColor ?? shColor 59 | 60 | $0.superview?.clipsToBounds = false 61 | 62 | image = $0.snapshot().withRenderingMode(.alwaysTemplate) 63 | $0.superview?.clipsToBounds = clip 64 | 65 | imgBtn.setImage(image, for: .normal) 66 | imgBtn.tintColor = tinttColor 67 | 68 | shadowContentView.addSubview(imgBtn) 69 | } 70 | 71 | 72 | var frr = shadowView.frame 73 | frr.size = .init(width: wMax, height: hMax) 74 | shadowView.frame = frr 75 | 76 | mainView.addSubview(shadowView) 77 | 78 | return shadowView 79 | } 80 | 81 | public func buttonClickStyleShadow(with views: [UIView], superView: Bool = true, color: UIColor? = nil, cornRadius: CGFloat? = nil, visible: Bool, value: CGFloat, duration: CGFloat?) { 82 | 83 | if visible { 84 | 85 | guard let shadowView = buttonClickStyleGetShadowView(superView: superView) else { return } 86 | 87 | if let duration = duration { 88 | UIView.animate(withDuration: duration, 89 | animations: { 90 | shadowView.alpha = 0 91 | }, 92 | completion: { fin in 93 | shadowView.removeFromSuperview() 94 | } 95 | ) 96 | } else { 97 | shadowView.alpha = 0 98 | shadowView.removeFromSuperview() 99 | } 100 | 101 | 102 | } else { 103 | 104 | guard let shadowView = buttonClickStyleAddShadowView(with: views, superView: superView, shadowColor: color, value: value) else { return } 105 | 106 | shadowView.alpha = ((duration == nil) ? 1 : 0) 107 | if let duration = duration { 108 | if duration == .zero { 109 | shadowView.alpha = 1 110 | } else { 111 | UIView.animate(withDuration: duration, animations: { 112 | shadowView.alpha = 1 113 | }) 114 | } 115 | } 116 | 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Animations/ButtonClickStyleAnim+UIViewSnake.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | extension UIView { 5 | 6 | // MARK: - Shake 7 | 8 | public func buttonClickStyleShake(value: CGFloat, duration: CGFloat) { 9 | let animation = CAKeyframeAnimation(keyPath: "transform.translation.x") 10 | animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) 11 | animation.duration = duration // 0.6 12 | 13 | let to = 5 + (value * 30.0) 14 | let offset: CGFloat = to // 20.0 15 | animation.values = [-offset, offset, -offset, offset, -(offset/2), (offset/2), -(offset/4), (offset/4), 0.0 ] 16 | layer.add(animation, forKey: "shake") 17 | } 18 | 19 | // MARK: - Shake 2 20 | 21 | public func buttonClickStyleShakeNew(value: CGFloat, duration: CGFloat) { 22 | 23 | let shake = CABasicAnimation(keyPath: "position") 24 | shake.duration = duration 25 | shake.repeatCount = 2 26 | shake.autoreverses = true 27 | 28 | let to = -10 + (value * 30) 29 | let fromPoint = CGPoint(x: center.x - to, y: center.y) 30 | let fromValue = NSValue(cgPoint: fromPoint) 31 | 32 | let toPoint = CGPoint(x: center.x + to, y: center.y) 33 | let toValue = NSValue(cgPoint: toPoint) 34 | 35 | shake.fromValue = fromValue 36 | shake.toValue = toValue 37 | 38 | layer.add(shake, forKey: "position") 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/ButtonClicClosure.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | extension ButtonClick { 5 | 6 | public typealias Emoji = (type: String, color: String, repeats: String, new: String) 7 | public typealias Full = (base: String, name: String, emoji: Emoji, index: Int) 8 | public typealias Closure = () -> () 9 | public typealias ClosureEvent = (_ event: UIControl.Event) -> () 10 | 11 | 12 | @objc public func invoke() { 13 | closureSleeve?() 14 | } 15 | } 16 | 17 | 18 | extension UIControl { 19 | public func click(for controlEvents: UIControl.Event = .touchUpInside, 20 | _ closure: @escaping ButtonClick.Closure) { 21 | let sleeve = ButtonClick(closure) 22 | addTarget(sleeve, action: #selector(ButtonClick.invoke), for: controlEvents) 23 | objc_setAssociatedObject(self, 24 | String(format: "[%d]", arc4random()), 25 | sleeve, 26 | objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/ButtonClick.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | import UIKit 4 | 5 | open class ButtonClick { 6 | 7 | public var closureSleeve: ButtonClick.Closure? 8 | 9 | public init(_ closure: @escaping ButtonClick.Closure) { 10 | self.closureSleeve = closure 11 | } 12 | 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/ButtonClickState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BtnCellState.swift 3 | // ButtonCustomButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 26.03.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension ButtonClick { 11 | 12 | public struct State: Equatable { 13 | var titleText: String? 14 | var allSubviews: Bool = true 15 | var animationType: Int? 16 | var animationStyle: _Style? 17 | var animationTypeValue: CGFloat? 18 | var animationDuration: CGFloat? 19 | var new: Bool = false 20 | var color: UIColor? 21 | var startClick: Bool = false 22 | var debugButtonShow: Bool = false 23 | var addBackgrondColor: Bool = true 24 | 25 | public init( 26 | titleText: String? = nil, 27 | allSubviews: Bool = true, 28 | animationType: Int? = nil, 29 | animationStyle: _Style? = nil, 30 | animationTypeValue: CGFloat? = nil, 31 | animationDuration: CGFloat? = nil, 32 | new: Bool = false, 33 | color: UIColor? = nil, 34 | startClick: Bool = false, 35 | debugButtonShow: Bool = false, 36 | addBackgrondColor: Bool = true 37 | ) { 38 | self.titleText = titleText 39 | self.allSubviews = allSubviews 40 | self.animationType = animationType 41 | self.animationStyle = animationStyle 42 | self.animationTypeValue = animationTypeValue 43 | self.animationDuration = animationDuration 44 | self.new = new 45 | self.color = color 46 | self.startClick = startClick 47 | self.debugButtonShow = debugButtonShow 48 | self.addBackgrondColor = addBackgrondColor 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/ButtonClickStyle.swift: -------------------------------------------------------------------------------- 1 | public struct ButtonClickStyle { 2 | public private(set) var text = "Hello, World!" 3 | 4 | public init() { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/ButtonClickStyleButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonClickStyleButton.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 19.04.2022. 6 | // Copyright © 2022 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class ButtonClickStyleButton: UIButton { 12 | 13 | public var click: ButtonClick.ClosureEvent? 14 | 15 | // MARK: - Initialize 16 | 17 | required public init?(coder aDecoder: NSCoder) { 18 | super.init(coder: aDecoder) 19 | } 20 | 21 | override public init(frame: CGRect) { 22 | super.init(frame: frame) 23 | } 24 | 25 | public init( 26 | frame: CGRect, 27 | click: ButtonClick.ClosureEvent? = nil 28 | ) { 29 | super.init(frame: frame) 30 | self.click = click 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/ButtonClickStyleGestureRecognizer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonClickStyleGestureRecognizer.swift 3 | // ButtonLayersButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 09.03.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension ButtonClick.Style { 11 | 12 | open class GestureRecognizer: UITapGestureRecognizer { 13 | private var action: (UITapGestureRecognizer) -> Void 14 | 15 | public init(action: @escaping (UITapGestureRecognizer) -> Void) { 16 | self.action = action 17 | super.init(target: nil, action: nil) 18 | self.addTarget(self, action: #selector(execute(_:))) 19 | } 20 | 21 | @objc private func execute(_ sender: UITapGestureRecognizer) { 22 | action(sender) 23 | } 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Style/ButtonClickStyleBase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonClick+StyleBase.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 10.04.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension ButtonClick { 11 | 12 | public enum StyleBase: String, CaseIterable { 13 | case hide = "Hide" 14 | case move = "Move" 15 | case add = "Add" 16 | case addHide = "Add & Hide" 17 | case tapGesture = "TapGesture.Pulse" 18 | case loading = "Loading" 19 | case none = "❌" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Style/ButtonClickStyleEmoji.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonClick+StyleEmoji.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 10.04.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension ButtonClick.Style { 11 | 12 | public func emojiNew() -> String { 13 | switch self { 14 | case .alpha(_): return "" 15 | case .flash(_): return "" 16 | case .shadow(_, let color): return color == nil ? "" : "🆕" 17 | case .color(_, _): return "" 18 | case .colorFlat(_, _): return "" // border text 19 | case .press(_): return "" 20 | case .pulsate(_, let new): return new ? "🆕" : "" 21 | case .shake(_, let new): return new ? "🆕" : "" 22 | case .androidClickable(_, let color): return color == nil ? "" : "" 23 | default: return "🆕" 24 | } 25 | } 26 | 27 | public func emojiType() -> String { 28 | switch self { 29 | case .alpha(_): return "👁" 30 | case .flash(_): return "👁" 31 | case .shadow(_, _): return "🕳" 32 | case .color(_, _): return "" 33 | case .colorFlat(_, _): return "🔲 " 34 | case .press(_): return "👇" 35 | case .pulsate(_, _): return "💢" 36 | case .shake(_, _): return "🔛" 37 | case .androidClickable(_, _): return "🧿" 38 | default: return "✨" 39 | } 40 | } 41 | 42 | public func emojRepeat() -> String { 43 | switch self { 44 | case .alpha(_): return "" 45 | case .flash(_): return "♻️" 46 | case .shadow(_, _): return "" 47 | case .color(_, _): return "" 48 | case .colorFlat(_, _): return "" // border text 49 | case .press(_): return "" 50 | case .pulsate(_, _): return "♻️" 51 | case .shake(_, _): return "♻️" 52 | case .androidClickable(_, _): return "" 53 | default: return "" 54 | } 55 | } 56 | 57 | 58 | public func emojiColor() -> String { 59 | switch self { 60 | case .alpha(_): return "" 61 | case .flash(_): return "" 62 | case .shadow(_, let color): return color == nil ? "⚫️" : "🔵" 63 | case .color(_, _): return "🔵" 64 | case .colorFlat(_, _): return "🔵" // border text 65 | case .press(_): return "" 66 | case .pulsate(_, let new): return new ? "" : "" 67 | case .shake(_, let new): return new ? "" : "" 68 | case .androidClickable(_, let color): return color == nil ? "⚫️" : "🔵" 69 | default: return "🔵" 70 | } 71 | } 72 | 73 | public func emoji() -> ButtonClick.Emoji { 74 | return (emojiType(), emojiColor(), emojRepeat(), emojiNew()) 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/Style/ButtonClickStyleShort.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonClick+StyleShort.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 10.04.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension ButtonClick { 11 | 12 | //MARK: - Style 13 | 14 | public enum _Style: Int, CaseIterable { 15 | case alpha // 0 16 | case flash // 1 17 | case shadow // 2 18 | case shadowColor // 3 19 | case color // 4 20 | case colorFlat // 5 21 | case pulsateNew // 6 22 | case pulsate // 7 23 | case press // 8 24 | case shake // 9 25 | case shakeNew // 10 26 | case androidClickable // 11 27 | case androidClickableDark // 12 28 | case fave // 13 29 | case glare // 14 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/ButtonClickStyle/UIDesignable/ButtonClickStyleDesignTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonClickStyleDesignTest.swift 3 | // ButtonClickStyle 4 | // 5 | // Created by Рустам Мотыгуллин on 17.04.2022. 6 | // Copyright © 2022 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @IBDesignable 12 | public class ButtonClickStyleDesignTest: UIView { 13 | 14 | @IBInspectable var cornerRadius: CGFloat = 0.0 15 | @IBInspectable var fillColor: UIColor? 16 | 17 | //MARK: - Draw 18 | 19 | public override func draw(_ rect: CGRect) { 20 | super.draw(rect) 21 | 22 | backgroundColor = .clear 23 | 24 | layer.backgroundColor = fillColor?.cgColor 25 | 26 | // let bezier = rectangle(rect: bounds, radius: cornerRadius) 27 | // addFill(bezier: bezier) 28 | layer.cornerRadius = cornerRadius 29 | } 30 | 31 | public override func layoutSubviews() { 32 | 33 | backgroundColor = .clear 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrustaa/ButtonClickStyle/9cc538ae122a678f86f9e694a2cb533e33d073b8/logo.png --------------------------------------------------------------------------------