Commit 1aa6b0a4 authored by jzhang's avatar jzhang

no message

parent e0c176e8
......@@ -40,6 +40,8 @@
697B07ED284F2E5C0051FC23 /* CompleteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 697B07EC284F2E5C0051FC23 /* CompleteVC.swift */; };
6989B7B72852EAB90014BB5B /* wakelock.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6989B7B52852EAA20014BB5B /* wakelock.xcframework */; };
6989B7B82852EAB90014BB5B /* wakelock.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6989B7B52852EAA20014BB5B /* wakelock.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
8DE79EDB672D5394BDEB806E /* Pods_BreastFeedingDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39043640BDC7A50986C47129 /* Pods_BreastFeedingDemo.framework */; };
EA14360528E0BF1900FFBE72 /* DemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA14360428E0BF1900FFBE72 /* DemoViewController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
......@@ -94,6 +96,7 @@
6989B7B52852EAA20014BB5B /* wakelock.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = wakelock.xcframework; sourceTree = "<group>"; };
8C76E81CF245C7C738786086 /* Pods-BreastFeedingDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BreastFeedingDemo.debug.xcconfig"; path = "Target Support Files/Pods-BreastFeedingDemo/Pods-BreastFeedingDemo.debug.xcconfig"; sourceTree = "<group>"; };
A4415E51DE97A1784932289A /* Pods-BreastFeedingDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BreastFeedingDemo.release.xcconfig"; path = "Target Support Files/Pods-BreastFeedingDemo/Pods-BreastFeedingDemo.release.xcconfig"; sourceTree = "<group>"; };
EA14360428E0BF1900FFBE72 /* DemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -113,6 +116,7 @@
694B85EB2848ECF2009BEDE1 /* App.xcframework in Frameworks */,
694B85F92848EDC4009BEDE1 /* FlutterPluginRegistrant.xcframework in Frameworks */,
694B85ED2848ECF4009BEDE1 /* camera.xcframework in Frameworks */,
8DE79EDB672D5394BDEB806E /* Pods_BreastFeedingDemo.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -155,6 +159,7 @@
694B85BB2848EB4C009BEDE1 /* AppDelegate.swift */,
694B85BD2848EB4C009BEDE1 /* SceneDelegate.swift */,
694B85BF2848EB4C009BEDE1 /* ViewController.swift */,
EA14360428E0BF1900FFBE72 /* DemoViewController.swift */,
697B07EC284F2E5C0051FC23 /* CompleteVC.swift */,
692EC419284C81700043E3EA /* ViewModel.swift */,
694B85C12848EB4C009BEDE1 /* Main.storyboard */,
......@@ -213,6 +218,7 @@
694B85B52848EB4C009BEDE1 /* Frameworks */,
694B85B62848EB4C009BEDE1 /* Resources */,
694B85E62848EC8C009BEDE1 /* Embed Frameworks */,
5DA61345C58EE2716C01BA2C /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
......@@ -273,6 +279,23 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
5DA61345C58EE2716C01BA2C /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-BreastFeedingDemo/Pods-BreastFeedingDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-BreastFeedingDemo/Pods-BreastFeedingDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-BreastFeedingDemo/Pods-BreastFeedingDemo-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
8AF6361FD6EF23190F10D3B6 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
......@@ -305,6 +328,7 @@
694B85C02848EB4C009BEDE1 /* ViewController.swift in Sources */,
694B85BC2848EB4C009BEDE1 /* AppDelegate.swift in Sources */,
697B07ED284F2E5C0051FC23 /* CompleteVC.swift in Sources */,
EA14360528E0BF1900FFBE72 /* DemoViewController.swift in Sources */,
692EC41A284C81700043E3EA /* ViewModel.swift in Sources */,
694B85BE2848EB4C009BEDE1 /* SceneDelegate.swift in Sources */,
);
......@@ -455,7 +479,10 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 19;
DEVELOPMENT_TEAM = W3C84P5FPS;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Flutter";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = BreastFeedingDemo/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "BF AiDemo";
......@@ -489,7 +516,10 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 19;
DEVELOPMENT_TEAM = W3C84P5FPS;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Flutter";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = BreastFeedingDemo/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "BF AiDemo";
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>BreastFeedingDemo.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>BreastFeedingDemo.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
</dict>
</dict>
</plist>
......@@ -436,10 +436,10 @@
</objects>
<point key="canvasLocation" x="-601.44927536231887" y="-227.00892857142856"/>
</scene>
<!--View Controller-->
<!--Demo View Controller-->
<scene sceneID="uUl-lb-yQN">
<objects>
<viewController id="XVX-uo-beN" sceneMemberID="viewController">
<viewController storyboardIdentifier="DemoViewController" id="XVX-uo-beN" customClass="DemoViewController" customModule="BreastFeedingDemo" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="vsR-gb-RGA">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
......@@ -467,6 +467,7 @@
<state key="normal" title="" backgroundImage="icon_global"/>
<connections>
<action selector="showPanel:" destination="BYZ-38-t0r" eventType="touchUpInside" id="uX1-5I-hDE"/>
<action selector="switchLanguageAction:" destination="XVX-uo-beN" eventType="touchUpInside" id="46p-n9-Pdr"/>
</connections>
</button>
</subviews>
......
//
// DemoViewController.swift
// BreastFeedingDemo
//
// Created by jzhang on 2022/9/26.
//
import UIKit
import Popover
import ZJTableViewManager
class DemoViewController: UIViewController {
fileprivate var popover: Popover!
fileprivate var manager: ZJTableViewManager!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension DemoViewController {
@IBAction func switchLanguageAction(_ sender: UIButton) {
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 200, height: 135))
// tableView.isScrollEnabled = false
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
} else {
// Fallback on earlier versions
}
manager = ZJTableViewManager(tableView: tableView)
let section = ZJTableViewSection()
manager.add(section: section)
for i in 0...2 {
let item = ZJTableViewItem(text: String(i) + " text text")
section.add(item: item)
}
self.popover = Popover(options: [ .type(.up), .blackOverlayColor(UIColor(white: 0.0, alpha: 0.6))])
self.popover.show(tableView, fromView: sender)
}
}
......@@ -137,6 +137,7 @@ class ViewController: UIViewController {
@IBAction func showPanel(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
popupView.isHidden = !sender.isSelected
//
(panelV.viewWithTag(1000) as! UIButton).isSelected = false
(panelV.viewWithTag(1001) as! UIButton).isSelected = false
(panelV.viewWithTag(1002) as! UIButton).isSelected = false
......
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
source 'https://github.com/CocoaPods/Specs.git'
target 'BreastFeedingDemo' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
pod 'ZJTableViewManager', '~> 1.0.8'
pod 'Popover', '~> 1.3.0'
# Pods for BreastFeedingDemo
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
# Pods for BreastFeedingDemo
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
]
end
end
end
PODFILE CHECKSUM: 9e3e51b1ff29b93ccce59b38c7b3231538815b9f
PODS:
- Popover (1.3.0)
- ZJTableViewManager (1.0.8):
- ZJTableViewManager/Core (= 1.0.8)
- ZJTableViewManager/Other (= 1.0.8)
- ZJTableViewManager/Core (1.0.8)
- ZJTableViewManager/Other (1.0.8):
- ZJTableViewManager/Core
COCOAPODS: 1.11.3
DEPENDENCIES:
- Popover (~> 1.3.0)
- ZJTableViewManager (~> 1.0.8)
SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
- Popover
- ZJTableViewManager
SPEC CHECKSUMS:
Popover: 10e1d9528f81d9504df984b7b3f491292bc1822d
ZJTableViewManager: 670f0805009b4a2680f20412c9c7be6f41ba7595
PODFILE CHECKSUM: 6a55778ec27acc11a2018147be40d7ee909e78c5
COCOAPODS: 1.11.2
PODFILE CHECKSUM: 9e3e51b1ff29b93ccce59b38c7b3231538815b9f
PODS:
- Popover (1.3.0)
- ZJTableViewManager (1.0.8):
- ZJTableViewManager/Core (= 1.0.8)
- ZJTableViewManager/Other (= 1.0.8)
- ZJTableViewManager/Core (1.0.8)
- ZJTableViewManager/Other (1.0.8):
- ZJTableViewManager/Core
COCOAPODS: 1.11.3
DEPENDENCIES:
- Popover (~> 1.3.0)
- ZJTableViewManager (~> 1.0.8)
SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
- Popover
- ZJTableViewManager
SPEC CHECKSUMS:
Popover: 10e1d9528f81d9504df984b7b3f491292bc1822d
ZJTableViewManager: 670f0805009b4a2680f20412c9c7be6f41ba7595
PODFILE CHECKSUM: 6a55778ec27acc11a2018147be40d7ee909e78c5
COCOAPODS: 1.11.2
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Pods-BreastFeedingDemo.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B5C990C062A5766D35C8D9B8A6A9B6D2"
BuildableName = "Pods_BreastFeedingDemo.framework"
BlueprintName = "Pods-BreastFeedingDemo"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "89ADB0D61D0BE9648E9853F5F8BDA717"
BuildableName = "Popover.framework"
BlueprintName = "Popover"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F366DD389362A47A0707FE45D5503886"
BuildableName = "ZJTableViewManager.framework"
BlueprintName = "ZJTableViewManager"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Pods-BreastFeedingDemo.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>Popover.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>1</integer>
</dict>
<key>ZJTableViewManager.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict/>
</dict>
</plist>
This diff is collapsed.
Copyright (c) 2020 corin8823 <yusuke_takahashi@cyberagent.co.jp>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# Popover
[![CI Status](http://img.shields.io/travis/corin8823/Popover.svg?style=flat)](https://travis-ci.org/corin8823/Popover)
[![Version](https://img.shields.io/cocoapods/v/Popover.svg?style=flat)](http://cocoapods.org/pods/Popover)
[![License](https://img.shields.io/cocoapods/l/Popover.svg?style=flat)](http://cocoapods.org/pods/Popover)
[![Platform](https://img.shields.io/cocoapods/p/Popover.svg?style=flat)](http://cocoapods.org/pods/Popover)
## Description and [appetize.io`s DEMO](https://appetize.io/app/q4n81yf0aakkx20x2cejh107b4)
![](https://github.com/corin8823/Popover/blob/master/ScreenShots/Screenshot.gif)
## Usage
To run the example project, clone the repo, and run `pod install` from the Example directory first.
### Simple
```swift
let startPoint = CGPoint(x: self.view.frame.width - 60, y: 55)
let aView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 180))
let popover = Popover()
popover.show(aView, point: startPoint)
```
### Custom
```swift
@IBOutlet weak var leftBottomButton: UIButton!
let width = self.view.frame.width / 4
let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width))
let options = [
.type(.up),
.cornerRadius(width / 2),
.animationIn(0.3),
.blackOverlayColor(UIColor.red),
.arrowSize(CGSize.zero)
] as [PopoverOption]
let popover = Popover(options: options, showHandler: nil, dismissHandler: nil)
popover.show(aView, fromView: self.leftBottomButton)
```
## Requirements
- iOS 9.0+
- Swift 5
## Installation
### CocoaPods (iOS 8+)
Popover is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your `Podfile`:
```ruby
use_frameworks!
pod "Popover"
```
### Carthage (iOS 8+)
You can use [Carthage](https://github.com/Carthage/Carthage) to install `Popover` by adding it to your `Cartfile`:
```ruby
github "corin8823/Popover"
```
### Manual Installation
The class file required for Popover is located in the Classes folder in the root of this repository as listed below:
```
Popover.swift
```
## Customization
### Enum
- ``case arrowSize(CGSize)``
- ``case animationIn(NSTimeInterval)``
- ``case animationOut(NSTimeInterval)``
- ``case cornerRadius(CGFloat)``
- ``case sideEdge(CGFloat)``
- ``case blackOverlayColor(UIColor)``
- ``case overlayBlur(UIBlurEffectStyle)``
- ``case type(Popover.PopoverType)``
- ``case color(UIColor)``
- ``case dismissOnBlackOverlayTap(Bool)``
- ``case showBlackOverlay(Bool)``
### Property
- ``arrowSize: CGSize = CGSize(width: 16.0, height: 10.0)``
- ``animationIn: NSTimeInterval = 0.6``
- ``animationOut: NSTimeInterval = 0.3``
- ``cornerRadius: CGFloat = 6.0``
- ``sideEdge: CGFloat = 20.0``
- ``popoverType: PopoverType = .down``
- ``blackOverlayColor: UIColor = UIColor(white: 0.0, alpha: 0.2)``
- ``overlayBlur: UIBlurEffect?``
- ``popoverColor: UIColor = UIColor.white``
## Acknowledgments
Inspired by [DXPopover](https://github.com/xiekw2010/DXPopover) in [xiekw2010](https://github.com/xiekw2010)
## License
Popover is available under the MIT license. See the LICENSE file for more info.
# Acknowledgements
This application makes use of the following third party libraries:
## Popover
Copyright (c) 2020 corin8823 <yusuke_takahashi@cyberagent.co.jp>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## ZJTableViewManager
Copyright (c) 2018 Javen (https://github.com/JavenZ).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Generated by CocoaPods - https://cocoapods.org
......@@ -12,6 +12,63 @@
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2020 corin8823 &lt;yusuke_takahashi@cyberagent.co.jp&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>Popover</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2018 Javen (https://github.com/JavenZ).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>ZJTableViewManager</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
......
${PODS_ROOT}/Target Support Files/Pods-BreastFeedingDemo/Pods-BreastFeedingDemo-frameworks.sh
${BUILT_PRODUCTS_DIR}/Popover/Popover.framework
${BUILT_PRODUCTS_DIR}/ZJTableViewManager/ZJTableViewManager.framework
\ No newline at end of file
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Popover.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZJTableViewManager.framework
\ No newline at end of file
${PODS_ROOT}/Target Support Files/Pods-BreastFeedingDemo/Pods-BreastFeedingDemo-frameworks.sh
${BUILT_PRODUCTS_DIR}/Popover/Popover.framework
${BUILT_PRODUCTS_DIR}/ZJTableViewManager/ZJTableViewManager.framework
\ No newline at end of file
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Popover.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZJTableViewManager.framework
\ No newline at end of file
#!/bin/sh
set -e
set -u
set -o pipefail
function on_error {
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
}
trap 'on_error $LINENO' ERR
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
BCSYMBOLMAP_DIR="BCSymbolMaps"
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
echo "Installing $f"
install_bcsymbolmap "$f" "$destination"
rm "$f"
done
rmdir "${source}/${BCSYMBOLMAP_DIR}"
fi
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
elif [ -L "${binary}" ]; then
echo "Destination binary is symlinked..."
dirname="$(dirname "${binary}")"
binary="${dirname}/$(readlink "${binary}")"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
warn_missing_arch=${2:-true}
if [ -r "$source" ]; then
# Copy the dSYM into the targets temp dir.
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}\""
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}"
local basename
basename="$(basename -s .dSYM "$source")"
binary_name="$(ls "$source/Contents/Resources/DWARF")"
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
# Strip invalid architectures from the dSYM.
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
strip_invalid_archs "$binary" "$warn_missing_arch"
fi
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# 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.
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
fi
fi
}
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
warn_missing_arch=${2:-true}
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
if [[ "$warn_missing_arch" == "true" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
fi
STRIP_BINARY_RETVAL=1
return
fi
stripped=""
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary"
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=0
}
# Copies the bcsymbolmap files of a vendored framework
install_bcsymbolmap() {
local bcsymbolmap_path="$1"
local destination="${BUILT_PRODUCTS_DIR}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identity
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Popover/Popover.framework"
install_framework "${BUILT_PRODUCTS_DIR}/ZJTableViewManager/ZJTableViewManager.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Popover/Popover.framework"
install_framework "${BUILT_PRODUCTS_DIR}/ZJTableViewManager/ZJTableViewManager.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Popover" "${PODS_CONFIGURATION_BUILD_DIR}/ZJTableViewManager"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Popover/Popover.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZJTableViewManager/ZJTableViewManager.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "Popover" -framework "ZJTableViewManager"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
......
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Popover" "${PODS_CONFIGURATION_BUILD_DIR}/ZJTableViewManager"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Popover/Popover.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZJTableViewManager/ZJTableViewManager.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "Popover" -framework "ZJTableViewManager"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_Popover : NSObject
@end
@implementation PodsDummy_Popover
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double PopoverVersionNumber;
FOUNDATION_EXPORT const unsigned char PopoverVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Popover
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Popover
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module Popover {
umbrella header "Popover-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Popover
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Popover
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.8</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_ZJTableViewManager : NSObject
@end
@implementation PodsDummy_ZJTableViewManager
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double ZJTableViewManagerVersionNumber;
FOUNDATION_EXPORT const unsigned char ZJTableViewManagerVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ZJTableViewManager
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/ZJTableViewManager
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module ZJTableViewManager {
umbrella header "ZJTableViewManager-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ZJTableViewManager
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/ZJTableViewManager
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
Copyright (c) 2018 Javen (https://github.com/JavenZ).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
\ No newline at end of file
This diff is collapsed.
//
// ZJDefaultCell.swift
// NewRetail
//
// Created by Javen on 2018/2/8.
// Copyright © 2018年 . All rights reserved.
//
import UIKit
class ZJDefaultCell: UITableViewCell, ZJCellProtocol {
var item: ZJTableViewItem!
typealias ZJCellItemClass = ZJTableViewItem
func cellWillAppear() {}
}
//
// ZJProtocol.swift
// test
//
// Created by Jie Zhang on 2019/10/18.
// Copyright © 2019 Green Dot. All rights reserved.
//
import Foundation
import UIKit
// MARK: - ZJTableViewCellProtocol
public protocol ZJItemProtocol where Self: ZJTableViewItem {}
public protocol ZJInternalCellProtocol where Self: UITableViewCell {
var _item: ZJItemProtocol? { get set }
func cellWillAppear()
func cellDidAppear()
func cellDidDisappear()
}
public extension ZJInternalCellProtocol {
func cellDidAppear() {}
func cellDidDisappear() {}
}
public protocol ZJCellProtocol: ZJInternalCellProtocol {
associatedtype ZJCellItemClass: ZJItemProtocol
var item: ZJCellItemClass! { get set }
}
public extension ZJCellProtocol {
var _item: ZJItemProtocol? {
get {
return item
}
set {
item = (newValue as! Self.ZJCellItemClass)
}
}
}
extension ZJTableViewItem: ZJItemProtocol {}
// MARK: - ZJTableViewScrollDelegate
public protocol ZJTableViewScrollDelegate: NSObjectProtocol {
@available(iOS 2.0, *)
func scrollViewDidScroll(_ scrollView: UIScrollView) // any offset changes
@available(iOS 3.2, *)
func scrollViewDidZoom(_ scrollView: UIScrollView) // any zoom scale changes
// called on start of dragging (may require some time and or distance to move)
@available(iOS 2.0, *)
func scrollViewWillBeginDragging(_ scrollView: UIScrollView)
// called on finger up if the user dragged. velocity is in points/millisecond. targetContentOffset may be changed to adjust where the scroll view comes to rest
@available(iOS 5.0, *)
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
@available(iOS 2.0, *)
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
@available(iOS 2.0, *)
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) // called on finger up as we are moving
@available(iOS 2.0, *)
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) // called when scroll view grinds to a halt
@available(iOS 2.0, *)
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) // called when setContentOffset/scrollRectVisible:animated: finishes. not called if not animating
@available(iOS 2.0, *)
func viewForZooming(in scrollView: UIScrollView) -> UIView? // return a view that will be scaled. if delegate returns nil, nothing happens
@available(iOS 3.2, *)
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) // called before the scroll view begins zooming its content
@available(iOS 2.0, *)
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) // scale between minimum and maximum. called after any 'bounce' animations
@available(iOS 2.0, *)
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool // return a yes if you want to scroll to the top. if not defined, assumes YES
@available(iOS 2.0, *)
func scrollViewDidScrollToTop(_ scrollView: UIScrollView) // called when scrolling animation finished. may be called immediately if already at top
/* Also see -[UIScrollView adjustedContentInsetDidChange]
*/
@available(iOS 11.0, *)
func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView)
}
// MARK: - ZJTableViewScrollDelegate Default Implementation
public extension ZJTableViewScrollDelegate {
func scrollViewDidScroll(_: UIScrollView) {}
func scrollViewDidZoom(_: UIScrollView) {}
func scrollViewWillBeginDragging(_: UIScrollView) {}
func scrollViewWillEndDragging(_: UIScrollView, withVelocity _: CGPoint, targetContentOffset _: UnsafeMutablePointer<CGPoint>) {}
func scrollViewDidEndDragging(_: UIScrollView, willDecelerate _: Bool) {}
func scrollViewWillBeginDecelerating(_: UIScrollView) {}
func scrollViewDidEndDecelerating(_: UIScrollView) {}
func scrollViewDidEndScrollingAnimation(_: UIScrollView) {}
func viewForZooming(in _: UIScrollView) -> UIView? { return nil }
func scrollViewWillBeginZooming(_: UIScrollView, with _: UIView?) {}
func scrollViewDidEndZooming(_: UIScrollView, with _: UIView?, atScale _: CGFloat) {}
func scrollViewShouldScrollToTop(_: UIScrollView) -> Bool { return true }
func scrollViewDidScrollToTop(_: UIScrollView) {}
func scrollViewDidChangeAdjustedContentInset(_: UIScrollView) {}
}
// MARK: - UIScrollViewDelegate
extension ZJTableViewManager: UIScrollViewDelegate {
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
d.scrollViewDidScroll(scrollView)
}
}
public func scrollViewDidZoom(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
d.scrollViewDidZoom(scrollView)
}
}
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
d.scrollViewWillBeginDragging(scrollView)
}
}
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if let d = scrollDelegate {
d.scrollViewWillEndDragging(scrollView, withVelocity: velocity, targetContentOffset: targetContentOffset)
}
}
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if let d = scrollDelegate {
d.scrollViewDidEndDragging(scrollView, willDecelerate: decelerate)
}
}
public func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
d.scrollViewWillBeginDecelerating(scrollView)
}
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
d.scrollViewDidEndDecelerating(scrollView)
}
}
public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
d.scrollViewDidEndScrollingAnimation(scrollView)
}
}
public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
if let d = scrollDelegate {
return d.viewForZooming(in: scrollView)
}
return nil
}
public func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
if let d = scrollDelegate {
d.scrollViewWillBeginZooming(scrollView, with: view)
}
}
public func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
if let d = scrollDelegate {
d.scrollViewDidEndZooming(scrollView, with: view, atScale: scale)
}
}
public func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
if let d = scrollDelegate {
return d.scrollViewShouldScrollToTop(scrollView)
}
return true
}
public func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
d.scrollViewDidScrollToTop(scrollView)
}
}
public func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView) {
if let d = scrollDelegate {
if #available(iOS 11.0, *) {
d.scrollViewDidChangeAdjustedContentInset(scrollView)
} else {
// Fallback on earlier versions
}
}
}
}
//
// ZJTableViewItem.swift
// NewRetail
//
// Created by Javen on 2018/2/8.
// Copyright © 2018年 . All rights reserved.
//
import UIKit
public typealias ZJTableViewItemBlock = (ZJTableViewItem) -> Void
open class ZJTableViewItem: NSObject {
public var tableVManager: ZJTableViewManager {
return section.tableViewManager
}
private weak var _section: ZJTableViewSection?
public var section: ZJTableViewSection {
set {
_section = newValue
}
get {
guard let s = _section else { fatalError() }
return s
}
}
public var cellIdentifier: String!
/// cell高度(如果要自动计算高度,使用autoHeight(manager:)方法,框架会算出高度,具体看demo)
/// 传UITableViewAutomaticDimension则是系统实时计算高度,可能会有卡顿、reload弹跳等问题,不建议使用,有特殊需要可以选择使用
public var cellHeight: CGFloat!
/// cell点击事件的回调
public var selectionHandler: ZJTableViewItemBlock?
public func setSelectionHandler<T: ZJTableViewItem>(_ handler: ((_ callBackItem: T) -> Void)?) {
selectionHandler = { item in
handler?(item as! T)
}
}
public var deletionHandler: ZJTableViewItemBlock?
public func setDeletionHandler<T: ZJTableViewItem>(_ handler: ((_ callBackItem: T) -> Void)?) {
deletionHandler = { item in
handler?(item as! T)
}
}
public var labelText: String?
public var detailLabelText: String?
public var textAlignment: NSTextAlignment = .left
public var detailTextAlignment: NSTextAlignment = .left
public var image: UIImage?
public var highlightedImage: UIImage?
public var style: UITableViewCell.CellStyle = .default
public var accessoryType: UITableViewCell.AccessoryType = .none
public var selectionStyle: UITableViewCell.SelectionStyle = .default
public var editingStyle: UITableViewCell.EditingStyle = .none
public var accessoryView: UIView?
public var isSelected: Bool {
return cell.isSelected
}
public var isAllowSelect: Bool = true
public var indexPath: IndexPath {
let rowIndex = self.section.items.zj_indexOf(self)
let section = tableVManager.sections.zj_indexOf(self.section)
return IndexPath(item: rowIndex, section: section)
}
/// 尽量避免通过此属性直接修改cell里面的元素,直接修改cell没有修改修改数据源,由于TableViewCell的复用,会造成异常(正确做法是修改item的属性,通过item.reload()来刷新cell)
public var cell: UITableViewCell {
if let unwrappedCell = tableVManager.tableView.cellForRow(at: indexPath) {
return unwrappedCell
}
zj_log("没有获取到对应的cell,必须在tableView reload之后才能通过这个属性获取到cell。或者获取的indexPath对应的cell必须在屏幕内,无法获取屏幕外的cell")
fatalError()
}
override public init() {
super.init()
cellIdentifier = "\(type(of: self))"
cellHeight = 44
}
public convenience init(text: String?) {
self.init()
labelText = text
}
public func reload(_ animation: UITableView.RowAnimation) {
zj_log("reload tableview at \(indexPath)")
tableVManager.tableView.beginUpdates()
tableVManager.tableView.reloadRows(at: [indexPath], with: animation)
tableVManager.tableView.endUpdates()
}
public func select(animated: Bool = true, scrollPosition: UITableView.ScrollPosition = .none) {
if isAllowSelect {
tableVManager.tableView.selectRow(at: indexPath, animated: animated, scrollPosition: scrollPosition)
}
}
public func deselect(animated: Bool = true) {
tableVManager.tableView.deselectRow(at: indexPath, animated: animated)
}
public func delete(_ animation: UITableView.RowAnimation = .automatic) {
if section == nil {
zj_log("Item did not in section,please check section.add() method")
return
}
if !section.items.contains(where: { $0 == self }) {
zj_log("can't delete because this item did not in section")
return
}
let indexPath = self.indexPath
section.items.remove(at: indexPath.row)
tableVManager.tableView.deleteRows(at: [indexPath], with: animation)
}
/// 计算cell高度
///
/// - Parameters:
/// - manager: 当前tableview的manager
public func autoHeight(_ manager: ZJTableViewManager) {
guard let cell = manager.tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as? ZJInternalCellProtocol else {
zj_log("please register cell")
return
}
cell._item = self
cell.cellWillAppear()
cellHeight = cell.systemLayoutSizeFitting(CGSize(width: manager.tableView.frame.width, height: 0), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height
}
}
//
// ZJTableViewSection.swift
// NewRetail
//
// Created by Javen on 2018/2/8.
// Copyright © 2018年 . All rights reserved.
//
import UIKit
public typealias ZJTableViewSectionBlock = (ZJTableViewSection) -> Void
open class ZJTableViewSection: NSObject {
private weak var _tableViewManager: ZJTableViewManager?
public var tableViewManager: ZJTableViewManager {
set {
_tableViewManager = newValue
}
get {
guard let tableViewManager = _tableViewManager else {
zj_log("Please add section to manager")
fatalError()
}
return tableViewManager
}
}
public var items = [ZJTableViewItem]()
public var headerHeight: CGFloat!
public var footerHeight: CGFloat!
public var headerView: UIView?
public var footerView: UIView?
public var headerTitle: String?
public var footerTitle: String?
var headerWillDisplayHandler: ZJTableViewSectionBlock?
public func setHeaderWillDisplayHandler(_ block: ZJTableViewSectionBlock?) {
headerWillDisplayHandler = block
}
var headerDidEndDisplayHandler: ZJTableViewSectionBlock?
public func setHeaderDidEndDisplayHandler(_ block: ZJTableViewSectionBlock?) {
headerDidEndDisplayHandler = block
}
public var index: Int {
return tableViewManager.sections.zj_indexOf(self)
}
override public init() {
super.init()
items = []
headerHeight = CGFloat.leastNormalMagnitude
footerHeight = CGFloat.leastNormalMagnitude
}
public convenience init(headerHeight: CGFloat!, color: UIColor) {
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: headerHeight))
headerView.backgroundColor = color
self.init(headerView: headerView, footerView: nil)
}
public convenience init(headerTitle: String?, footerTitle: String?) {
self.init()
self.headerTitle = headerTitle
self.footerTitle = footerTitle
}
public convenience init(headerTitle: String?) {
self.init(headerTitle: headerTitle, footerTitle: nil)
}
public convenience init(footerTitle: String?) {
self.init(headerTitle: nil, footerTitle: footerTitle)
}
public convenience init(headerView: UIView!) {
self.init(headerView: headerView, footerView: nil)
}
public convenience init(footerView: UIView?) {
self.init(headerView: nil, footerView: footerView)
}
public convenience init(headerView: UIView?, footerView: UIView?) {
self.init()
if let header = headerView {
self.headerView = header
headerHeight = header.frame.size.height
}
if let footer = footerView {
self.footerView = footer
footerHeight = footer.frame.size.height
}
}
public func add(item: ZJTableViewItem) {
item.section = self
items.append(item)
}
public func remove(item: ZJTableViewItem) {
// If crash at here, item not in this section
items.remove(at: items.zj_indexOf(item))
}
public func removeAllItems() {
items.removeAll()
}
public func replaceItemsFrom(array: [ZJTableViewItem]!) {
removeAllItems()
items = items + array
}
public func insert(_ item: ZJTableViewItem!, afterItem: ZJTableViewItem, animate: UITableView.RowAnimation = .automatic) {
if !items.contains(where: { $0 == afterItem }) {
zj_log("can't insert because afterItem did not in sections")
return
}
tableViewManager.tableView.beginUpdates()
item.section = self
items.insert(item, at: items.zj_indexOf(afterItem) + 1)
tableViewManager.tableView.insertRows(at: [item.indexPath], with: animate)
tableViewManager.tableView.endUpdates()
}
public func insert(_ items: [ZJTableViewItem], afterItem: ZJTableViewItem, animate: UITableView.RowAnimation = .automatic) {
if !self.items.contains(where: { $0 == afterItem }) {
zj_log("can't insert because afterItem did not in sections")
return
}
tableViewManager.tableView.beginUpdates()
let newFirstIndex = self.items.zj_indexOf(afterItem) + 1
self.items.insert(contentsOf: items, at: newFirstIndex)
var arrNewIndexPath = [IndexPath]()
for i in 0 ..< items.count {
items[i].section = self
arrNewIndexPath.append(IndexPath(item: newFirstIndex + i, section: afterItem.indexPath.section))
}
tableViewManager.tableView.insertRows(at: arrNewIndexPath, with: animate)
tableViewManager.tableView.endUpdates()
}
public func delete(_ itemsToDelete: [ZJTableViewItem], animate: UITableView.RowAnimation = .automatic) {
guard itemsToDelete.count > 0 else { return }
tableViewManager.tableView.beginUpdates()
var arrNewIndexPath = [IndexPath]()
for i in itemsToDelete {
arrNewIndexPath.append(i.indexPath)
}
for i in itemsToDelete {
remove(item: i)
}
tableViewManager.tableView.deleteRows(at: arrNewIndexPath, with: animate)
tableViewManager.tableView.endUpdates()
}
public func reload(_ animation: UITableView.RowAnimation) {
// If crash at here, section did not in manager!
let index = tableViewManager.sections.zj_indexOf(self)
tableViewManager.tableView.reloadSections(IndexSet(integer: index), with: animation)
}
deinit {
print("Section Deinit")
}
}
//
// ZJExpandTreeCell.swift
// ZJExpandTreeDeme
//
// Created by Javen on 2019/3/19.
// Copyright © 2019 Javen. All rights reserved.
// https://www.jianshu.com/p/49ed18a01f19
import UIKit
open class ZJExpandTreeCellItem: ZJTableViewItem {
public private(set) var level: Int = 0
public var isExpand = false
public var arrSubLevel = [ZJExpandTreeCellItem]()
/// 展开或者收起下级cell的回调
public var willExpand: ((ZJExpandTreeCellItem) -> Void)?
public weak var superLevelItem: ZJExpandTreeCellItem?
/// 折叠时是否保持下级的树形结构
public var isKeepStructure = true
/// 是否自动折叠已经打开的Cell
public var isAutoClose = false
override public init() {
super.init()
selectionStyle = .none
setSelectionHandler { [unowned self] (callBackItem: ZJExpandTreeCellItem) in
if let superLevelItem = self.superLevelItem, superLevelItem.isAutoClose {
// 寻找同级已经展开的item
let arrItems = superLevelItem.getAllBelowItems().filter { $0.level == self.level && $0 != self && $0.isExpand }
for item in arrItems {
item.toggleExpand()
}
}
callBackItem.toggleExpand()
}
}
public func addSub(item: ZJExpandTreeCellItem, section: ZJTableViewSection) {
arrSubLevel.append(item)
item.superLevelItem = self
item.level = level + 1
if ZJExpandTreeCellItem.checkIfFoldedBySupperLevel(self), isExpand {
section.add(item: item)
}
}
/// 处理展开事件,返回值是当前cell的状态(展开或者收起)
@discardableResult open func toggleExpand() -> Bool {
var arrItems: [ZJExpandTreeCellItem]
if isExpand {
// 点击之前是打开的,直接通过递归获取item
arrItems = getAllBelowItems()
isExpand = !isExpand
} else {
// 点击之前是关闭的,需要先改变isExpand属性(不这么做会导致这一个level下一级的cell不显示)
isExpand = !isExpand
arrItems = getAllBelowItems()
if !isKeepStructure {
var tempItems = [ZJExpandTreeCellItem]()
for item in arrItems {
item.isExpand = false
if item.level == level + 1 {
tempItems.append(item)
}
}
arrItems = tempItems
}
}
willExpand?(self)
if isExpand {
section.insert(arrItems, afterItem: self, animate: .fade)
} else {
section.delete(arrItems, animate: .fade)
}
zj_log(isExpand ? "展开" : "收起")
return isExpand
}
/// 获取当前item下面所有的item
public func getAllBelowItems() -> [ZJExpandTreeCellItem] {
var arrItems = [ZJExpandTreeCellItem]()
ZJExpandTreeCellItem.recursionForItem(self, outItems: &arrItems)
return arrItems
}
/// 递归获取一个item下面所有显示的item
public class func recursionForItem(_ item: ZJExpandTreeCellItem, outItems: inout [ZJExpandTreeCellItem]) {
for subItem in item.arrSubLevel {
zj_log(subItem.level)
if item.isExpand == true {
outItems.append(subItem)
if item.arrSubLevel.count != 0 {
recursionForItem(subItem, outItems: &outItems)
}
}
}
}
// 递归判断一个item是否在某个父节点被折叠
public class func checkIfFoldedBySupperLevel(_ item: ZJExpandTreeCellItem) -> Bool {
guard let superItem = item.superLevelItem else {
return item.isExpand
}
if superItem.isExpand {
return checkIfFoldedBySupperLevel(superItem)
} else {
return false
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment