├── screenshots └── ALTableViewDiagram.png ├── ALTableViewSwift ├── TestALTableView │ ├── TestALTableView │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Orders │ │ │ ├── Styles.swift │ │ │ ├── Loading │ │ │ │ ├── LoadingTableViewCell.swift │ │ │ │ └── LoadingTableViewCell.xib │ │ │ ├── LoadingRetry │ │ │ │ ├── LoadingRetryTableViewCell.swift │ │ │ │ └── LoadingRetryTableViewCell.xib │ │ │ ├── OrderElement.swift │ │ │ └── OrdersTableViewCell.swift │ │ ├── Master │ │ │ ├── Master2TableViewCell.swift │ │ │ ├── MasterHeaderFooter.swift │ │ │ ├── MasterTableViewCell.swift │ │ │ ├── MasterHeaderFooter.xib │ │ │ ├── Master2TableViewCell.xib │ │ │ └── MasterTableViewCell.xib │ │ ├── DetailViewController.swift │ │ ├── Base.lproj │ │ │ └── LaunchScreen.storyboard │ │ ├── Info.plist │ │ ├── AppDelegate.swift │ │ └── MasterViewController.swift │ └── TestALTableView.xcodeproj │ │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Pods │ ├── Target Support Files │ │ ├── SwipeCellKit │ │ │ ├── SwipeCellKit.modulemap │ │ │ ├── SwipeCellKit-dummy.m │ │ │ ├── SwipeCellKit-prefix.pch │ │ │ ├── SwipeCellKit-umbrella.h │ │ │ ├── SwipeCellKit.xcconfig │ │ │ └── Info.plist │ │ ├── Pods-ALTableView │ │ │ ├── Pods-ALTableView.modulemap │ │ │ ├── Pods-ALTableView-dummy.m │ │ │ ├── Pods-ALTableView-acknowledgements.markdown │ │ │ ├── Pods-ALTableView-umbrella.h │ │ │ ├── Pods-ALTableView.debug.xcconfig │ │ │ ├── Pods-ALTableView.release.xcconfig │ │ │ ├── Info.plist │ │ │ ├── Pods-ALTableView-acknowledgements.plist │ │ │ ├── Pods-ALTableView-resources.sh │ │ │ └── Pods-ALTableView-frameworks.sh │ │ ├── Pods-TestALTableView │ │ │ ├── Pods-TestALTableView.modulemap │ │ │ ├── Pods-TestALTableView-dummy.m │ │ │ ├── Pods-TestALTableView-umbrella.h │ │ │ ├── Pods-TestALTableView.debug.xcconfig │ │ │ ├── Pods-TestALTableView.release.xcconfig │ │ │ ├── Info.plist │ │ │ ├── Pods-TestALTableView-acknowledgements.markdown │ │ │ ├── Pods-TestALTableView-acknowledgements.plist │ │ │ └── Pods-TestALTableView-resources.sh │ │ └── Pods-ALTableViewTests │ │ │ ├── Pods-ALTableViewTests.modulemap │ │ │ ├── Pods-ALTableViewTests-acknowledgements.markdown │ │ │ ├── Pods-ALTableViewTests-dummy.m │ │ │ ├── Pods-ALTableViewTests.debug.xcconfig │ │ │ ├── Pods-ALTableViewTests.release.xcconfig │ │ │ ├── Pods-ALTableViewTests-umbrella.h │ │ │ ├── Info.plist │ │ │ ├── Pods-ALTableViewTests-acknowledgements.plist │ │ │ ├── Pods-ALTableViewTests-resources.sh │ │ │ └── Pods-ALTableViewTests-frameworks.sh │ ├── Manifest.lock │ └── SwipeCellKit │ │ ├── Source │ │ ├── SwipeAccessibilityCustomAction.swift │ │ ├── Swipeable.swift │ │ ├── SwipeFeedback.swift │ │ ├── SwipeTableViewCell+Display.swift │ │ ├── SwipeCollectionViewCell+Display.swift │ │ ├── Extensions.swift │ │ ├── SwipeTableViewCell+Accessibility.swift │ │ ├── SwipeCollectionViewCell+Accessibility.swift │ │ ├── SwipeAnimator.swift │ │ ├── SwipeOptions.swift │ │ ├── SwipeTransitionLayout.swift │ │ ├── SwipeTableViewCellDelegate.swift │ │ ├── SwipeActionTransitioning.swift │ │ ├── SwipeCollectionViewCellDelegate.swift │ │ ├── SwipeActionButton.swift │ │ ├── SwipeExpanding.swift │ │ └── SwipeAction.swift │ │ └── LICENSE ├── ALTableView │ ├── ALTableView.xcodeproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── ALTableView │ │ ├── ALTableView.h │ │ ├── Info.plist │ │ └── ALTableViewClasses │ │ │ ├── Elements │ │ │ ├── Section │ │ │ │ ├── ALSectionElementFooter.swift │ │ │ │ ├── ALSectionElement.swift │ │ │ │ ├── ALSectionElementRow.swift │ │ │ │ └── ALSectionElementHeader.swift │ │ │ ├── ALElement.swift │ │ │ ├── HeaderFooter │ │ │ │ └── ALHeaderFooterElement.swift │ │ │ └── Row │ │ │ │ └── ALRowElement.swift │ │ │ ├── ALTableView │ │ │ ├── ALTableViewDataSource.swift │ │ │ ├── ALTableViewPullToRefresh.swift │ │ │ ├── ALTableView.swift │ │ │ ├── ALTableViewEditingManaging.swift │ │ │ └── ALTableViewDelegate.swift │ │ │ ├── Utils │ │ │ └── ALIndexOperator │ │ │ │ └── ALIndexOperator.swift │ │ │ └── Extension │ │ │ └── Array+ALTableView.swift │ └── ALTableViewTests │ │ ├── Info.plist │ │ ├── ALTableViewTests.swift │ │ └── ALRowElement │ │ └── ALRowElementInitialization.swift ├── ALTableView.xcworkspace │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── contents.xcworkspacedata ├── Podfile.lock └── Podfile ├── LICENSE ├── .gitignore └── ALTableView.podspec /screenshots/ALTableViewDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALiOSDev/ALTableView/HEAD/screenshots/ALTableViewDiagram.png -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/SwipeCellKit/SwipeCellKit.modulemap: -------------------------------------------------------------------------------- 1 | framework module SwipeCellKit { 2 | umbrella header "SwipeCellKit-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/SwipeCellKit/SwipeCellKit-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SwipeCellKit : NSObject 3 | @end 4 | @implementation PodsDummy_SwipeCellKit 5 | @end 6 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ALTableView { 2 | umbrella header "Pods-ALTableView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ALTableView : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ALTableView 5 | @end 6 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_TestALTableView { 2 | umbrella header "Pods-TestALTableView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ALTableViewTests { 2 | umbrella header "Pods-ALTableViewTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_TestALTableView : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_TestALTableView 5 | @end 6 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ALTableViewTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ALTableViewTests 5 | @end 6 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/SwipeCellKit/SwipeCellKit-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 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ALTableViewSwift/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwipeCellKit (2.5.0) 3 | 4 | DEPENDENCIES: 5 | - SwipeCellKit (= 2.5.0) 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - SwipeCellKit 10 | 11 | SPEC CHECKSUMS: 12 | SwipeCellKit: d8f2617538ce3021cb0a11d1b93856a06a2f2e20 13 | 14 | PODFILE CHECKSUM: a24e7a1ed9e3bea698885fc35383601a3a902f5d 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwipeCellKit (2.5.0) 3 | 4 | DEPENDENCIES: 5 | - SwipeCellKit (= 2.5.0) 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - SwipeCellKit 10 | 11 | SPEC CHECKSUMS: 12 | SwipeCellKit: d8f2617538ce3021cb0a11d1b93856a06a2f2e20 13 | 14 | PODFILE CHECKSUM: a24e7a1ed9e3bea698885fc35383601a3a902f5d 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 6 | PODS_ROOT = ${SRCROOT}/../Pods 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 6 | PODS_ROOT = ${SRCROOT}/../Pods 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/SwipeCellKit/SwipeCellKit-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 SwipeCellKitVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char SwipeCellKitVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView-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_ALTableViewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ALTableViewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 6 | PODS_ROOT = ${SRCROOT}/../Pods 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 6 | PODS_ROOT = ${SRCROOT}/../Pods 7 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView-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_TestALTableViewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_TestALTableViewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests-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_ALTableViewTestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ALTableViewTestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/SwipeCellKit/SwipeCellKit.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwipeCellKit 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwipeCellKit 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ALTableView.h 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 20/4/18. 6 | // Copyright © 2018 ALTableView. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ALTableView. 12 | FOUNDATION_EXPORT double ALTableViewVersionNumber; 13 | 14 | //! Project version string for ALTableView. 15 | FOUNDATION_EXPORT const unsigned char ALTableViewVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /ALTableViewSwift/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | 3 | platform :ios, '9.0' 4 | 5 | workspace 'ALTableView' 6 | use_frameworks! 7 | 8 | def app_pods 9 | project 'TestALTableView/TestALTableView.xcodeproj' 10 | pod 'SwipeCellKit', '2.5.0' 11 | end 12 | 13 | def framework_pods 14 | project 'ALTableView/ALTableView.xcodeproj' 15 | end 16 | 17 | target 'ALTableView' do 18 | 19 | framework_pods 20 | # Pods for ALTableView 21 | 22 | target 'ALTableViewTests' do 23 | inherit! :search_paths 24 | # Pods for testing 25 | end 26 | 27 | end 28 | 29 | target 'TestALTableView' do 30 | app_pods 31 | end 32 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Orders/Styles.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Styles.swift 3 | // BimbaYLola 4 | // 5 | // Created by lorenzo villarroel perez on 25/9/18. 6 | // Copyright © 2018 BimbaYLola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct TextStyles { 12 | 13 | 14 | static func ordersElement(text: String) -> TextConfigurable { 15 | return TextConfigurable(text: text, font: UIFont.systemFont(ofSize: 14), color: .black, alignment: .left) 16 | } 17 | 18 | static func ordersElementDate(text: String) -> TextConfigurable { 19 | return TextConfigurable(text: text, font: UIFont.systemFont(ofSize: 14), color: .black, alignment: .left) 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Orders/Loading/LoadingTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoadingTableViewCell.swift 3 | // bimbaylola 4 | // 5 | // Created by lorenzo villarroel perez on 20/12/2018. 6 | // Copyright © 2018 BimbaYLola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ALTableView 11 | 12 | class LoadingTableViewCell: UITableViewCell, ALCellProtocol { 13 | 14 | class var nib: String { 15 | return "LoadingTableViewCell" 16 | } 17 | class var reuseIdentifier: String { 18 | return "LoadingTableViewCellReuseIdentifier" 19 | } 20 | 21 | @IBOutlet weak var activityIndicator: UIActivityIndicatorView! 22 | 23 | func cellCreated(dataObject: Any?) { 24 | activityIndicator.startAnimating() 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwipeCellKit" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SwipeCellKit/SwipeCellKit.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "SwipeCellKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 11 | PODS_ROOT = ${SRCROOT}/../Pods 12 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwipeCellKit" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SwipeCellKit/SwipeCellKit.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "SwipeCellKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 11 | PODS_ROOT = ${SRCROOT}/../Pods 12 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeAccessibilityCustomAction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeAccessibilityCustomAction.swift 3 | // SwipeCellKit 4 | // 5 | // Created by Jeremy Koch 6 | // Copyright © 2017 Jeremy Koch. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SwipeAccessibilityCustomAction: UIAccessibilityCustomAction { 12 | let action: SwipeAction 13 | let indexPath: IndexPath 14 | 15 | init(action: SwipeAction, indexPath: IndexPath, target: Any, selector: Selector) { 16 | 17 | self.action = action 18 | self.indexPath = indexPath 19 | 20 | let name = action.accessibilityLabel ?? action.title ?? action.image?.accessibilityIdentifier ?? "" 21 | 22 | super.init(name: name, target: target, selector: selector) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 0.3.6 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/SwipeCellKit/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.5.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView-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 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests-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 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Elements/Section/ALSectionElementFooter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALSectionElementFooter.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 26/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension ALSectionElement { 12 | 13 | //MARK: - Getters 14 | 15 | internal func getFooterFrom(tableView: UITableView) -> UIView? { 16 | 17 | return self.footerElement?.getViewFrom(tableView: tableView) 18 | } 19 | 20 | internal func getFooterElement() -> ALHeaderFooterElement? { 21 | 22 | return self.footerElement 23 | } 24 | 25 | internal func getFooterHeight() -> CGFloat { 26 | 27 | return self.footerElement?.getHeight() ?? 0.0 28 | } 29 | 30 | internal func getFooterEstimatedHeight() -> CGFloat { 31 | 32 | return self.footerElement?.getEstimatedHeight() ?? 0.0 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/Swipeable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Swipeable.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: - Internal 11 | 12 | protocol Swipeable { 13 | var state: SwipeState { get set } 14 | 15 | var actionsView: SwipeActionsView? { get set } 16 | 17 | var frame: CGRect { get } 18 | 19 | var scrollView: UIScrollView? { get } 20 | 21 | var indexPath: IndexPath? { get } 22 | 23 | var panGestureRecognizer: UIGestureRecognizer { get } 24 | } 25 | 26 | extension SwipeTableViewCell: Swipeable {} 27 | extension SwipeCollectionViewCell: Swipeable {} 28 | 29 | enum SwipeState: Int { 30 | case center = 0 31 | case left 32 | case right 33 | case dragging 34 | case animatingToCenter 35 | 36 | init(orientation: SwipeActionsOrientation) { 37 | self = orientation == .left ? .left : .right 38 | } 39 | 40 | var isActive: Bool { return self != .center } 41 | } 42 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/ALTableView/ALTableViewDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALTableViewDataSource.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 16/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | //MARK: - UITableViewDataSource 12 | 13 | extension ALTableView: UITableViewDataSource { 14 | 15 | public func numberOfSections(in tableView: UITableView) -> Int { 16 | 17 | return self.sectionElements.count 18 | } 19 | 20 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 21 | 22 | return self.getSectionElementAt(index: section)?.getNumberOfRows() ?? 0 23 | } 24 | 25 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 26 | 27 | return self.getSectionElementAt(index: indexPath.section)?.getCellViewFrom(row: indexPath.row, tableView: tableView) ?? UITableViewCell() 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Master/Master2TableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Master2TableViewCell.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 14/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ALTableView 11 | 12 | class Master2TableViewCell: UITableViewCell, ALCellProtocol { 13 | 14 | static let nib = "Master2TableViewCell" 15 | static let reuseIdentifier = "Master2TableViewCellReuseIdentifier" 16 | 17 | @IBOutlet weak var label: UILabel! 18 | override func awakeFromNib() { 19 | super.awakeFromNib() 20 | // Initialization code 21 | } 22 | 23 | override func setSelected(_ selected: Bool, animated: Bool) { 24 | super.setSelected(selected, animated: animated) 25 | 26 | // Configure the view for the selected state 27 | } 28 | 29 | public func cellCreated(dataObject: Any?) { 30 | if let title = dataObject as? Int { 31 | self.label.text = String(title) 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ALiOSDev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2017 Jeremy Koch 3 | 4 | http://jerkoch.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableViewTests/ALTableViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALTableViewTests.swift 3 | // ALTableViewTests 4 | // 5 | // Created by lorenzo villarroel perez on 7/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import ALTableView 11 | 12 | class ALTableViewTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/DetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.swift 3 | // TestALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 20/4/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DetailViewController: UIViewController { 12 | 13 | @IBOutlet weak var detailDescriptionLabel: UILabel! 14 | 15 | 16 | func configureView() { 17 | // Update the user interface for the detail item. 18 | if let detail = detailItem { 19 | if let label = detailDescriptionLabel { 20 | label.text = detail.description 21 | } 22 | } 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | // Do any additional setup after loading the view, typically from a nib. 28 | configureView() 29 | } 30 | 31 | override func didReceiveMemoryWarning() { 32 | super.didReceiveMemoryWarning() 33 | // Dispose of any resources that can be recreated. 34 | } 35 | 36 | var detailItem: NSDate? { 37 | didSet { 38 | // Update the view. 39 | configureView() 40 | } 41 | } 42 | 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Master/MasterHeaderFooter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MasterHeaderFooter.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 22/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ALTableView 11 | 12 | class MasterHeaderFooter: UITableViewHeaderFooterView, ALHeaderFooterProtocol { 13 | 14 | static let nib = "MasterHeaderFooter" 15 | static let reuseIdentifier = "MasterHeaderFooterReuseIdentifier" 16 | 17 | @IBOutlet weak var labelText: UILabel! 18 | /* 19 | // Only override draw() if you perform custom drawing. 20 | // An empty implementation adversely affects performance during animation. 21 | override func draw(_ rect: CGRect) { 22 | // Drawing code 23 | } 24 | */ 25 | 26 | func viewCreated(dataObject: Any?) { 27 | if let title: String = dataObject as? String { 28 | self.labelText.text = title 29 | } 30 | 31 | if #available(iOS 10.0, *) { 32 | self.contentView.backgroundColor = .green 33 | } else { 34 | self.backgroundView = UIView() 35 | self.backgroundView?.backgroundColor = .green 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Elements/ALElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALElement.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 20/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class ALElement { 12 | 13 | internal var estimateHeightMode: Bool 14 | internal var height: CGFloat 15 | internal let identifier: String 16 | internal let dataObject: Any? 17 | 18 | 19 | init(identifier: String, dataObject: Any?, estimateHeightMode: Bool, height: CGFloat) { 20 | 21 | self.identifier = identifier 22 | self.dataObject = dataObject 23 | self.estimateHeightMode = estimateHeightMode 24 | self.height = height 25 | } 26 | 27 | //MARK: - Getters 28 | 29 | internal func getDataObject() -> Any? { 30 | 31 | return self.dataObject 32 | } 33 | 34 | internal func getEstimatedHeight() -> CGFloat { 35 | 36 | return self.height 37 | } 38 | 39 | internal func getHeight() -> CGFloat { 40 | if self.estimateHeightMode { 41 | return UITableView.automaticDimension 42 | } 43 | return self.height 44 | } 45 | 46 | internal func isEstimateHeightMode() -> Bool { 47 | 48 | return self.estimateHeightMode 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwipeCellKit 5 | 6 | MIT License 7 | Copyright (c) 2017 Jeremy Koch 8 | 9 | http://jerkoch.com 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeFeedback.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeFeedback.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | final class SwipeFeedback { 11 | enum Style { 12 | case light 13 | case medium 14 | case heavy 15 | } 16 | 17 | @available(iOS 10.0.1, *) 18 | private var feedbackGenerator: UIImpactFeedbackGenerator? { 19 | get { 20 | return _feedbackGenerator as? UIImpactFeedbackGenerator 21 | } 22 | set { 23 | _feedbackGenerator = newValue 24 | } 25 | } 26 | 27 | private var _feedbackGenerator: Any? 28 | 29 | init(style: Style) { 30 | if #available(iOS 10.0.1, *) { 31 | switch style { 32 | case .light: 33 | feedbackGenerator = UIImpactFeedbackGenerator(style: .light) 34 | case .medium: 35 | feedbackGenerator = UIImpactFeedbackGenerator(style: .medium) 36 | case .heavy: 37 | feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy) 38 | } 39 | } else { 40 | _feedbackGenerator = nil 41 | } 42 | } 43 | 44 | func prepare() { 45 | if #available(iOS 10.0.1, *) { 46 | feedbackGenerator?.prepare() 47 | } 48 | } 49 | 50 | func impactOccurred() { 51 | if #available(iOS 10.0.1, *) { 52 | feedbackGenerator?.impactOccurred() 53 | } 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/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 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/ALTableView/ALTableViewPullToRefresh.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALTableViewPullToRefresh.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 24/4/18. 6 | // Copyright © 2018 ALTableView. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension ALTableView { 12 | 13 | private static let refreshControlTag = 1000 14 | 15 | public func addPullToRefresh(title: NSAttributedString = NSAttributedString(string: ""), backgroundColor: UIColor = .clear, tintColor: UIColor = .black) { 16 | 17 | if let tableView = self.tableView { 18 | let refreshControl: UIRefreshControl = UIRefreshControl() 19 | refreshControl.backgroundColor = backgroundColor 20 | refreshControl.tintColor = tintColor 21 | refreshControl.addTarget(self, action: #selector(refreshTriggered(_:)), for: .valueChanged) 22 | refreshControl.attributedTitle = title 23 | 24 | if #available(iOS 10.0, *) { 25 | tableView.refreshControl = refreshControl 26 | } else { 27 | refreshControl.tag = ALTableView.refreshControlTag 28 | tableView.addSubview(refreshControl) 29 | } 30 | } 31 | } 32 | 33 | @objc private func refreshTriggered(_ sender: Any) { 34 | 35 | self.delegate?.tableViewPullToRefresh?() 36 | if let tableView = self.tableView { 37 | if #available(iOS 10.0, *) { 38 | tableView.refreshControl?.endRefreshing() 39 | } else { 40 | if let refreshControl = tableView.viewWithTag(ALTableView.refreshControlTag) as? UIRefreshControl { 41 | refreshControl.endRefreshing() 42 | } 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Orders/LoadingRetry/LoadingRetryTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoadingRetryTableViewCell.swift 3 | // BimbaYLola 4 | // 5 | // Created by lorenzo villarroel perez on 20/12/2018. 6 | // Copyright © 2018 BimbaYLola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ALTableView 11 | 12 | class LoadingRetryTableViewCell: UITableViewCell, ALCellProtocol { 13 | 14 | @IBOutlet weak var btShowMore: SecondaryButton! 15 | 16 | class var nib: String { 17 | return "LoadingRetryTableViewCell" 18 | } 19 | class var reuseIdentifier: String { 20 | return "LoadingRetryTableViewCellReuseIdentifier" 21 | } 22 | 23 | func cellCreated(dataObject: Any?) { 24 | btShowMore.isUserInteractionEnabled = false 25 | btShowMore.setTitle("PRODUCTS_GRID_SHOW_MORE", for: .normal) 26 | } 27 | 28 | } 29 | 30 | class SecondaryButton: UIButton { 31 | 32 | override var intrinsicContentSize: CGSize { 33 | get { 34 | let baseSize = super.intrinsicContentSize 35 | return CGSize(width: baseSize.width + titleEdgeInsets.left + titleEdgeInsets.right, 36 | height: baseSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom) 37 | } 38 | set { 39 | 40 | } 41 | } 42 | 43 | override func awakeFromNib() { 44 | super.awakeFromNib() 45 | 46 | setTitleColor(.black, for: .normal) 47 | titleLabel?.font = UIFont.systemFont(ofSize: 15.0) 48 | 49 | backgroundColor = .white 50 | 51 | layer.borderWidth = 1.0 52 | layer.borderColor = UIColor.black.cgColor 53 | 54 | titleEdgeInsets = UIEdgeInsets(top: 0.0, left: 16.0, bottom: 0.0, right: 16.0) 55 | 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 0.3.6 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIStatusBarTintParameters 32 | 33 | UINavigationBar 34 | 35 | Style 36 | UIBarStyleDefault 37 | Translucent 38 | 39 | 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | UISupportedInterfaceOrientations~ipad 48 | 49 | UIInterfaceOrientationPortrait 50 | UIInterfaceOrientationPortraitUpsideDown 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /ALTableView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ALTableView.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 http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = "ALTableView" 11 | s.version = "0.3.6" 12 | s.summary = "An easy way to manage UITableView and UITableViewController" 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 framework is a generic UITableViewDataSource and UITableViewDelegate which will help you to reduce all the code you have to copy-paste everytime you create a tableView. For doing that you only need to create SectionElement array and for each one a RowElement array. 22 | DESC 23 | 24 | s.homepage = "https://github.com/ALiOSDev/ALTableView.git" 25 | s.license = "MIT" 26 | 27 | s.author = "Abimael Barea, Lorenzo Villarroel" 28 | s.swift_version = '4.2' 29 | 30 | s.platform = :ios, "9.0" 31 | 32 | s.source = { :git => "https://github.com/ALiOSDev/ALTableView.git", :tag => "#{s.version}"} 33 | 34 | # s.social_media_url = 'https://twitter.com/ALTableView' 35 | 36 | s.ios.deployment_target = '9.0' 37 | 38 | s.source_files = 'ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/**/*.{swift,h,m}' 39 | 40 | # s.resource_bundles = { 41 | # 'ALTableView' => ['ALTableView/Assets/*.png'] 42 | # } 43 | 44 | # s.public_header_files = 'Pod/Classes/**/*.h' 45 | # s.frameworks = 'UIKit', 'MapKit' 46 | # s.dependency 'AFNetworking', '~> 2.3' 47 | 48 | end 49 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Master/MasterTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MasterTableViewCell.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 10/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ALTableView 11 | import SwipeCellKit 12 | 13 | class MasterTableViewCell: SwipeTableViewCell, ALCellProtocol { 14 | 15 | static let nib = "MasterTableViewCell" 16 | static let reuseIdentifier = "MasterTableViewCellReuseIdentifier" 17 | 18 | @IBOutlet weak var labelText: UILabel! 19 | 20 | public func cellCreated(dataObject: Any?) { 21 | if let title = dataObject as? String { 22 | self.labelText.text = title 23 | } 24 | delegate = self 25 | } 26 | 27 | public func cellPressed(viewController: UIViewController?) { 28 | self.labelText.text = "Tapped" 29 | } 30 | 31 | func cellDeselected() { 32 | self.labelText.text = "Deselected" 33 | } 34 | 35 | } 36 | 37 | extension MasterTableViewCell: SwipeTableViewCellDelegate { 38 | 39 | func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? { 40 | var actions = [SwipeAction]() 41 | switch orientation { 42 | case .right: 43 | let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in 44 | print("cell deleted") 45 | // handle action by updating model with deletion 46 | } 47 | actions.append(deleteAction) 48 | break 49 | case .left: 50 | let wishlistAction = SwipeAction(style: .default, title: "Wishlist") { action, indexPath in 51 | print("cell wishlist") 52 | // handle action by updating model with deletion 53 | } 54 | wishlistAction.backgroundColor = .blue 55 | actions.append(wishlistAction) 56 | break 57 | } 58 | 59 | return actions 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/ALTableView/ALTableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALTableView.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 7/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @objc public protocol ALTableViewProtocol: class { 12 | @objc optional func tableViewPullToRefresh() 13 | @objc optional func tableViewDidReachEnd() 14 | } 15 | 16 | public class ALTableView: NSObject { 17 | 18 | //MARK: - Properties 19 | 20 | internal var sectionElements: Array 21 | public weak var delegate: ALTableViewProtocol? 22 | public weak var editingDelegate: ALTableViewRowEditingProtocol? 23 | public weak var viewController: UIViewController? 24 | public weak var tableView: UITableView? 25 | public var movingRowsAllowed: Bool 26 | 27 | 28 | //MARK: - Initializers 29 | 30 | public init(sectionElements: Array, 31 | viewController: UIViewController, 32 | tableView: UITableView, 33 | movingRowsAllowed: Bool = false) { 34 | 35 | self.sectionElements = sectionElements 36 | self.movingRowsAllowed = movingRowsAllowed 37 | super.init() 38 | self.viewController = viewController 39 | tableView.delegate = self 40 | tableView.dataSource = self 41 | self.tableView = tableView 42 | self.sectionElements.forEach { (sectionElement: ALSectionElement) in 43 | sectionElement.delegate = self 44 | } 45 | 46 | } 47 | 48 | //MARK: - Public methods 49 | 50 | public func registerCell(nibName: String, reuseIdentifier: String) { 51 | let nib = UINib(nibName: nibName, bundle: nil) 52 | self.tableView?.register(nib, forCellReuseIdentifier: reuseIdentifier) 53 | } 54 | 55 | public func registerHeaderFooter(nibName: String, reuseIdentifier: String) { 56 | let nib = UINib(nibName: nibName, bundle: nil) 57 | self.tableView?.register(nib, forHeaderFooterViewReuseIdentifier: reuseIdentifier) 58 | } 59 | 60 | //MARK: - Private methods 61 | 62 | 63 | } 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Elements/Section/ALSectionElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SectionElement.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 7/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | //Implemented by ALSectionManager 12 | protocol ALSectionHeaderViewDelegate: class { 13 | func sectionOpened(sectionElement: ALSectionElement) 14 | func sectionClosed(sectionElement: ALSectionElement) 15 | } 16 | 17 | public class ALSectionElement { 18 | 19 | //MARK: - Properties 20 | 21 | internal let headerElement: ALHeaderFooterElement? 22 | internal let footerElement: ALHeaderFooterElement? 23 | 24 | internal var isOpened: Bool = true 25 | internal let isExpandable: Bool 26 | 27 | internal var headerTapGesture: UITapGestureRecognizer? 28 | internal var rowElements: Array 29 | 30 | internal weak var delegate: ALSectionHeaderViewDelegate? 31 | 32 | //MARK: - Initializers 33 | 34 | public init(rowElements: Array, headerElement: ALHeaderFooterElement?, footerElement: ALHeaderFooterElement?, headerHeight: CGFloat = 0, footerHeight: CGFloat = 0, isExpandable: Bool = false) { 35 | 36 | self.headerElement = headerElement 37 | self.footerElement = footerElement 38 | self.isExpandable = isExpandable 39 | self.rowElements = rowElements 40 | } 41 | 42 | //MARK: - Getters 43 | 44 | public func getNumberOfRows() -> Int { 45 | 46 | if self.isOpened { 47 | return self.rowElements.count 48 | } else { 49 | return 0 50 | } 51 | } 52 | 53 | public func getNumberOfRealRows() -> Int { 54 | 55 | return self.rowElements.count 56 | } 57 | 58 | } 59 | 60 | //MARK: - Equatable 61 | 62 | extension ALSectionElement: Equatable { 63 | 64 | public static func ==(lhs: ALSectionElement, rhs: ALSectionElement) -> Bool { 65 | 66 | return lhs === rhs 67 | } 68 | } 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView-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 | MIT License 18 | Copyright (c) 2017 Jeremy Koch 19 | 20 | http://jerkoch.com 21 | 22 | Permission is hereby granted, free of charge, to any person obtaining a copy 23 | of this software and associated documentation files (the "Software"), to deal 24 | in the Software without restriction, including without limitation the rights 25 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 26 | copies of the Software, and to permit persons to whom the Software is 27 | furnished to do so, subject to the following conditions: 28 | 29 | The above copyright notice and this permission notice shall be included in all 30 | copies or substantial portions of the Software. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 35 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 37 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 38 | SOFTWARE. 39 | License 40 | MIT 41 | Title 42 | SwipeCellKit 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/ALTableView/ALTableViewEditingManaging.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALTableViewEditingManaging.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 20/4/18. 6 | // Copyright © 2018 ALTableView. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol ALTableViewRowEditingProtocol: class { 12 | func rowMoved(from sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) 13 | func rowDeleted(indexPath: IndexPath, dataObject: Any?) 14 | } 15 | 16 | extension ALTableView { 17 | 18 | public func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 19 | 20 | return movingRowsAllowed 21 | } 22 | 23 | public func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { 24 | 25 | let originSection = self.getSectionElementAt(index: sourceIndexPath.section) 26 | let destinationSection = self.getSectionElementAt(index: destinationIndexPath.section) 27 | 28 | if let originRowElement = originSection?.getRowElementAt(index: sourceIndexPath.row) { 29 | originSection?.deleteRowElements(numberOfRowElements: 1, at: .middle(sourceIndexPath.row)) 30 | destinationSection?.insert(rowElements: [originRowElement], at: .middle(destinationIndexPath.row)) 31 | editingDelegate?.rowMoved(from: sourceIndexPath, to: destinationIndexPath) 32 | } 33 | } 34 | 35 | public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 36 | let canEditRow = self.getSectionElementAt(index: indexPath.section)?.getRowElementAt(index: indexPath.row)?.editingAllowed ?? false 37 | return canEditRow 38 | } 39 | 40 | public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 41 | 42 | switch editingStyle { 43 | case .delete: 44 | if self.remove(at: indexPath, animation: .automatic) { 45 | let dataObject = self.getSectionElementAt(index: indexPath.section)?.getRowElementAt(index: indexPath.row)?.getDataObject() 46 | editingDelegate?.rowDeleted(indexPath: indexPath, dataObject: dataObject) 47 | } 48 | 49 | default: 50 | break 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Elements/Section/ALSectionElementRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALSectionElementRow.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 26/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | //MARK: - Getters 12 | extension ALSectionElement { 13 | 14 | //MARK: - Get Cell View 15 | 16 | internal func getCellViewFrom(row: Int, tableView: UITableView) -> UITableViewCell? { 17 | 18 | return self.getRowElementAt(index: row)?.getViewFrom(tableView: tableView) 19 | } 20 | 21 | //MARK: - Managing height of cells 22 | 23 | internal func setRowElementHeight(row: Int, height: CGFloat) -> Void { 24 | 25 | self.getRowElementAt(index: row)?.setCellHeight(height: height) 26 | } 27 | 28 | internal func getRowHeight(at index: Int) -> CGFloat { 29 | 30 | return self.getRowElementAt(index: index)?.getHeight() ?? 0.0 31 | } 32 | 33 | internal func getRowEstimatedHeight(at index: Int) -> CGFloat { 34 | 35 | return self.getRowElementAt(index: index)?.getEstimatedHeight() ?? 0.0 36 | } 37 | 38 | //MARK: - Managing the insertion of new cells 39 | 40 | @discardableResult internal func insert(rowElements: Array, at position: ALPosition) -> Bool { 41 | 42 | return self.rowElements.safeInsert(contentsOf: rowElements, at: position) 43 | } 44 | 45 | //MARK: - Managing the deletion of new cells 46 | 47 | @discardableResult internal func deleteRowElements(numberOfRowElements: Int, at position: ALPosition) -> Bool { 48 | 49 | return self.rowElements.safeDelete(numberOfElements: numberOfRowElements, at:position) 50 | } 51 | 52 | //MARK: - Managing the replacement of new cells 53 | 54 | @discardableResult internal func replace(rowElements: Array, at position: ALPosition) -> Bool { 55 | 56 | return self.rowElements.safeReplace(contentsOf: rowElements, at: position) 57 | } 58 | 59 | //MARK: - Cell events 60 | 61 | internal func rowElementPressed(row: Int, viewController: UIViewController?, cell: UITableViewCell) { 62 | 63 | self.getRowElementAt(index: row)?.rowElementPressed(viewController: viewController, cell: cell) 64 | } 65 | 66 | internal func rowElementDeselected(row: Int, cell: UITableViewCell) { 67 | 68 | self.getRowElementAt(index: row)?.rowElementDeselected(cell: cell) 69 | } 70 | } 71 | 72 | //MARK: - Support methods 73 | 74 | extension ALSectionElement { 75 | 76 | public func getRowElementAt(index: Int) -> ALRowElement? { 77 | 78 | return self.rowElements[ALSafe: index] 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeTableViewCell+Display.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeTableViewCell+Display.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | extension SwipeTableViewCell { 11 | /// The point at which the origin of the cell is offset from the non-swiped origin. 12 | public var swipeOffset: CGFloat { 13 | set { setSwipeOffset(newValue, animated: false) } 14 | get { return frame.midX - bounds.midX } 15 | } 16 | 17 | /** 18 | Hides the swipe actions and returns the cell to center. 19 | 20 | - parameter animated: Specify `true` to animate the hiding of the swipe actions or `false` to hide it immediately. 21 | 22 | - parameter completion: The closure to be executed once the animation has finished. A `Boolean` argument indicates whether or not the animations actually finished before the completion handler was called. 23 | */ 24 | public func hideSwipe(animated: Bool, completion: ((Bool) -> Void)? = nil) { 25 | swipeController.hideSwipe(animated: animated, completion: completion) 26 | } 27 | 28 | /** 29 | Shows the swipe actions for the specified orientation. 30 | 31 | - parameter orientation: The side of the cell on which to show the swipe actions. 32 | 33 | - parameter animated: Specify `true` to animate the showing of the swipe actions or `false` to show them immediately. 34 | 35 | - parameter completion: The closure to be executed once the animation has finished. A `Boolean` argument indicates whether or not the animations actually finished before the completion handler was called. 36 | */ 37 | public func showSwipe(orientation: SwipeActionsOrientation, animated: Bool = true, completion: ((Bool) -> Void)? = nil) { 38 | setSwipeOffset(.greatestFiniteMagnitude * orientation.scale * -1, 39 | animated: animated, 40 | completion: completion) 41 | } 42 | 43 | /** 44 | The point at which the origin of the cell is offset from the non-swiped origin. 45 | 46 | - parameter offset: A point (expressed in points) that is offset from the non-swiped origin. 47 | 48 | - parameter animated: Specify `true` to animate the transition to the new offset, `false` to make the transition immediate. 49 | 50 | - parameter completion: The closure to be executed once the animation has finished. A `Boolean` argument indicates whether or not the animations actually finished before the completion handler was called. 51 | */ 52 | public func setSwipeOffset(_ offset: CGFloat, animated: Bool = true, completion: ((Bool) -> Void)? = nil) { 53 | swipeController.setSwipeOffset(offset, animated: animated, completion: completion) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Elements/Section/ALSectionElementHeader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALSectionElementHeader.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 26/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension ALSectionElement { 12 | 13 | //MARK: - Getters 14 | 15 | internal func getHeaderFrom(tableView: UITableView) -> UIView? { 16 | 17 | guard let viewHeader = self.headerElement?.getViewFrom(tableView: tableView) else { 18 | return nil 19 | } 20 | self.setUpHeaderRecognizer(viewHeader: viewHeader) 21 | return viewHeader 22 | } 23 | 24 | internal func getHeaderElement() -> ALHeaderFooterElement? { 25 | 26 | return self.headerElement 27 | } 28 | 29 | internal func getHeaderHeight() -> CGFloat { 30 | 31 | return self.headerElement?.getHeight() ?? 0.0 32 | } 33 | 34 | internal func getHeaderEstimatedHeight() -> CGFloat { 35 | 36 | return self.headerElement?.getEstimatedHeight() ?? 0.0 37 | } 38 | 39 | } 40 | 41 | //MARK: - Managing the opening and close of section 42 | 43 | extension ALSectionElement { 44 | 45 | fileprivate func setUpHeaderRecognizer (viewHeader: UIView) -> Void { 46 | if let headerTapGesture = self.headerTapGesture { 47 | viewHeader.removeGestureRecognizer(headerTapGesture) 48 | self.headerTapGesture = nil 49 | } 50 | if self.headerTapGesture == nil { 51 | self.headerTapGesture = UITapGestureRecognizer(target: self, action: #selector(self.toggleOpen(sender:))) 52 | if let headerTapGesture = self.headerTapGesture { 53 | viewHeader.isUserInteractionEnabled = true 54 | viewHeader.addGestureRecognizer(headerTapGesture) 55 | } 56 | } 57 | } 58 | 59 | @objc func toggleOpen(sender: Any) { 60 | if let tapGesture = sender as? UITapGestureRecognizer, 61 | let headerView = tapGesture.view as? UITableViewHeaderFooterView { 62 | self.headerElement?.headerFooterElementPressed(view: headerView) 63 | } 64 | if self.isExpandable { 65 | self.toggleOpenWith(userAction: true) 66 | } 67 | } 68 | 69 | func toggleOpenWith(userAction: Bool) { 70 | 71 | guard let delegate = self.delegate else { 72 | return 73 | } 74 | self.isOpened = !self.isOpened 75 | if userAction { 76 | if self.isOpened { 77 | delegate.sectionOpened(sectionElement: self) 78 | } else { 79 | delegate.sectionClosed(sectionElement: self) 80 | } 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeCollectionViewCell+Display.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeCollectionViewCell+Display.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | extension SwipeCollectionViewCell { 11 | /// The point at which the origin of the cell is offset from the non-swiped origin. 12 | public var swipeOffset: CGFloat { 13 | set { setSwipeOffset(newValue, animated: false) } 14 | get { return contentView.frame.midX - bounds.midX } 15 | } 16 | 17 | /** 18 | Hides the swipe actions and returns the cell to center. 19 | 20 | - parameter animated: Specify `true` to animate the hiding of the swipe actions or `false` to hide it immediately. 21 | 22 | - parameter completion: The closure to be executed once the animation has finished. A `Boolean` argument indicates whether or not the animations actually finished before the completion handler was called. 23 | */ 24 | public func hideSwipe(animated: Bool, completion: ((Bool) -> Void)? = nil) { 25 | swipeController.hideSwipe(animated: animated, completion: completion) 26 | } 27 | 28 | /** 29 | Shows the swipe actions for the specified orientation. 30 | 31 | - parameter orientation: The side of the cell on which to show the swipe actions. 32 | 33 | - parameter animated: Specify `true` to animate the showing of the swipe actions or `false` to show them immediately. 34 | 35 | - parameter completion: The closure to be executed once the animation has finished. A `Boolean` argument indicates whether or not the animations actually finished before the completion handler was called. 36 | */ 37 | public func showSwipe(orientation: SwipeActionsOrientation, animated: Bool = true, completion: ((Bool) -> Void)? = nil) { 38 | setSwipeOffset(.greatestFiniteMagnitude * orientation.scale * -1, 39 | animated: animated, 40 | completion: completion) 41 | } 42 | 43 | /** 44 | The point at which the origin of the cell is offset from the non-swiped origin. 45 | 46 | - parameter offset: A point (expressed in points) that is offset from the non-swiped origin. 47 | 48 | - parameter animated: Specify `true` to animate the transition to the new offset, `false` to make the transition immediate. 49 | 50 | - parameter completion: The closure to be executed once the animation has finished. A `Boolean` argument indicates whether or not the animations actually finished before the completion handler was called. 51 | */ 52 | public func setSwipeOffset(_ offset: CGFloat, animated: Bool = true, completion: ((Bool) -> Void)? = nil) { 53 | swipeController.setSwipeOffset(offset, animated: animated, completion: completion) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Orders/Loading/LoadingTableViewCell.xib: -------------------------------------------------------------------------------- 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 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UITableView { 11 | var swipeCells: [SwipeTableViewCell] { 12 | return visibleCells.compactMap({ $0 as? SwipeTableViewCell }) 13 | } 14 | 15 | func hideSwipeCell() { 16 | swipeCells.forEach { $0.hideSwipe(animated: true) } 17 | } 18 | } 19 | 20 | extension UICollectionView { 21 | var swipeCells: [SwipeCollectionViewCell] { 22 | return visibleCells as? [SwipeCollectionViewCell] ?? [] 23 | } 24 | 25 | func hideSwipeCell() { 26 | swipeCells.forEach { $0.hideSwipe(animated: true) } 27 | } 28 | 29 | func setGestureEnabled(_ enabled: Bool) { 30 | gestureRecognizers?.forEach { 31 | guard $0 != panGestureRecognizer else { return } 32 | 33 | $0.isEnabled = enabled 34 | } 35 | } 36 | } 37 | 38 | extension UIScrollView { 39 | var swipeables: [Swipeable] { 40 | switch self { 41 | case let tableView as UITableView: 42 | return tableView.swipeCells 43 | case let collectionView as UICollectionView: 44 | return collectionView.swipeCells 45 | default: 46 | return [] 47 | } 48 | } 49 | 50 | func hideSwipeables() { 51 | switch self { 52 | case let tableView as UITableView: 53 | tableView.hideSwipeCell() 54 | case let collectionView as UICollectionView: 55 | collectionView.hideSwipeCell() 56 | default: 57 | return 58 | } 59 | } 60 | } 61 | 62 | extension UIPanGestureRecognizer { 63 | func elasticTranslation(in view: UIView?, withLimit limit: CGSize, fromOriginalCenter center: CGPoint, applyingRatio ratio: CGFloat = 0.20) -> CGPoint { 64 | let translation = self.translation(in: view) 65 | 66 | guard let sourceView = self.view else { 67 | return translation 68 | } 69 | 70 | let updatedCenter = CGPoint(x: center.x + translation.x, y: center.y + translation.y) 71 | let distanceFromCenter = CGSize(width: abs(updatedCenter.x - sourceView.bounds.midX), 72 | height: abs(updatedCenter.y - sourceView.bounds.midY)) 73 | 74 | let inverseRatio = 1.0 - ratio 75 | let scale: (x: CGFloat, y: CGFloat) = (updatedCenter.x < sourceView.bounds.midX ? -1 : 1, updatedCenter.y < sourceView.bounds.midY ? -1 : 1) 76 | let x = updatedCenter.x - (distanceFromCenter.width > limit.width ? inverseRatio * (distanceFromCenter.width - limit.width) * scale.x : 0) 77 | let y = updatedCenter.y - (distanceFromCenter.height > limit.height ? inverseRatio * (distanceFromCenter.height - limit.height) * scale.y : 0) 78 | 79 | return CGPoint(x: x, y: y) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeTableViewCell+Accessibility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeTableViewCell+Accessibility.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | extension SwipeTableViewCell { 11 | /// :nodoc: 12 | open override func accessibilityElementCount() -> Int { 13 | guard state != .center else { 14 | return super.accessibilityElementCount() 15 | } 16 | 17 | return 1 18 | } 19 | 20 | /// :nodoc: 21 | open override func accessibilityElement(at index: Int) -> Any? { 22 | guard state != .center else { 23 | return super.accessibilityElement(at: index) 24 | } 25 | 26 | return actionsView 27 | } 28 | 29 | /// :nodoc: 30 | open override func index(ofAccessibilityElement element: Any) -> Int { 31 | guard state != .center else { 32 | return super.index(ofAccessibilityElement: element) 33 | } 34 | 35 | return element is SwipeActionsView ? 0 : NSNotFound 36 | } 37 | } 38 | 39 | extension SwipeTableViewCell { 40 | /// :nodoc: 41 | open override var accessibilityCustomActions: [UIAccessibilityCustomAction]? { 42 | get { 43 | guard let tableView = tableView, let indexPath = tableView.indexPath(for: self) else { 44 | return super.accessibilityCustomActions 45 | } 46 | 47 | let leftActions = delegate?.tableView(tableView, editActionsForRowAt: indexPath, for: .left) ?? [] 48 | let rightActions = delegate?.tableView(tableView, editActionsForRowAt: indexPath, for: .right) ?? [] 49 | 50 | let actions = [rightActions.first, leftActions.first].compactMap({ $0 }) + rightActions.dropFirst() + leftActions.dropFirst() 51 | 52 | if actions.count > 0 { 53 | return actions.map({ SwipeAccessibilityCustomAction(action: $0, 54 | indexPath: indexPath, 55 | target: self, 56 | selector: #selector(performAccessibilityCustomAction(accessibilityCustomAction:))) }) 57 | } else { 58 | return super.accessibilityCustomActions 59 | } 60 | } 61 | 62 | set { 63 | super.accessibilityCustomActions = newValue 64 | } 65 | } 66 | 67 | @objc func performAccessibilityCustomAction(accessibilityCustomAction: SwipeAccessibilityCustomAction) -> Bool { 68 | guard let tableView = tableView else { return false } 69 | 70 | let swipeAction = accessibilityCustomAction.action 71 | 72 | swipeAction.handler?(swipeAction, accessibilityCustomAction.indexPath) 73 | 74 | if swipeAction.style == .destructive { 75 | tableView.deleteRows(at: [accessibilityCustomAction.indexPath], with: .fade) 76 | } 77 | 78 | return true 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Elements/HeaderFooter/ALHeaderFooterElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALHeaderFooterElement.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 20/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public typealias ALHeaderFooterPressedHandler = (UITableViewHeaderFooterView) -> Void 12 | public typealias ALHeaderFooterCreatedHandler = (Any?, UITableViewHeaderFooterView) -> Void 13 | public typealias ALHeaderFooterDeselectedHandler = (UITableViewHeaderFooterView) -> Void 14 | 15 | //Implemented by ALHeaderFooterElement 16 | public protocol ALHeaderFooterElementProtocol { 17 | func headerFooterElementPressed(view: UITableViewHeaderFooterView) 18 | } 19 | 20 | //Implemented by UITableViewCell 21 | public protocol ALHeaderFooterProtocol { 22 | func viewPressed () -> Void 23 | func viewCreated(dataObject: Any?) -> Void 24 | } 25 | 26 | extension ALHeaderFooterProtocol { 27 | public func viewPressed () -> Void { 28 | 29 | } 30 | 31 | public func viewCreated(dataObject: Any?) -> Void { 32 | print("ALHeaderFooterProtocol") 33 | } 34 | } 35 | 36 | public class ALHeaderFooterElement: ALElement, ALHeaderFooterElementProtocol { 37 | 38 | private var pressedHandler: ALHeaderFooterPressedHandler? 39 | private var createdHandler: ALHeaderFooterCreatedHandler? 40 | 41 | //MARK: - Initializers 42 | 43 | public init(identifier: String, dataObject: Any, estimateHeightMode: Bool = false, height: CGFloat = 44.0, pressedHandler: ALHeaderFooterPressedHandler? = nil, createdHandler: ALHeaderFooterCreatedHandler? = nil) { 44 | 45 | self.pressedHandler = pressedHandler 46 | self.createdHandler = createdHandler 47 | super.init(identifier: identifier, dataObject: dataObject, estimateHeightMode: estimateHeightMode, height: height) 48 | } 49 | 50 | //MARK: - Getters 51 | 52 | internal func getViewFrom(tableView: UITableView) -> UITableViewHeaderFooterView { 53 | 54 | guard let dequeuedElement: UITableViewHeaderFooterView = tableView.dequeueReusableHeaderFooterView(withIdentifier: self.identifier) else { 55 | return UITableViewHeaderFooterView() 56 | } 57 | if let alHeaderFooter = dequeuedElement as? ALHeaderFooterProtocol { 58 | alHeaderFooter.viewCreated(dataObject: self.dataObject) 59 | } 60 | if let handler:ALHeaderFooterCreatedHandler = self.createdHandler { 61 | handler(self.dataObject, dequeuedElement) 62 | } 63 | return dequeuedElement 64 | } 65 | 66 | //MARK: - ALHeaderFooterElementProtocol 67 | 68 | public func headerFooterElementPressed(view: UITableViewHeaderFooterView) { 69 | 70 | if let view: ALHeaderFooterProtocol = view as? ALHeaderFooterProtocol { 71 | view.viewPressed() 72 | } 73 | 74 | if let handler:ALHeaderFooterPressedHandler = self.pressedHandler { 75 | handler(view) 76 | } 77 | } 78 | } 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeCollectionViewCell+Accessibility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeCollectionViewCell+Accessibility.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | extension SwipeCollectionViewCell { 11 | /// :nodoc: 12 | open override func accessibilityElementCount() -> Int { 13 | guard state != .center else { 14 | return super.accessibilityElementCount() 15 | } 16 | 17 | return 1 18 | } 19 | 20 | /// :nodoc: 21 | open override func accessibilityElement(at index: Int) -> Any? { 22 | guard state != .center else { 23 | return super.accessibilityElement(at: index) 24 | } 25 | 26 | return actionsView 27 | } 28 | 29 | /// :nodoc: 30 | open override func index(ofAccessibilityElement element: Any) -> Int { 31 | guard state != .center else { 32 | return super.index(ofAccessibilityElement: element) 33 | } 34 | 35 | return element is SwipeActionsView ? 0 : NSNotFound 36 | } 37 | } 38 | 39 | extension SwipeCollectionViewCell { 40 | /// :nodoc: 41 | open override var accessibilityCustomActions: [UIAccessibilityCustomAction]? { 42 | get { 43 | guard let collectionView = collectionView, let indexPath = collectionView.indexPath(for: self) else { 44 | return super.accessibilityCustomActions 45 | } 46 | 47 | let leftActions = delegate?.collectionView(collectionView, editActionsForItemAt: indexPath, for: .left) ?? [] 48 | let rightActions = delegate?.collectionView(collectionView, editActionsForItemAt: indexPath, for: .right) ?? [] 49 | 50 | let actions = [rightActions.first, leftActions.first].compactMap({ $0 }) + rightActions.dropFirst() + leftActions.dropFirst() 51 | 52 | if actions.count > 0 { 53 | return actions.map({ SwipeAccessibilityCustomAction(action: $0, 54 | indexPath: indexPath, 55 | target: self, 56 | selector: #selector(performAccessibilityCustomAction(accessibilityCustomAction:))) }) 57 | } else { 58 | return super.accessibilityCustomActions 59 | } 60 | } 61 | 62 | set { 63 | super.accessibilityCustomActions = newValue 64 | } 65 | } 66 | 67 | @objc func performAccessibilityCustomAction(accessibilityCustomAction: SwipeAccessibilityCustomAction) -> Bool { 68 | guard let collectionView = collectionView else { return false } 69 | 70 | let swipeAction = accessibilityCustomAction.action 71 | 72 | swipeAction.handler?(swipeAction, accessibilityCustomAction.indexPath) 73 | 74 | if swipeAction.style == .destructive { 75 | collectionView.deleteItems(at: [accessibilityCustomAction.indexPath]) 76 | } 77 | 78 | return true 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Master/MasterHeaderFooter.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Orders/LoadingRetry/LoadingRetryTableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Master/Master2TableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Master/MasterTableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // TestALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 20/4/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | let splitViewController = window!.rootViewController as! UISplitViewController 20 | let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController 21 | navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem 22 | splitViewController.delegate = self 23 | return true 24 | } 25 | 26 | func applicationWillResignActive(_ application: UIApplication) { 27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 28 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 29 | } 30 | 31 | func applicationDidEnterBackground(_ application: UIApplication) { 32 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | func applicationWillEnterForeground(_ application: UIApplication) { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | func applicationDidBecomeActive(_ application: UIApplication) { 41 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 42 | } 43 | 44 | func applicationWillTerminate(_ application: UIApplication) { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | // MARK: - Split view 49 | 50 | func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool { 51 | guard let secondaryAsNavController = secondaryViewController as? UINavigationController else { return false } 52 | guard let topAsDetailController = secondaryAsNavController.topViewController as? DetailViewController else { return false } 53 | if topAsDetailController.detailItem == nil { 54 | // Return true to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded. 55 | return true 56 | } 57 | return false 58 | } 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Orders/OrderElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OrderElement.swift 3 | // bimbaylola 4 | // 5 | // Created by Michel Goñi on 07/12/2018. 6 | // Copyright © 2018 BimbaYLola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum DeliveryStatus: String { 12 | case delivered 13 | case pickUp 14 | case incidence 15 | case processing 16 | case preparing 17 | case shipped 18 | case unknown 19 | 20 | func retrieveStatusColor() -> UIColor { 21 | 22 | switch self { 23 | case .delivered: 24 | return .green 25 | case .pickUp: 26 | return .blue 27 | case .incidence: 28 | return .purple 29 | case .processing: 30 | return .orange 31 | case .preparing: 32 | return .yellow 33 | case .shipped: 34 | return .blue 35 | case .unknown: 36 | return .blue 37 | } 38 | } 39 | } 40 | 41 | protocol OrderRepresentable { 42 | var image: UIImage? { get } 43 | var orderId: TextConfigurableProtocol { get } 44 | var orderAmount: TextConfigurableProtocol { get } 45 | var orderCreationDate: Date { get } 46 | var orderStatus: TextConfigurableProtocol { get } 47 | var orderStatusType: DeliveryStatus? {get} 48 | var delegate: OrderIdProtocol? {get} 49 | } 50 | 51 | struct OrderElement: OrderRepresentable { 52 | 53 | var image: UIImage? 54 | var orderId: TextConfigurableProtocol 55 | var orderAmount: TextConfigurableProtocol 56 | var orderCreationDate: Date 57 | var orderStatus: TextConfigurableProtocol 58 | var orderStatusType: DeliveryStatus? 59 | weak var delegate: OrderIdProtocol? 60 | 61 | init(image: UIImage? = nil,orderId: TextConfigurableProtocol,orderAmount: TextConfigurableProtocol,orderCreationDate:Date, orderStatus: TextConfigurableProtocol, delegate: OrderIdProtocol?) { 62 | 63 | self.image = image 64 | self.orderId = orderId 65 | self.orderAmount = orderAmount 66 | self.orderCreationDate = orderCreationDate 67 | self.orderStatus = orderStatus 68 | self.orderStatusType = getStatus(orderStatus: self.orderStatus.text) 69 | self.delegate = delegate 70 | 71 | } 72 | 73 | // MARK: - Private methods 74 | private func getStatus(orderStatus: String) -> DeliveryStatus { 75 | 76 | return DeliveryStatus(rawValue: orderStatus) ?? .unknown 77 | 78 | } 79 | } 80 | 81 | 82 | protocol TextConfigurableProtocol { 83 | var text: String { get set } 84 | var font: UIFont { get set } 85 | var color: UIColor { get set } 86 | var alignment: NSTextAlignment { get set } 87 | func isEmpty() -> Bool 88 | } 89 | 90 | extension TextConfigurableProtocol { 91 | func isEmpty() -> Bool { 92 | return text.isEmpty 93 | } 94 | } 95 | 96 | struct TextConfigurable: TextConfigurableProtocol { 97 | var text: String 98 | var font: UIFont 99 | var color: UIColor 100 | var alignment: NSTextAlignment 101 | 102 | static func defaultEmptyMember() -> TextConfigurable { 103 | return TextConfigurable(text: "", font: UIFont.systemFont(ofSize: 16.0), color: .black, alignment: .left) 104 | } 105 | 106 | static func defaultMember () -> TextConfigurable { 107 | return TextConfigurable(text: " ", font: UIFont.systemFont(ofSize: 16.0), color: .black, alignment: .left) 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Utils/ALIndexOperator/ALIndexOperator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALIndexOperator.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 27/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum ALPosition { 12 | case begining 13 | case end 14 | case middle(Int) 15 | 16 | func getValue() -> Int{ 17 | switch self { 18 | case .middle(let value): 19 | return value 20 | default: 21 | return 0 22 | } 23 | } 24 | } 25 | 26 | enum ALOperation { 27 | 28 | case get 29 | case insert 30 | case delete 31 | case replace 32 | 33 | func getIndexOperator(position: ALPosition, numberOfElements: Int) -> ALIndexOperator { 34 | 35 | switch position { 36 | case ALPosition.begining: 37 | return self.getBeginingOperator() 38 | case ALPosition.end: 39 | return self.getEndOperator(numberOfElements: numberOfElements) 40 | case ALPosition.middle: 41 | return self.getMiddleOperator(index: position.getValue()) 42 | } 43 | 44 | } 45 | 46 | private func getBeginingOperator() -> ALIndexOperator { 47 | 48 | switch self { 49 | case .insert: 50 | return ALFirstPosition() 51 | default: 52 | return ALFirstElement() 53 | } 54 | } 55 | 56 | private func getEndOperator(numberOfElements: Int) -> ALIndexOperator { 57 | 58 | switch self { 59 | case .insert: 60 | return ALLastPosition(numberOfElements: numberOfElements) 61 | default: 62 | return ALLastElement(numberOfElements: numberOfElements) 63 | } 64 | } 65 | 66 | private func getMiddleOperator(index: Int) -> ALIndexOperator { 67 | 68 | return ALMiddlePosition(index: index) 69 | } 70 | } 71 | 72 | 73 | protocol ALIndexOperator { 74 | 75 | func calculateIndex() -> Int 76 | } 77 | 78 | class ALLastElement: ALIndexOperator { 79 | 80 | let numberOfElements: Int 81 | 82 | init(numberOfElements: Int) { 83 | 84 | self.numberOfElements = numberOfElements - 1 85 | } 86 | 87 | func calculateIndex() -> Int { 88 | 89 | return self.numberOfElements 90 | } 91 | 92 | } 93 | 94 | class ALLastPosition: ALIndexOperator { 95 | 96 | let numberOfElements: Int 97 | 98 | init(numberOfElements: Int) { 99 | 100 | self.numberOfElements = numberOfElements 101 | } 102 | 103 | func calculateIndex() -> Int { 104 | 105 | return self.numberOfElements 106 | } 107 | 108 | } 109 | 110 | class ALFirstElement: ALIndexOperator { 111 | 112 | func calculateIndex() -> Int { 113 | 114 | return 0 115 | } 116 | 117 | } 118 | 119 | class ALFirstPosition: ALIndexOperator { 120 | 121 | func calculateIndex() -> Int { 122 | 123 | return 0 124 | } 125 | 126 | } 127 | 128 | class ALMiddlePosition: ALIndexOperator { 129 | 130 | let index: Int 131 | 132 | init(index: Int) { 133 | 134 | self.index = index 135 | } 136 | 137 | func calculateIndex() -> Int { 138 | 139 | return self.index 140 | } 141 | 142 | } 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeAnimator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeAnimator.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol SwipeAnimator { 11 | /// A Boolean value indicating whether the animation is currently running. 12 | var isRunning: Bool { get } 13 | 14 | /** 15 | The animation to be run by the SwipeAnimator 16 | 17 | - parameter animation: The closure to be executed by the animator 18 | */ 19 | func addAnimations(_ animation: @escaping () -> Void) 20 | 21 | /** 22 | Completion handler for the animation that is going to be started 23 | 24 | - parameter completion: The closure to be execute on completion of the animator 25 | */ 26 | func addCompletion(completion: @escaping (Bool) -> Void) 27 | 28 | /** 29 | Starts the defined animation 30 | */ 31 | func startAnimation() 32 | 33 | /** 34 | Starts the defined animation after the given delay 35 | 36 | - parameter delay: Delay of the animation 37 | */ 38 | func startAnimation(afterDelay delay: TimeInterval) 39 | 40 | /** 41 | Stops the animations at their current positions. 42 | 43 | - parameter withoutFinishing: A Boolean indicating whether any final actions should be performed. 44 | */ 45 | func stopAnimation(_ withoutFinishing: Bool) 46 | } 47 | 48 | @available(iOS 10.0, *) 49 | extension UIViewPropertyAnimator: SwipeAnimator { 50 | func addCompletion(completion: @escaping (Bool) -> Void) { 51 | addCompletion { position in 52 | completion(position == .end) 53 | } 54 | } 55 | } 56 | 57 | class UIViewSpringAnimator: SwipeAnimator { 58 | var isRunning: Bool = false 59 | 60 | let duration:TimeInterval 61 | let damping:CGFloat 62 | let velocity:CGFloat 63 | 64 | var animations:(() -> Void)? 65 | var completion:((Bool) -> Void)? 66 | 67 | required init(duration: TimeInterval, 68 | damping: CGFloat, 69 | initialVelocity velocity: CGFloat = 0) { 70 | self.duration = duration 71 | self.damping = damping 72 | self.velocity = velocity 73 | } 74 | 75 | func addAnimations(_ animations: @escaping () -> Void) { 76 | self.animations = animations 77 | } 78 | 79 | func addCompletion(completion: @escaping (Bool) -> Void) { 80 | self.completion = { [weak self] finished in 81 | guard self?.isRunning == true else { return } 82 | 83 | self?.isRunning = false 84 | self?.animations = nil 85 | self?.completion = nil 86 | 87 | completion(finished) 88 | } 89 | } 90 | 91 | func startAnimation() { 92 | self.startAnimation(afterDelay: 0) 93 | } 94 | 95 | func startAnimation(afterDelay delay:TimeInterval) { 96 | guard let animations = animations else { return } 97 | 98 | isRunning = true 99 | 100 | UIView.animate(withDuration: duration, 101 | delay: delay, 102 | usingSpringWithDamping: damping, 103 | initialSpringVelocity: velocity, 104 | options: [.curveEaseInOut, .allowUserInteraction], 105 | animations: animations, 106 | completion: completion) 107 | } 108 | 109 | func stopAnimation(_ withoutFinishing: Bool) { 110 | isRunning = false 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/Orders/OrdersTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OrdersTableViewCell.swift 3 | // bimbaylola 4 | // 5 | // Created by Michel Goñi on 07/12/2018. 6 | // Copyright © 2018 BimbaYLola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ALTableView 11 | 12 | protocol OrdersElementConfigurable { 13 | func configure(element: OrderRepresentable) 14 | } 15 | 16 | protocol OrderIdProtocol: class { 17 | func orderIdSelected(orderId: Int) 18 | } 19 | 20 | class OrdersTableViewCell: UITableViewCell, ALCellProtocol, OrdersElementConfigurable { 21 | 22 | @IBOutlet weak var lbOrderId: UILabel! 23 | @IBOutlet weak var lbOrderDate: UILabel! 24 | @IBOutlet weak var imgOrderStatus: UIImageView! 25 | @IBOutlet weak var lbOrderStatus: UILabel! 26 | @IBOutlet weak var lbOrderAmount: UILabel! 27 | 28 | private var element: OrderRepresentable? 29 | 30 | class var nib: String { 31 | return "OrdersTableViewCell" 32 | } 33 | class var reuseIdentifier: String { 34 | return "OrdersTableViewCellReuseIdentifier" 35 | } 36 | 37 | // MARK: - ALCellProtocol 38 | 39 | public func cellCreated(dataObject: Any?) { 40 | if let element = dataObject as? OrderRepresentable { 41 | self.element = element 42 | configure(element: element) 43 | } 44 | 45 | } 46 | 47 | func cellPressed(viewController: UIViewController?) { 48 | 49 | if let orderid = element?.orderId { 50 | element?.delegate?.orderIdSelected(orderId: Int(orderid.text) ?? 0) 51 | } 52 | 53 | } 54 | 55 | // MARK: - OrdersElementConfigurable 56 | func configure(element: OrderRepresentable) { 57 | lbOrderId.configure(textConfigurable: TextStyles.ordersElement(text: element.orderId.text)) 58 | lbOrderDate.configure(textConfigurable: TextStyles.ordersElementDate(text: element.orderCreationDate.string(withFormat: "dd/MM/yyyy"))) 59 | imgOrderStatus.layer.masksToBounds = true 60 | imgOrderStatus.layer.cornerRadius = imgOrderStatus.frame.height / 2 61 | imgOrderStatus.image = element.orderStatusType?.retrieveStatusColor().image(CGSize(width: 14, height: 14)) 62 | lbOrderStatus.configure(textConfigurable: TextStyles.ordersElement(text: element.orderStatus.text)) 63 | lbOrderAmount.configure(textConfigurable: TextStyles.ordersElement(text: element.orderAmount.text)) 64 | } 65 | 66 | } 67 | 68 | extension UILabel { 69 | 70 | func configure(textConfigurable: TextConfigurableProtocol) { 71 | text = textConfigurable.text 72 | font = textConfigurable.font 73 | textColor = textConfigurable.color 74 | textAlignment = textConfigurable.alignment 75 | } 76 | 77 | } 78 | 79 | extension UIColor { 80 | 81 | /// Prints color inside an image 82 | /// - parameter size: The size of the image as CGSize. 83 | /// - Example: UIColor.red.image(CGSize(width: 35, height: 35)). 84 | public func image(_ size: CGSize = CGSize(width: 35, height: 35)) -> UIImage { 85 | if #available(iOS 10.0, *) { 86 | return UIGraphicsImageRenderer(size: size).image { rendererContext in 87 | self.setFill() 88 | rendererContext.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height)) 89 | } 90 | } else { 91 | return UIImage() 92 | } 93 | } 94 | } 95 | 96 | extension Date { 97 | public func string(withFormat format: String = "dd/MM/yyyy HH:mm") -> String { 98 | let dateFormatter = DateFormatter() 99 | dateFormatter.dateFormat = format 100 | return dateFormatter.string(from: self) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeOptions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Options.swift 3 | // 4 | // Created by Jeremy Koch. 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | /// :nodoc: 11 | public typealias SwipeTableOptions = SwipeOptions 12 | 13 | /// The `SwipeOptions` class provides options for transistion and expansion behavior for swiped cell. 14 | public struct SwipeOptions { 15 | /// The transition style. Transition is the style of how the action buttons are exposed during the swipe. 16 | public var transitionStyle: SwipeTransitionStyle = .border 17 | 18 | /// The expansion style. Expansion is the behavior when the cell is swiped past a defined threshold. 19 | public var expansionStyle: SwipeExpansionStyle? 20 | 21 | /// The object that is notified when expansion changes. 22 | /// 23 | /// - note: If an `expansionDelegate` is not provided, and the expanding action is configured with a clear background, the system automatically uses the default `ScaleAndAlphaExpansion` to show/hide underlying actions. 24 | public var expansionDelegate: SwipeExpanding? 25 | 26 | /// The background color behind the action buttons. 27 | public var backgroundColor: UIColor? 28 | 29 | /// The largest allowable button width. 30 | /// 31 | /// - note: By default, the value is set to the table/collection view divided by the number of action buttons minus some additional padding. If the value is set to 0, then word wrapping will not occur and the buttons will grow as large as needed to fit the entire title/image. 32 | public var maximumButtonWidth: CGFloat? 33 | 34 | /// The smallest allowable button width. 35 | /// 36 | /// - note: By default, the system chooses an appropriate size. 37 | public var minimumButtonWidth: CGFloat? 38 | 39 | /// The vertical alignment mode used for when a button image and title are present. 40 | public var buttonVerticalAlignment: SwipeVerticalAlignment = .centerFirstBaseline 41 | 42 | /// The amount of space, in points, between the border and the button image or title. 43 | public var buttonPadding: CGFloat? 44 | 45 | /// The amount of space, in points, between the button image and the button title. 46 | public var buttonSpacing: CGFloat? 47 | 48 | /// Constructs a new `SwipeOptions` instance with default options. 49 | public init() {} 50 | } 51 | 52 | /// Describes the transition style. Transition is the style of how the action buttons are exposed during the swipe. 53 | public enum SwipeTransitionStyle { 54 | /// The visible action area is equally divide between all action buttons. 55 | case border 56 | 57 | /// The visible action area is dragged, pinned to the cell, with each action button fully sized as it is exposed. 58 | case drag 59 | 60 | /// The visible action area sits behind the cell, pinned to the edge of the table/collection view, and is revealed as the cell is dragged aside. 61 | case reveal 62 | } 63 | 64 | /// Describes which side of the cell that the action buttons will be displayed. 65 | public enum SwipeActionsOrientation: CGFloat { 66 | /// The left side of the cell. 67 | case left = -1 68 | 69 | /// The right side of the cell. 70 | case right = 1 71 | 72 | var scale: CGFloat { 73 | return rawValue 74 | } 75 | } 76 | 77 | /// Describes the alignment mode used when action button images and titles are provided. 78 | public enum SwipeVerticalAlignment { 79 | /// All actions will be inspected and the tallest image and first baseline offset of title text will be used to create the alignment rectangle. 80 | /// 81 | /// - note: This mode will ensure the image and first line of each button title and consistently aligned across the swipe view. 82 | case centerFirstBaseline 83 | 84 | /// The action button image height and full title height are used to create the aligment rectange. 85 | /// 86 | /// - note: Buttons with varying number of lines will not be consistently aligned across the swipe view. 87 | case center 88 | } 89 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeTransitionLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeTransitionLayout.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: - Layout Protocol 11 | 12 | protocol SwipeTransitionLayout { 13 | func container(view: UIView, didChangeVisibleWidthWithContext context: ActionsViewLayoutContext) 14 | func layout(view: UIView, atIndex index: Int, with context: ActionsViewLayoutContext) 15 | func visibleWidthsForViews(with context: ActionsViewLayoutContext) -> [CGFloat] 16 | } 17 | 18 | // MARK: - Layout Context 19 | 20 | struct ActionsViewLayoutContext { 21 | let numberOfActions: Int 22 | let orientation: SwipeActionsOrientation 23 | let contentSize: CGSize 24 | let visibleWidth: CGFloat 25 | let minimumButtonWidth: CGFloat 26 | 27 | init(numberOfActions: Int, orientation: SwipeActionsOrientation, contentSize: CGSize = .zero, visibleWidth: CGFloat = 0, minimumButtonWidth: CGFloat = 0) { 28 | self.numberOfActions = numberOfActions 29 | self.orientation = orientation 30 | self.contentSize = contentSize 31 | self.visibleWidth = visibleWidth 32 | self.minimumButtonWidth = minimumButtonWidth 33 | } 34 | 35 | static func newContext(for actionsView: SwipeActionsView) -> ActionsViewLayoutContext { 36 | return ActionsViewLayoutContext(numberOfActions: actionsView.actions.count, 37 | orientation: actionsView.orientation, 38 | contentSize: actionsView.contentSize, 39 | visibleWidth: actionsView.visibleWidth, 40 | minimumButtonWidth: actionsView.minimumButtonWidth) 41 | } 42 | } 43 | 44 | // MARK: - Supported Layout Implementations 45 | 46 | class BorderTransitionLayout: SwipeTransitionLayout { 47 | func container(view: UIView, didChangeVisibleWidthWithContext context: ActionsViewLayoutContext) { 48 | } 49 | 50 | func layout(view: UIView, atIndex index: Int, with context: ActionsViewLayoutContext) { 51 | let diff = context.visibleWidth - context.contentSize.width 52 | view.frame.origin.x = (CGFloat(index) * context.contentSize.width / CGFloat(context.numberOfActions) + diff) * context.orientation.scale 53 | } 54 | 55 | func visibleWidthsForViews(with context: ActionsViewLayoutContext) -> [CGFloat] { 56 | let diff = context.visibleWidth - context.contentSize.width 57 | let visibleWidth = context.contentSize.width / CGFloat(context.numberOfActions) + diff 58 | 59 | // visible widths are all the same regardless of the action view position 60 | return (0.. [CGFloat] { 74 | return (0.. [CGFloat] { 86 | return super.visibleWidthsForViews(with: context).reversed() 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeTableViewCellDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeTableViewCellDelegate.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | /** 11 | The `SwipeTableViewCellDelegate` protocol is adopted by an object that manages the display of action buttons when the cell is swiped. 12 | */ 13 | public protocol SwipeTableViewCellDelegate: class { 14 | 15 | /** 16 | Asks the delegate for the actions to display in response to a swipe in the specified row. 17 | 18 | - parameter tableView: The table view object which owns the cell requesting this information. 19 | 20 | - parameter indexPath: The index path of the row. 21 | 22 | - parameter orientation: The side of the cell requesting this information. 23 | 24 | - returns: An array of `SwipeAction` objects representing the actions for the row. Each action you provide is used to create a button that the user can tap. Returning `nil` will prevent swiping for the supplied orientation. 25 | */ 26 | func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? 27 | 28 | /** 29 | Asks the delegate for the display options to be used while presenting the action buttons. 30 | 31 | - parameter tableView: The table view object which owns the cell requesting this information. 32 | 33 | - parameter indexPath: The index path of the row. 34 | 35 | - parameter orientation: The side of the cell requesting this information. 36 | 37 | - returns: A `SwipeOptions` instance which configures the behavior of the action buttons. 38 | 39 | - note: If not implemented, a default `SwipeOptions` instance is used. 40 | */ 41 | func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions 42 | 43 | /** 44 | Tells the delegate that the table view is about to go into editing mode. 45 | 46 | - parameter tableView: The table view object providing this information. 47 | 48 | - parameter indexPath: The index path of the row. 49 | 50 | - parameter orientation: The side of the cell. 51 | */ 52 | func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) 53 | 54 | /** 55 | Tells the delegate that the table view has left editing mode. 56 | 57 | - parameter tableView: The table view object providing this information. 58 | 59 | - parameter indexPath: The index path of the row. 60 | 61 | - parameter orientation: The side of the cell. 62 | */ 63 | func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?, for orientation: SwipeActionsOrientation) 64 | 65 | /** 66 | Asks the delegate for visibile rectangle of the table view, which is used to ensure swipe actions are vertically centered within the visible portion of the cell. 67 | 68 | - parameter tableView: The table view object providing this information. 69 | 70 | - returns: The visible rectangle of the table view. 71 | 72 | - note: The returned rectange should be in the table view's own coordinate system. Returning `nil` will result in no vertical offset to be be calculated. 73 | */ 74 | func visibleRect(for tableView: UITableView) -> CGRect? 75 | } 76 | 77 | /** 78 | Default implementation of `SwipeTableViewCellDelegate` methods 79 | */ 80 | public extension SwipeTableViewCellDelegate { 81 | func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions { 82 | return SwipeOptions() 83 | } 84 | 85 | func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) {} 86 | 87 | func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?, for orientation: SwipeActionsOrientation) {} 88 | 89 | func visibleRect(for tableView: UITableView) -> CGRect? { 90 | return nil 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeActionTransitioning.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeActionTransitioning.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | /** 11 | Adopt the `SwipeActionTransitioning` protocol in objects that implement custom appearance of actions during transition. 12 | */ 13 | public protocol SwipeActionTransitioning { 14 | /** 15 | Tells the delegate that transition change has occured. 16 | */ 17 | func didTransition(with context: SwipeActionTransitioningContext) -> Void 18 | } 19 | 20 | /** 21 | The `SwipeActionTransitioningContext` type provides information relevant to a specific action as transitioning occurs. 22 | */ 23 | public struct SwipeActionTransitioningContext { 24 | /// The unique action identifier. 25 | public let actionIdentifier: String? 26 | 27 | /// The button that is changing. 28 | public let button: UIButton 29 | 30 | /// The old visibility percentage between 0.0 and 1.0. 31 | public let newPercentVisible: CGFloat 32 | 33 | /// The new visibility percentage between 0.0 and 1.0. 34 | public let oldPercentVisible: CGFloat 35 | 36 | internal let wrapperView: UIView 37 | 38 | internal init(actionIdentifier: String?, button: UIButton, newPercentVisible: CGFloat, oldPercentVisible: CGFloat, wrapperView: UIView) { 39 | self.actionIdentifier = actionIdentifier 40 | self.button = button 41 | self.newPercentVisible = newPercentVisible 42 | self.oldPercentVisible = oldPercentVisible 43 | self.wrapperView = wrapperView 44 | } 45 | 46 | /// Sets the background color behind the action button. 47 | /// 48 | /// - parameter color: The background color. 49 | public func setBackgroundColor(_ color: UIColor?) { 50 | wrapperView.backgroundColor = color 51 | } 52 | } 53 | 54 | /** 55 | A scale transition object drives the custom appearance of actions during transition. 56 | 57 | As button's percentage visibility crosses the `threshold`, the `ScaleTransition` object will animate from `initialScale` to `identity`. The default settings provide a "pop-like" effect as the buttons are exposed more than 50%. 58 | */ 59 | public struct ScaleTransition: SwipeActionTransitioning { 60 | 61 | /// Returns a `ScaleTransition` instance with default transition options. 62 | public static var `default`: ScaleTransition { return ScaleTransition() } 63 | 64 | /// The duration of the animation. 65 | public let duration: Double 66 | 67 | /// The initial scale factor used before the action button percent visible is greater than the threshold. 68 | public let initialScale: CGFloat 69 | 70 | /// The percent visible threshold that triggers the scaling animation. 71 | public let threshold: CGFloat 72 | 73 | /** 74 | Contructs a new `ScaleTransition` instance. 75 | 76 | - parameter duration: The duration of the animation. 77 | 78 | - parameter initialScale: The initial scale factor used before the action button percent visible is greater than the threshold. 79 | 80 | - parameter threshold: The percent visible threshold that triggers the scaling animation. 81 | 82 | - returns: The new `ScaleTransition` instance. 83 | */ 84 | public init(duration: Double = 0.15, initialScale: CGFloat = 0.8, threshold: CGFloat = 0.5) { 85 | self.duration = duration 86 | self.initialScale = initialScale 87 | self.threshold = threshold 88 | } 89 | 90 | /// :nodoc: 91 | public func didTransition(with context: SwipeActionTransitioningContext) -> Void { 92 | if context.oldPercentVisible == 0 { 93 | context.button.transform = .init(scaleX: initialScale, y: initialScale) 94 | } 95 | 96 | if context.oldPercentVisible < threshold && context.newPercentVisible >= threshold { 97 | UIView.animate(withDuration: duration) { 98 | context.button.transform = .identity 99 | } 100 | } else if context.oldPercentVisible >= threshold && context.newPercentVisible < threshold { 101 | UIView.animate(withDuration: duration) { 102 | context.button.transform = .init(scaleX: self.initialScale, y: self.initialScale) 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeCollectionViewCellDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeCollectionViewCellDelegate.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | /** 11 | The `SwipeCollectionViewCellDelegate` protocol is adopted by an object that manages the display of action buttons when the item is swiped. 12 | */ 13 | public protocol SwipeCollectionViewCellDelegate: class { 14 | /** 15 | Asks the delegate for the actions to display in response to a swipe in the specified item. 16 | 17 | - parameter collectionView: The collection view object which owns the item requesting this information. 18 | 19 | - parameter indexPath: The index path of the item. 20 | 21 | - parameter orientation: The side of the item requesting this information. 22 | 23 | - returns: An array of `SwipeAction` objects representing the actions for the item. Each action you provide is used to create a button that the user can tap. Returning `nil` will prevent swiping for the supplied orientation. 24 | */ 25 | func collectionView(_ collectionView: UICollectionView, editActionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? 26 | 27 | /** 28 | Asks the delegate for the display options to be used while presenting the action buttons. 29 | 30 | - parameter collectionView: The collection view object which owns the item requesting this information. 31 | 32 | - parameter indexPath: The index path of the item. 33 | 34 | - parameter orientation: The side of the item requesting this information. 35 | 36 | - returns: A `SwipeOptions` instance which configures the behavior of the action buttons. 37 | 38 | - note: If not implemented, a default `SwipeOptions` instance is used. 39 | */ 40 | func collectionView(_ collectionView: UICollectionView, editActionsOptionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions 41 | 42 | /** 43 | Tells the delegate that the collection view is about to go into editing mode. 44 | 45 | - parameter collectionView: The collection view object providing this information. 46 | 47 | - parameter indexPath: The index path of the item. 48 | 49 | - parameter orientation: The side of the item. 50 | */ 51 | func collectionView(_ collectionView: UICollectionView, willBeginEditingItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) 52 | 53 | /** 54 | Tells the delegate that the collection view has left editing mode. 55 | 56 | - parameter collectionView: The collection view object providing this information. 57 | 58 | - parameter indexPath: The index path of the item. 59 | 60 | - parameter orientation: The side of the item. 61 | */ 62 | func collectionView(_ collectionView: UICollectionView, didEndEditingItemAt indexPath: IndexPath?, for orientation: SwipeActionsOrientation) 63 | 64 | /** 65 | Asks the delegate for visibile rectangle of the collection view, which is used to ensure swipe actions are vertically centered within the visible portion of the item. 66 | 67 | - parameter collectionView: The collection view object providing this information. 68 | 69 | - returns: The visible rectangle of the collection view. 70 | 71 | - note: The returned rectange should be in the collection view's own coordinate system. Returning `nil` will result in no vertical offset to be be calculated. 72 | */ 73 | func visibleRect(for collectionView: UICollectionView) -> CGRect? 74 | } 75 | 76 | /** 77 | Default implementation of `SwipeCollectionViewCellDelegate` methods 78 | */ 79 | public extension SwipeCollectionViewCellDelegate { 80 | func collectionView(_ collectionView: UICollectionView, editActionsOptionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions { 81 | return SwipeOptions() 82 | } 83 | 84 | func collectionView(_ collectionView: UICollectionView, willBeginEditingItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) {} 85 | 86 | func collectionView(_ collectionView: UICollectionView, didEndEditingItemAt indexPath: IndexPath?, for orientation: SwipeActionsOrientation) {} 87 | 88 | func visibleRect(for collectionView: UICollectionView) -> CGRect? { 89 | return nil 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeActionButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeActionButton.swift 3 | // 4 | // Created by Jeremy Koch. 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | class SwipeActionButton: UIButton { 11 | var spacing: CGFloat = 8 12 | var shouldHighlight = true 13 | var highlightedBackgroundColor: UIColor? 14 | 15 | var maximumImageHeight: CGFloat = 0 16 | var verticalAlignment: SwipeVerticalAlignment = .centerFirstBaseline 17 | 18 | 19 | var currentSpacing: CGFloat { 20 | return (currentTitle?.isEmpty == false && imageHeight > 0) ? spacing : 0 21 | } 22 | 23 | var alignmentRect: CGRect { 24 | let contentRect = self.contentRect(forBounds: bounds) 25 | let titleHeight = titleBoundingRect(with: verticalAlignment == .centerFirstBaseline ? CGRect.infinite.size : contentRect.size).integral.height 26 | let totalHeight = imageHeight + titleHeight + currentSpacing 27 | 28 | return contentRect.center(size: CGSize(width: contentRect.width, height: totalHeight)) 29 | } 30 | 31 | private var imageHeight: CGFloat { 32 | get { 33 | return currentImage == nil ? 0 : maximumImageHeight 34 | } 35 | } 36 | 37 | override var intrinsicContentSize: CGSize { 38 | return CGSize(width: UIView.noIntrinsicMetric, height: contentEdgeInsets.top + alignmentRect.height + contentEdgeInsets.bottom) 39 | } 40 | 41 | convenience init(action: SwipeAction) { 42 | self.init(frame: .zero) 43 | 44 | contentHorizontalAlignment = .center 45 | 46 | tintColor = action.textColor ?? .white 47 | let highlightedTextColor = action.highlightedTextColor ?? tintColor 48 | highlightedBackgroundColor = action.highlightedBackgroundColor ?? UIColor.black.withAlphaComponent(0.1) 49 | 50 | titleLabel?.font = action.font ?? UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.medium) 51 | titleLabel?.textAlignment = .center 52 | titleLabel?.lineBreakMode = .byWordWrapping 53 | titleLabel?.numberOfLines = 0 54 | 55 | accessibilityLabel = action.accessibilityLabel 56 | 57 | setTitle(action.title, for: .normal) 58 | setTitleColor(tintColor, for: .normal) 59 | setTitleColor(highlightedTextColor, for: .highlighted) 60 | setImage(action.image, for: .normal) 61 | setImage(action.highlightedImage ?? action.image, for: .highlighted) 62 | } 63 | 64 | override var isHighlighted: Bool { 65 | didSet { 66 | guard shouldHighlight else { return } 67 | 68 | backgroundColor = isHighlighted ? highlightedBackgroundColor : .clear 69 | } 70 | } 71 | 72 | func preferredWidth(maximum: CGFloat) -> CGFloat { 73 | let width = maximum > 0 ? maximum : CGFloat.greatestFiniteMagnitude 74 | let textWidth = titleBoundingRect(with: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)).width 75 | let imageWidth = currentImage?.size.width ?? 0 76 | 77 | return min(width, max(textWidth, imageWidth) + contentEdgeInsets.left + contentEdgeInsets.right) 78 | } 79 | 80 | func titleBoundingRect(with size: CGSize) -> CGRect { 81 | guard let title = currentTitle, let font = titleLabel?.font else { return .zero } 82 | 83 | return title.boundingRect(with: size, 84 | options: [.usesLineFragmentOrigin], 85 | attributes: [NSAttributedString.Key.font: font], 86 | context: nil).integral 87 | } 88 | 89 | override func titleRect(forContentRect contentRect: CGRect) -> CGRect { 90 | var rect = contentRect.center(size: titleBoundingRect(with: contentRect.size).size) 91 | rect.origin.y = alignmentRect.minY + imageHeight + currentSpacing 92 | return rect.integral 93 | } 94 | 95 | override func imageRect(forContentRect contentRect: CGRect) -> CGRect { 96 | var rect = contentRect.center(size: currentImage?.size ?? .zero) 97 | rect.origin.y = alignmentRect.minY + (imageHeight - rect.height) / 2 98 | return rect 99 | } 100 | } 101 | 102 | extension CGRect { 103 | func center(size: CGSize) -> CGRect { 104 | let dx = width - size.width 105 | let dy = height - size.height 106 | return CGRect(x: origin.x + dx * 0.5, y: origin.y + dy * 0.5, width: size.width, height: size.height) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Elements/Row/ALRowElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RowElement.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 7/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public typealias ALCellPressedHandler = (UIViewController?, UITableViewCell) -> Void 12 | public typealias ALCellCreatedHandler = (Any?, UITableViewCell) -> Void 13 | public typealias ALCellDeselectedHandler = (UITableViewCell) -> Void 14 | 15 | //Implemented by ALRowElement 16 | public protocol ALRowElementProtocol { 17 | func rowElementPressed(viewController: UIViewController?, cell: UITableViewCell) 18 | func rowElementDeselected(cell: UITableViewCell) 19 | } 20 | 21 | //Implemented by UITableViewCell 22 | public protocol ALCellProtocol { 23 | func cellPressed (viewController: UIViewController?) -> Void 24 | func cellDeselected () -> Void 25 | func cellCreated(dataObject: Any?) -> Void 26 | } 27 | 28 | extension ALCellProtocol { 29 | public func cellPressed (viewController: UIViewController?) -> Void { 30 | 31 | } 32 | 33 | public func cellDeselected () -> Void { 34 | 35 | } 36 | 37 | public func cellCreated(dataObject: Any?) -> Void { 38 | print("ALCellProtocol") 39 | } 40 | } 41 | 42 | public class ALRowElement: ALElement, ALRowElementProtocol { 43 | 44 | //MARK: - Properties 45 | 46 | 47 | private var className: AnyClass //TODO es posible que el className no sea necesario 48 | 49 | private let cellStyle: UITableViewCell.CellStyle 50 | internal var editingAllowed: Bool 51 | 52 | private var pressedHandler: ALCellPressedHandler? 53 | private var createdHandler: ALCellCreatedHandler? 54 | private var deselectedHandler: ALCellDeselectedHandler? 55 | 56 | //MARK: - Initializers 57 | 58 | public init(className: AnyClass, 59 | identifier: String, 60 | dataObject: Any?, 61 | cellStyle: UITableViewCell.CellStyle = .default, 62 | estimateHeightMode: Bool = false, 63 | height: CGFloat = 44.0, 64 | editingAllowed: Bool = false, 65 | pressedHandler: ALCellPressedHandler? = nil, 66 | createdHandler: ALCellCreatedHandler? = nil, 67 | deselectedHandler: ALCellDeselectedHandler? = nil) { 68 | 69 | self.className = className 70 | self.cellStyle = cellStyle 71 | self.editingAllowed = editingAllowed 72 | self.pressedHandler = pressedHandler 73 | self.createdHandler = createdHandler 74 | self.deselectedHandler = deselectedHandler 75 | super.init(identifier: identifier, dataObject: dataObject, estimateHeightMode: estimateHeightMode, height: height) 76 | } 77 | 78 | //MARK: - Getters 79 | 80 | internal func getViewFrom(tableView: UITableView) -> UITableViewCell { 81 | 82 | guard let dequeuedElement: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: self.identifier) else { 83 | return UITableViewCell() 84 | } 85 | if let alCell = dequeuedElement as? ALCellProtocol { 86 | object_setClass(alCell, self.className) 87 | alCell.cellCreated(dataObject: self.dataObject) 88 | } 89 | if let handler:ALCellCreatedHandler = self.createdHandler { 90 | handler(self.dataObject, dequeuedElement) 91 | } 92 | return dequeuedElement 93 | } 94 | 95 | 96 | //MARK: - Setters 97 | 98 | internal func setCellHeight(height: CGFloat) -> Void { 99 | 100 | self.height = height 101 | } 102 | 103 | //MARK: - ALRowElementProtocol 104 | 105 | public func rowElementPressed(viewController: UIViewController?, cell: UITableViewCell) { 106 | 107 | if let cell: ALCellProtocol = cell as? ALCellProtocol { 108 | cell.cellPressed(viewController: viewController) 109 | } 110 | 111 | if let handler:ALCellPressedHandler = self.pressedHandler { 112 | handler(viewController, cell) 113 | } 114 | } 115 | 116 | public func rowElementDeselected(cell: UITableViewCell) { 117 | 118 | if let cell: ALCellProtocol = cell as? ALCellProtocol { 119 | cell.cellDeselected() 120 | } 121 | 122 | if let handler: ALCellDeselectedHandler = self.deselectedHandler { 123 | handler(cell) 124 | } 125 | } 126 | } 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeExpanding.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeExpanding.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | /** 11 | Adopt the `SwipeExpanding` protocol in objects that implement custom appearance of actions during expansion. 12 | */ 13 | public protocol SwipeExpanding { 14 | 15 | /** 16 | Asks your object for the animation timing parameters. 17 | 18 | - parameter buttons: The expansion action button, which includes expanding action plus the remaining actions in the view. 19 | 20 | - parameter expanding: The new expansion state. 21 | 22 | - parameter otherActionButtons: The other action buttons in the view, not including the action button being expanded. 23 | */ 24 | 25 | func animationTimingParameters(buttons: [UIButton], expanding: Bool) -> SwipeExpansionAnimationTimingParameters 26 | 27 | /** 28 | Tells your object when the expansion state is changing. 29 | 30 | - parameter button: The expansion action button. 31 | 32 | - parameter expanding: The new expansion state. 33 | 34 | - parameter otherActionButtons: The other action buttons in the view, not including the action button being expanded. 35 | */ 36 | func actionButton(_ button: UIButton, didChange expanding: Bool, otherActionButtons: [UIButton]) 37 | } 38 | 39 | /** 40 | Specifies timing information for the overall expansion animation. 41 | */ 42 | public struct SwipeExpansionAnimationTimingParameters { 43 | 44 | /// Returns a `SwipeExpansionAnimationTimingParameters` instance with default animation parameters. 45 | public static var `default`: SwipeExpansionAnimationTimingParameters { return SwipeExpansionAnimationTimingParameters() } 46 | 47 | /// The duration of the expansion animation. 48 | public var duration: Double 49 | 50 | /// The delay before starting the expansion animation. 51 | public var delay: Double 52 | 53 | /** 54 | Contructs a new `SwipeExpansionAnimationTimingParameters` instance. 55 | 56 | - parameter duration: The duration of the animation. 57 | 58 | - parameter delay: The delay before starting the expansion animation. 59 | 60 | - returns: The new `SwipeExpansionAnimationTimingParameters` instance. 61 | */ 62 | public init(duration: Double = 0.6, delay: Double = 0) { 63 | self.duration = duration 64 | self.delay = delay 65 | } 66 | } 67 | 68 | /** 69 | A scale and alpha expansion object drives the custom appearance of the effected actions during expansion. 70 | */ 71 | public struct ScaleAndAlphaExpansion: SwipeExpanding { 72 | 73 | /// Returns a `ScaleAndAlphaExpansion` instance with default expansion options. 74 | public static var `default`: ScaleAndAlphaExpansion { return ScaleAndAlphaExpansion() } 75 | 76 | /// The duration of the animation. 77 | public let duration: Double 78 | 79 | /// The scale factor used during animation. 80 | public let scale: CGFloat 81 | 82 | /// The inter-button delay between animations. 83 | public let interButtonDelay: Double 84 | 85 | /** 86 | Contructs a new `ScaleAndAlphaExpansion` instance. 87 | 88 | - parameter duration: The duration of the animation. 89 | 90 | - parameter scale: The scale factor used during animation. 91 | 92 | - parameter interButtonDelay: The inter-button delay between animations. 93 | 94 | - returns: The new `ScaleAndAlphaExpansion` instance. 95 | */ 96 | public init(duration: Double = 0.15, scale: CGFloat = 0.8, interButtonDelay: Double = 0.1) { 97 | self.duration = duration 98 | self.scale = scale 99 | self.interButtonDelay = interButtonDelay 100 | } 101 | 102 | /// :nodoc: 103 | public func animationTimingParameters(buttons: [UIButton], expanding: Bool) -> SwipeExpansionAnimationTimingParameters { 104 | var timingParameters = SwipeExpansionAnimationTimingParameters.default 105 | timingParameters.delay = expanding ? interButtonDelay : 0 106 | return timingParameters 107 | } 108 | 109 | /// :nodoc: 110 | public func actionButton(_ button: UIButton, didChange expanding: Bool, otherActionButtons: [UIButton]) { 111 | let buttons = expanding ? otherActionButtons : otherActionButtons.reversed() 112 | 113 | buttons.enumerated().forEach { index, button in 114 | UIView.animate(withDuration: duration, delay: interButtonDelay * Double(expanding ? index : index + 1), options: [], animations: { 115 | button.transform = expanding ? .init(scaleX: self.scale, y: self.scale) : .identity 116 | button.alpha = expanding ? 0.0 : 1.0 117 | }, completion: nil) 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/ALTableView/ALTableViewDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALTableViewDelegate.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 16/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | //MARK: - UITableViewDelegate 12 | 13 | extension ALTableView: UITableViewDelegate { 14 | 15 | //MARK: - Configuring Rows 16 | 17 | public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 18 | 19 | return self.getSectionElementAt(index: indexPath.section)?.getRowHeight(at: indexPath.row) ?? 0.0 20 | } 21 | 22 | public func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { 23 | 24 | return self.getSectionElementAt(index: indexPath.section)?.getRowEstimatedHeight(at: indexPath.row) ?? 0.0 25 | } 26 | 27 | public func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int { 28 | 29 | return 0 30 | } 31 | 32 | public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 33 | 34 | //We set up the cellHeight again to avoid stuttering scroll when using automatic dimension with cells 35 | let cellHeight: CGFloat = cell.frame.size.height 36 | self.getSectionElementAt(index: indexPath.section)?.setRowElementHeight(row: indexPath.row, height: cellHeight) 37 | 38 | if self.isLastIndexPath(indexPath: indexPath, tableView: tableView) { 39 | //We reached the end of the tableView 40 | self.delegate?.tableViewDidReachEnd?() 41 | } 42 | } 43 | 44 | //MARK: - Managing selections 45 | 46 | public func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { 47 | 48 | return indexPath 49 | } 50 | 51 | 52 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 53 | 54 | guard let cell: UITableViewCell = tableView.cellForRow(at: indexPath) else { 55 | return 56 | } 57 | self.getSectionElementAt(index: indexPath.section)?.rowElementPressed(row: indexPath.row, viewController: self.viewController, cell: cell) 58 | } 59 | 60 | public func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? { 61 | 62 | return indexPath 63 | } 64 | 65 | public func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 66 | 67 | guard let cell: UITableViewCell = tableView.cellForRow(at: indexPath) else { 68 | return 69 | } 70 | self.getSectionElementAt(index: indexPath.section)?.rowElementDeselected(row: indexPath.row, cell: cell) 71 | } 72 | 73 | //MARK: - Modifying Header and Footer of Sections 74 | 75 | public func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat { 76 | 77 | return self.getSectionElementAt(index: section)?.getHeaderEstimatedHeight() ?? 0.0 78 | } 79 | 80 | public func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat { 81 | 82 | return self.getSectionElementAt(index: section)?.getFooterEstimatedHeight() ?? 0.0 83 | } 84 | 85 | public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 86 | 87 | return self.getSectionElementAt(index: section)?.getHeaderFrom(tableView: tableView) 88 | } 89 | 90 | public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { 91 | 92 | return self.getSectionElementAt(index: section)?.getFooterFrom(tableView: tableView) 93 | } 94 | 95 | public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 96 | 97 | return self.getSectionElementAt(index: section)?.getHeaderHeight() ?? 0.0 98 | } 99 | 100 | public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { 101 | 102 | return self.getSectionElementAt(index: section)?.getFooterHeight() ?? 0.0 103 | } 104 | 105 | } 106 | 107 | //MARK: - Private methods 108 | 109 | extension ALTableView { 110 | 111 | private func isLastIndexPath (indexPath: IndexPath, tableView: UITableView) -> Bool { 112 | 113 | let isLastSection: Bool = indexPath.section == tableView.numberOfSections - 1 114 | let isLastRow: Bool = indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 115 | return isLastSection && isLastRow 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableView/ALTableViewClasses/Extension/Array+ALTableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+ALTableView.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 27/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension Array { 13 | 14 | 15 | 16 | /// Returns the element at the specified index iff it is within bounds, otherwise nil. 17 | 18 | internal subscript (ALSafe index: Index) -> Element? { 19 | 20 | let position: ALPosition = ALPosition.middle(index) 21 | return self[ALSafePosition: position] 22 | } 23 | 24 | internal subscript (ALSafePosition position: ALPosition) -> Element? { 25 | 26 | let index: Int = self.getRealIndex(operation: .get, position: position) 27 | return indices.contains(index) ? self[index] : nil 28 | } 29 | 30 | internal mutating func safeInsert(contentsOf newElements: C, at i: Int) -> Bool where C : Collection, Element == C.Element { 31 | 32 | let position: ALPosition = ALPosition.middle(i) 33 | return self.safeInsert(contentsOf: newElements, at: position) 34 | } 35 | 36 | internal mutating func safeInsert(contentsOf newElements: C, at position: ALPosition) -> Bool where C : Collection, Element == C.Element { 37 | 38 | let index: Int = self.getRealIndex(operation: .insert, position: position) 39 | guard index >= 0 && index <= self.count else { 40 | return false 41 | } 42 | self.insert(contentsOf: newElements, at: index) 43 | return true 44 | } 45 | 46 | internal mutating func safeReplace(contentsOf newElements: C, at i: Int) -> Bool where C: Collection, Element == C.Element { 47 | 48 | let position: ALPosition = ALPosition.middle(i) 49 | return self.safeReplace(contentsOf: newElements, at: position) 50 | } 51 | 52 | internal mutating func safeReplace(contentsOf newElements: C, at position: ALPosition) -> Bool where C: Collection, Element == C.Element { 53 | 54 | let initialIndex = self.getRealIndex(operation: .replace, position: position) 55 | let finalIndex = initialIndex + Int(newElements.count) 56 | guard initialIndex >= 0, 57 | finalIndex <= self.count else { 58 | return false 59 | } 60 | 61 | let headArray = self[0.. Bool { 70 | 71 | let position: ALPosition = ALPosition.middle(i) 72 | return self.safeDelete(numberOfElements: numberOfElements, at: position) 73 | } 74 | 75 | internal mutating func safeDelete(numberOfElements: Int, at position: ALPosition) -> Bool { 76 | 77 | let initialIndex = self.getRealIndex(operation: .delete, position: position) 78 | let finalIndex = initialIndex + numberOfElements 79 | guard initialIndex >= 0, 80 | finalIndex <= self.count else { 81 | return false 82 | } 83 | let headArray = self[0.. Int { 91 | 92 | let indexOperator: ALIndexOperator = self.getIndexOperator(operation: operation, position: position) 93 | return indexOperator.calculateIndex() 94 | 95 | } 96 | 97 | private func getIndexOperator(operation: ALOperation, position: ALPosition) -> ALIndexOperator { 98 | 99 | return operation.getIndexOperator(position: position, numberOfElements: self.count) 100 | } 101 | 102 | 103 | 104 | } 105 | 106 | extension Array where Element: Equatable { 107 | 108 | /// SwifterSwift: Check if array contains an array of elements. 109 | /// 110 | /// [1, 2, 3, 4, 5].contains([1, 2]) -> true 111 | /// [1.2, 2.3, 4.5, 3.4, 4.5].contains([2, 6]) -> false 112 | /// ["h", "e", "l", "l", "o"].contains(["l", "o"]) -> true 113 | /// 114 | /// - Parameter elements: array of elements to check. 115 | /// - Returns: true if array contains all given items. 116 | internal func contains(_ elements: [Element]) -> Bool { 117 | guard !elements.isEmpty else { return true } 118 | var found = true 119 | for element in elements { 120 | if !self.contains(element) { 121 | found = false 122 | } 123 | } 124 | return found 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/SwipeCellKit/Source/SwipeAction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeAction.swift 3 | // 4 | // Created by Jeremy Koch 5 | // Copyright © 2017 Jeremy Koch. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | /// Constants that help define the appearance of action buttons. 11 | public enum SwipeActionStyle: Int { 12 | /// Apply a style that reflects standard non-destructive actions. 13 | case `default` 14 | 15 | /// Apply a style that reflects destructive actions. 16 | case destructive 17 | } 18 | 19 | /** 20 | The `SwipeAction` object defines a single action to present when the user swipes horizontally in a table/collection item. 21 | 22 | This class lets you define one or more custom actions to display for a given item in your table/collection. Each instance of this class represents a single action to perform and includes the text, formatting information, and behavior for the corresponding button. 23 | */ 24 | public class SwipeAction: NSObject { 25 | /// An optional unique action identifier. 26 | public var identifier: String? 27 | 28 | /// The title of the action button. 29 | /// 30 | /// - note: You must specify a title or an image. 31 | public var title: String? 32 | 33 | /// The style applied to the action button. 34 | public var style: SwipeActionStyle 35 | 36 | /// The object that is notified as transitioning occurs. 37 | public var transitionDelegate: SwipeActionTransitioning? 38 | 39 | /// The font to use for the title of the action button. 40 | /// 41 | /// - note: If you do not specify a font, a 15pt system font is used. 42 | public var font: UIFont? 43 | 44 | /// The text color of the action button. 45 | /// 46 | /// - note: If you do not specify a color, white is used. 47 | public var textColor: UIColor? 48 | 49 | /// The highlighted text color of the action button. 50 | /// 51 | /// - note: If you do not specify a color, `textColor` is used. 52 | public var highlightedTextColor: UIColor? 53 | 54 | /// The image used for the action button. 55 | /// 56 | /// - note: You must specify a title or an image. 57 | public var image: UIImage? 58 | 59 | /// The highlighted image used for the action button. 60 | /// 61 | /// - note: If you do not specify a highlight image, the default `image` is used for the highlighted state. 62 | public var highlightedImage: UIImage? 63 | 64 | /// The closure to execute when the user taps the button associated with this action. 65 | public var handler: ((SwipeAction, IndexPath) -> Void)? 66 | 67 | /// The background color of the action button. 68 | /// 69 | /// - note: Use this property to specify the background color for your button. If you do not specify a value for this property, the framework assigns a default color based on the value in the style property. 70 | public var backgroundColor: UIColor? 71 | 72 | /// The highlighted background color of the action button. 73 | /// 74 | /// - note: Use this property to specify the highlighted background color for your button. 75 | public var highlightedBackgroundColor: UIColor? 76 | 77 | /// The visual effect to apply to the action button. 78 | /// 79 | /// - note: Assigning a visual effect object to this property adds that effect to the background of the action button. 80 | public var backgroundEffect: UIVisualEffect? 81 | 82 | /// A Boolean value that determines whether the actions menu is automatically hidden upon selection. 83 | /// 84 | /// - note: When set to `true`, the actions menu is automatically hidden when the action is selected. The default value is `false`. 85 | public var hidesWhenSelected = false 86 | 87 | /** 88 | Constructs a new `SwipeAction` instance. 89 | 90 | - parameter style: The style of the action button. 91 | - parameter title: The title of the action button. 92 | - parameter handler: The closure to execute when the user taps the button associated with this action. 93 | */ 94 | public init(style: SwipeActionStyle, title: String?, handler: ((SwipeAction, IndexPath) -> Void)?) { 95 | self.title = title 96 | self.style = style 97 | self.handler = handler 98 | } 99 | 100 | /** 101 | Calling this method performs the configured expansion completion animation including deletion, if necessary. Calling this method more than once has no effect. 102 | 103 | You should only call this method from the implementation of your action `handler` method. 104 | 105 | - parameter style: The desired style for completing the expansion action. 106 | */ 107 | public func fulfill(with style: ExpansionFulfillmentStyle) { 108 | completionHandler?(style) 109 | } 110 | 111 | // MARK: - Internal 112 | 113 | internal var completionHandler: ((ExpansionFulfillmentStyle) -> Void)? 114 | } 115 | 116 | /// Describes how expansion should be resolved once the action has been fulfilled. 117 | public enum ExpansionFulfillmentStyle { 118 | /// Implies the item will be deleted upon action fulfillment. 119 | case delete 120 | 121 | /// Implies the item will be reset and the actions view hidden upon action fulfillment. 122 | case reset 123 | } 124 | 125 | // MARK: - Internal 126 | 127 | internal extension SwipeAction { 128 | var hasBackgroundColor: Bool { 129 | return backgroundColor != .clear && backgroundEffect == nil 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /ALTableViewSwift/ALTableView/ALTableViewTests/ALRowElement/ALRowElementInitialization.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ALRowElementInizialization.swift 3 | // ALTableViewTests 4 | // 5 | // Created by lorenzo villarroel perez on 16/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import ALTableView 11 | 12 | class ALRowElementInitialization: XCTestCase { 13 | 14 | private let cellIdentifier = "MasterTableViewCell" 15 | private var tableView: UITableView! 16 | private var viewController: UIViewController! 17 | 18 | override func setUp() { 19 | super.setUp() 20 | self.tableView = UITableView() 21 | self.viewController = UIViewController() 22 | // Put setup code here. This method is called before the invocation of each test method in the class. 23 | } 24 | 25 | override func tearDown() { 26 | // Put teardown code here. This method is called after the invocation of each test method in the class. 27 | super.tearDown() 28 | self.tableView = nil 29 | self.viewController = nil 30 | } 31 | 32 | // func testDefaultConstructor() { 33 | // let alTableView = ALTableView(sectionElements: [], viewController: viewController, tableView: tableView) 34 | // alTableView.registerCell(nibName: cellIdentifier, reuseIdentifier: cellIdentifier) 35 | // 36 | // let dataObject = "Test" 37 | // let rowElement: ALRowElement = ALRowElement(className: MasterTableViewCell.classForCoder(), identifier: cellIdentifier, dataObject: dataObject) 38 | // if let rowDataObject = rowElement.getDataObject() as? String { 39 | // XCTAssert(rowDataObject == dataObject, "Data Object does not match the passed one") 40 | // } else { 41 | // XCTFail("Data Object class does not match the passed one") 42 | // } 43 | // 44 | // XCTAssert(rowElement.getHeight() == 44, "The height is not the default one") 45 | // 46 | // if let cell = rowElement.getViewFrom(tableView: tableView) as? MasterTableViewCell { 47 | // if let cellText = cell.labelText.text { 48 | // XCTAssert(cellText == dataObject, "Cell text does not match the passed one") 49 | // } 50 | // } else { 51 | // XCTFail("Cell class does not match the passed one") 52 | // } 53 | // } 54 | // 55 | // func testCustomConstructor1() { 56 | // self.testCustomConstructor(estimateHeightMode: true) 57 | // } 58 | // 59 | // func testCustomConstructor2() { 60 | // self.testCustomConstructor(estimateHeightMode: false) 61 | // } 62 | // 63 | // func testCustomConstructor(estimateHeightMode: Bool = true) { 64 | // let cellHeight: CGFloat = 50.0 65 | // let alTableView = ALTableView(sectionElements: [], viewController: viewController, tableView: tableView) 66 | // alTableView.registerCell(nibName: cellIdentifier, reuseIdentifier: cellIdentifier) 67 | // 68 | // let dataObject = "Test" 69 | // let labelTextPressed = "Pressed" 70 | // let labelTextDeselected = "Deselected" 71 | // let rowElement: ALRowElement = ALRowElement(className: MasterTableViewCell.classForCoder(), identifier: cellIdentifier, dataObject: dataObject, cellStyle: .default, estimateHeightMode: estimateHeightMode, height: cellHeight, pressedHandler: { (viewController, cell) in 72 | // if let masterCell = cell as? MasterTableViewCell { 73 | // masterCell.labelText.text = labelTextPressed 74 | // } else { 75 | // XCTFail("Cell incorrect") 76 | // } 77 | // }, createdHandler: { (object, cell) in 78 | // if let masterCell = cell as? MasterTableViewCell { 79 | // if let string = object as? String { 80 | // XCTAssert(string == dataObject, "Data Object does not match the passed one") 81 | // masterCell.labelText.text = string 82 | // } else { 83 | // XCTFail("Data Object Incorrect") 84 | // } 85 | // } else { 86 | // XCTFail("Cell incorrect") 87 | // } 88 | // }, deselectedHandler: { (cell) in 89 | // if let masterCell = cell as? MasterTableViewCell { 90 | // masterCell.labelText.text = labelTextDeselected 91 | // } else { 92 | // XCTFail("Cell incorrect") 93 | // } 94 | // }) 95 | // 96 | // if let rowDataObject = rowElement.getDataObject() as? String { 97 | // XCTAssert(rowDataObject == dataObject, "Data Object does not match the passed one") 98 | // } else { 99 | // XCTFail("Data Object class does not match the passed one") 100 | // } 101 | // 102 | // if estimateHeightMode { 103 | // XCTAssert(rowElement.getHeight() == UITableViewAutomaticDimension, "The height is not the default one") 104 | // } else { 105 | // XCTAssert(rowElement.getHeight() == cellHeight, "The height is not the default one") 106 | // } 107 | // 108 | // XCTAssert(rowElement.isEstimateHeightMode() == estimateHeightMode, "The estimate mode does not match the passed one") 109 | // 110 | // if let cell = rowElement.getViewFrom(tableView: tableView) as? MasterTableViewCell { 111 | // if let cellText = cell.labelText.text { 112 | // XCTAssert(cellText == dataObject, "Cell text does not match the passed one") 113 | // } 114 | // rowElement.rowElementPressed(viewController: viewController, cell: cell) 115 | // if let cellText = cell.labelText.text { 116 | // XCTAssert(cellText == labelTextPressed, "Cell text does not match the passed one") 117 | // } 118 | // rowElement.rowElementDeselected(cell: cell) 119 | // if let cellText = cell.labelText.text { 120 | // XCTAssert(cellText == labelTextDeselected, "Cell text does not match the passed one") 121 | // } 122 | // } else { 123 | // XCTFail("Cell class does not match the passed one") 124 | // } 125 | // } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-TestALTableView/Pods-TestALTableView-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableView/Pods-ALTableView-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | # Used as a return value for each invocation of `strip_invalid_archs` function. 10 | STRIP_BINARY_RETVAL=0 11 | 12 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 13 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 14 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 15 | 16 | # Copies and strips a vendored framework 17 | install_framework() 18 | { 19 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 20 | local source="${BUILT_PRODUCTS_DIR}/$1" 21 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 22 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 23 | elif [ -r "$1" ]; then 24 | local source="$1" 25 | fi 26 | 27 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 28 | 29 | if [ -L "${source}" ]; then 30 | echo "Symlinked..." 31 | source="$(readlink "${source}")" 32 | fi 33 | 34 | # Use filter instead of exclude so missing patterns don't throw errors. 35 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 36 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 37 | 38 | local basename 39 | basename="$(basename -s .framework "$1")" 40 | binary="${destination}/${basename}.framework/${basename}" 41 | if ! [ -r "$binary" ]; then 42 | binary="${destination}/${basename}" 43 | fi 44 | 45 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 46 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 47 | strip_invalid_archs "$binary" 48 | fi 49 | 50 | # Resign the code if required by the build settings to avoid unstable apps 51 | code_sign_if_enabled "${destination}/$(basename "$1")" 52 | 53 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 54 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 55 | local swift_runtime_libs 56 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 57 | for lib in $swift_runtime_libs; do 58 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 59 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 60 | code_sign_if_enabled "${destination}/${lib}" 61 | done 62 | fi 63 | } 64 | 65 | # Copies and strips a vendored dSYM 66 | install_dsym() { 67 | local source="$1" 68 | if [ -r "$source" ]; then 69 | # Copy the dSYM into a the targets temp dir. 70 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 71 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 72 | 73 | local basename 74 | basename="$(basename -s .framework.dSYM "$source")" 75 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 76 | 77 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 78 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 79 | strip_invalid_archs "$binary" 80 | fi 81 | 82 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 83 | # Move the stripped file into its final destination. 84 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 85 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 86 | else 87 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 88 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 89 | fi 90 | fi 91 | } 92 | 93 | # Signs a framework with the provided identity 94 | code_sign_if_enabled() { 95 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 96 | # Use the current code_sign_identitiy 97 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 98 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 99 | 100 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 101 | code_sign_cmd="$code_sign_cmd &" 102 | fi 103 | echo "$code_sign_cmd" 104 | eval "$code_sign_cmd" 105 | fi 106 | } 107 | 108 | # Strip invalid architectures 109 | strip_invalid_archs() { 110 | binary="$1" 111 | # Get architectures for current target binary 112 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 113 | # Intersect them with the architectures we are building for 114 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 115 | # If there are no archs supported by this binary then warn the user 116 | if [[ -z "$intersected_archs" ]]; then 117 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 118 | STRIP_BINARY_RETVAL=0 119 | return 120 | fi 121 | stripped="" 122 | for arch in $binary_archs; do 123 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 124 | # Strip non-valid architectures in-place 125 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 126 | stripped="$stripped $arch" 127 | fi 128 | done 129 | if [[ "$stripped" ]]; then 130 | echo "Stripped $binary of architectures:$stripped" 131 | fi 132 | STRIP_BINARY_RETVAL=1 133 | } 134 | 135 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 136 | wait 137 | fi 138 | -------------------------------------------------------------------------------- /ALTableViewSwift/TestALTableView/TestALTableView/MasterViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MasterViewController.swift 3 | // ALTableView 4 | // 5 | // Created by lorenzo villarroel perez on 7/3/18. 6 | // Copyright © 2018 lorenzo villarroel perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ALTableView 11 | 12 | class MasterViewController: UITableViewController, ALTableViewProtocol { 13 | 14 | var detailViewController: DetailViewController? = nil 15 | var alTableView: ALTableView? 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | // Do any additional setup after loading the view, typically from a nib. 20 | if let split = splitViewController { 21 | let controllers = split.viewControllers 22 | detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController 23 | } 24 | self.tableView.tableFooterView = UIView() 25 | 26 | 27 | let sectionElements = self.createElements() 28 | 29 | self.alTableView = ALTableView(sectionElements: [ALSectionElement](), viewController: self, tableView: self.tableView) 30 | self.alTableView?.delegate = self 31 | self.registerCells() 32 | self.alTableView?.replaceAllSections(sectionElements: sectionElements) 33 | // self.tableView.reloadData() 34 | self.navigationItem.leftBarButtonItem = self.editButtonItem; 35 | self.alTableView?.addPullToRefresh(title: NSAttributedString(string: "Refreshing..."), backgroundColor: .green, tintColor: .blue) 36 | } 37 | 38 | override func viewWillAppear(_ animated: Bool) { 39 | clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed 40 | super.viewWillAppear(animated) 41 | } 42 | 43 | override func didReceiveMemoryWarning() { 44 | super.didReceiveMemoryWarning() 45 | // Dispose of any resources that can be recreated. 46 | } 47 | 48 | // MARK: - Segues 49 | 50 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 51 | if segue.identifier == "showDetail" { 52 | // if let indexPath = tableView.indexPathForSelectedRow { 53 | // let object = objects[indexPath.row] as! NSDate 54 | // let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController 55 | // controller.detailItem = object 56 | // controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem 57 | // controller.navigationItem.leftItemsSupplementBackButton = true 58 | // } 59 | } 60 | } 61 | 62 | func createElements() -> [ALSectionElement] { 63 | var sectionElements = [ALSectionElement]() 64 | var rowElements = Array() 65 | for _ in 0...8 { 66 | 67 | let rowElement = ALRowElement(className:MasterTableViewCell.classForCoder(), identifier: MasterTableViewCell.reuseIdentifier, dataObject: "Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1Texto 1", estimateHeightMode: true, editingAllowed: true) 68 | let rowElement2 = ALRowElement(className:Master2TableViewCell.classForCoder(), identifier: Master2TableViewCell.reuseIdentifier, dataObject: 12, estimateHeightMode: true) 69 | rowElements.append(rowElement) 70 | rowElements.append(rowElement2) 71 | 72 | 73 | 74 | 75 | } 76 | 77 | let headerElement = ALHeaderFooterElement(identifier: MasterHeaderFooter.reuseIdentifier, dataObject: "Header Test", estimateHeightMode: true) 78 | 79 | let section = ALSectionElement(rowElements: rowElements, headerElement: headerElement, footerElement: nil, isExpandable: true) 80 | 81 | sectionElements.append(section) 82 | // sectionElements.append(ALSectionElement(rowElements: [ALRowElement](), headerElement: nil, footerElement: nil, isExpandable: true)) 83 | 84 | return sectionElements 85 | } 86 | 87 | // func createElements() -> [ALSectionElement] { 88 | // var sectionElements = [ALSectionElement]() 89 | // var rowElements = Array() 90 | // for i in 0...8 { 91 | // let element = OrderElement(orderId: TextStyles.ordersElement(text: "\(i)"), 92 | // orderAmount: TextStyles.ordersElement(text: "\(i)\(i)\(i)"), 93 | // orderCreationDate: Date(), 94 | // orderStatus: TextStyles.ordersElement(text: "status \(i)\(i)\(i)"), 95 | // delegate: nil) 96 | // 97 | // let rowElement = ALRowElement(className: OrdersTableViewCell.classForCoder(), 98 | // identifier: OrdersTableViewCell.reuseIdentifier, 99 | // dataObject: element, 100 | // estimateHeightMode: true, 101 | // height: 92.0) 102 | //// let rowElement = ALRowElement(className: OrdersTableViewCell.classForCoder(), 103 | //// identifier: OrdersTableViewCell.reuseIdentifier, 104 | //// dataObject: element, 105 | //// estimateHeightMode: true) 106 | // rowElements.append(rowElement) 107 | // 108 | // 109 | // } 110 | // let section = ALSectionElement(rowElements: rowElements, headerElement: nil, footerElement: nil, isExpandable: true) 111 | // 112 | // sectionElements.append(section) 113 | // 114 | // return sectionElements 115 | // } 116 | 117 | func registerCells() { 118 | self.alTableView?.registerCell(nibName: MasterTableViewCell.nib, reuseIdentifier: MasterTableViewCell.reuseIdentifier) 119 | self.alTableView?.registerCell(nibName: Master2TableViewCell.nib, reuseIdentifier: Master2TableViewCell.reuseIdentifier) 120 | self.alTableView?.registerHeaderFooter(nibName: MasterHeaderFooter.nib, reuseIdentifier: MasterHeaderFooter.reuseIdentifier) 121 | 122 | 123 | alTableView?.registerCell(nibName: OrdersTableViewCell.nib, 124 | reuseIdentifier: OrdersTableViewCell.reuseIdentifier) 125 | alTableView?.registerCell(nibName: LoadingTableViewCell.nib, 126 | reuseIdentifier: LoadingTableViewCell.reuseIdentifier) 127 | alTableView?.registerCell(nibName: LoadingRetryTableViewCell.nib, 128 | reuseIdentifier: LoadingRetryTableViewCell.reuseIdentifier) 129 | } 130 | 131 | func tableViewPullToRefresh() { 132 | print("Refreshed") 133 | } 134 | 135 | func tableViewDidReachEnd() { 136 | print("tableViewDidReachEnd") 137 | } 138 | 139 | } 140 | 141 | -------------------------------------------------------------------------------- /ALTableViewSwift/Pods/Target Support Files/Pods-ALTableViewTests/Pods-ALTableViewTests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 95 | else 96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 145 | wait 146 | fi 147 | --------------------------------------------------------------------------------