├── .gitignore ├── AutoPacking ├── Plist │ ├── AdHocExportOptionsPlist.plist │ ├── AppStoreExportOptionsPlist.plist │ └── DevelopmentExportOptionsPlist.plist └── autopacking.sh ├── AutoPackingDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── edz.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── edz.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── AutoPackingDemo.xcworkspace ├── contents.xcworkspacedata ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── edz.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── AutoPackingDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── Images ├── buildSucceed.png └── plistConfig.png ├── LICENSE ├── Podfile ├── Podfile.lock ├── Pods ├── Bugly │ └── Bugly.framework │ │ ├── Bugly │ │ ├── Headers │ │ ├── Bugly.h │ │ ├── BuglyConfig.h │ │ └── BuglyLog.h │ │ └── Modules │ │ └── module.modulemap ├── ElegantTableView │ ├── ElegantTableView │ │ ├── ElegantTableViewGenerator.h │ │ └── ElegantTableViewGenerator.m │ ├── LICENSE │ └── README.md ├── Headers │ ├── Private │ │ ├── ElegantTableView │ │ │ └── ElegantTableViewGenerator.h │ │ └── YJBannerView │ │ │ ├── UIView+YJBannerViewExt.h │ │ │ ├── YJAbstractDotView.h │ │ │ ├── YJAnimatedDotView.h │ │ │ ├── YJBannerView.h │ │ │ ├── YJBannerViewCell.h │ │ │ ├── YJBannerViewCollectionView.h │ │ │ ├── YJBannerViewFooter.h │ │ │ └── YJHollowPageControl.h │ └── Public │ │ ├── Bugly │ │ └── Bugly │ │ │ ├── Bugly.h │ │ │ ├── BuglyConfig.h │ │ │ └── BuglyLog.h │ │ ├── ElegantTableView │ │ └── ElegantTableViewGenerator.h │ │ └── YJBannerView │ │ ├── UIView+YJBannerViewExt.h │ │ ├── YJAbstractDotView.h │ │ ├── YJAnimatedDotView.h │ │ ├── YJBannerView.h │ │ ├── YJBannerViewCell.h │ │ ├── YJBannerViewCollectionView.h │ │ ├── YJBannerViewFooter.h │ │ └── YJHollowPageControl.h ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── edz.xcuserdatad │ │ └── xcschemes │ │ ├── ElegantTableView.xcscheme │ │ ├── Pods-AutoPackingDemo.xcscheme │ │ ├── YJBannerView.xcscheme │ │ └── xcschememanagement.plist ├── Target Support Files │ ├── ElegantTableView │ │ ├── ElegantTableView-dummy.m │ │ ├── ElegantTableView-prefix.pch │ │ └── ElegantTableView.xcconfig │ ├── Pods-AutoPackingDemo │ │ ├── Pods-AutoPackingDemo-acknowledgements.markdown │ │ ├── Pods-AutoPackingDemo-acknowledgements.plist │ │ ├── Pods-AutoPackingDemo-dummy.m │ │ ├── Pods-AutoPackingDemo-frameworks.sh │ │ ├── Pods-AutoPackingDemo-resources.sh │ │ ├── Pods-AutoPackingDemo.debug.xcconfig │ │ └── Pods-AutoPackingDemo.release.xcconfig │ └── YJBannerView │ │ ├── YJBannerView-dummy.m │ │ ├── YJBannerView-prefix.pch │ │ └── YJBannerView.xcconfig └── YJBannerView │ ├── LICENSE │ ├── README.md │ └── YJBannerViewDemo │ └── YJBannerView │ ├── PageControls │ └── YJHollowPageControl │ │ ├── YJAbstractDotView.h │ │ ├── YJAbstractDotView.m │ │ ├── YJAnimatedDotView.h │ │ ├── YJAnimatedDotView.m │ │ ├── YJHollowPageControl.h │ │ └── YJHollowPageControl.m │ ├── Resource │ └── YJBannerView.bundle │ │ ├── yjbanner_arrow@2x.png │ │ └── yjbanner_arrow@3x.png │ ├── Tools │ ├── UIView+YJBannerViewExt.h │ └── UIView+YJBannerViewExt.m │ ├── Views │ ├── YJBannerViewCell.h │ ├── YJBannerViewCell.m │ ├── YJBannerViewCollectionView.h │ ├── YJBannerViewCollectionView.m │ ├── YJBannerViewFooter.h │ └── YJBannerViewFooter.m │ ├── YJBannerView.h │ └── YJBannerView.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | 103 | .DS_Store 104 | -------------------------------------------------------------------------------- /AutoPacking/Plist/AdHocExportOptionsPlist.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | compileBitcode 6 | 7 | method 8 | ad-hoc 9 | signingStyle 10 | automatic 11 | stripSwiftSymbols 12 | 13 | teamID 14 | 2222222 15 | thinning 16 | <none> 17 | 18 | 19 | -------------------------------------------------------------------------------- /AutoPacking/Plist/AppStoreExportOptionsPlist.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | method 6 | app-store 7 | signingStyle 8 | automatic 9 | stripSwiftSymbols 10 | 11 | teamID 12 | 33333333 13 | uploadSymbols 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /AutoPacking/Plist/DevelopmentExportOptionsPlist.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | compileBitcode 6 | 7 | method 8 | development 9 | signingStyle 10 | automatic 11 | stripSwiftSymbols 12 | 13 | teamID 14 | 5XXXXXXXXXX3 15 | thinning 16 | <none> 17 | 18 | 19 | -------------------------------------------------------------------------------- /AutoPacking/autopacking.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 该脚本使用方法 3 | # 源码地址:https://github.com/stackhou 4 | # step 1. 在工程根目录新建AutoPacking文件夹,在该文件夹中新建文件autopacking.sh,将该脚本复制到autopacking.sh文件并保存(或者直接复制该文件); 5 | # step 2. 设置该脚本; 6 | # step 2. cd 该脚本目录,运行chmod +x autopacking.sh; 7 | # step 3. 终端运行 sh autopacking.sh; 8 | # step 4. 选择不同选项.... 9 | # step 5. Success 🎉 🎉 🎉! 10 | # 注意:可以全文搜索“配置”,看相关注释选择配置,因为不同的项目配置不同,最好有相关的基础知识 11 | 12 | # ************************* 需要配置 Start ******************************** 13 | 14 | # 【配置上传到蒲公英相关信息】(可选) 15 | __PGYER_U_KEY="4xxxxxxxxxxxxxxxb" 16 | __PGYER_API_KEY="3xxxxxxxxxxxxxx5" 17 | 18 | # 【配置上传到 Fir】(可选) 19 | __FIR_API_TOKEN="xKKdjdldlodeikK626266skdkkddK" 20 | 21 | # 【配置证书】(如果只有一个证书时该项 可选) 22 | __CODE_SIGN_DISTRIBUTION="iPhone Distribution: xxxxxxxxxxxCo., Ltd." 23 | __CODE_SIGN_DEVELOPMENT="iPhone Developer: xxxx xxxx (5xxxxxxxxxx2V)" 24 | 25 | # 发布APP Store 账号密码 26 | __IOS_SUBMIT_ACCOUNT="apple id" 27 | __IOS_SUBMIT_PASSWORD="xxxxxx" 28 | 29 | # ==================== 公共部分 ===================== 30 | # ######### 脚本样式 ############# 31 | __TITLE_LEFT_COLOR="\033[36;1m==== " 32 | __TITLE_RIGHT_COLOR=" ====\033[0m" 33 | 34 | __OPTION_LEFT_COLOR="\033[33;1m" 35 | __OPTION_RIGHT_COLOR="\033[0m" 36 | 37 | __LINE_BREAK_LEFT="\033[32;1m" 38 | __LINE_BREAK_RIGHT="\033[0m" 39 | 40 | # 红底白字 41 | __ERROR_MESSAGE_LEFT="\033[41m ! ! ! " 42 | __ERROR_MESSAGE_RIGHT=" ! ! ! \033[0m" 43 | 44 | # xcode version 45 | XCODE_BUILD_VERSION=$(xcodebuild -version) 46 | echo "-------------- Xcode版本: $XCODE_BUILD_VERSION -------------------" 47 | 48 | # 等待用户输入时间 49 | __WAIT_ELECT_TIME=0.2 50 | 51 | # 选择项输入方法 接收3个参数:1、选项标题 2、选项数组 3、选项数组的长度(0~256) 52 | function READ_USER_INPUT() { 53 | title=$1 54 | options=$2 55 | maxValue=$3 56 | echo "${__TITLE_LEFT_COLOR}${title}${__TITLE_RIGHT_COLOR}" 57 | for option in ${options[*]}; do 58 | echo "${__OPTION_LEFT_COLOR}${option}${__OPTION_RIGHT_COLOR}" 59 | done 60 | read 61 | __INPUT=$REPLY 62 | expr $__INPUT "+" 10 &> /dev/null 63 | if [[ $? -eq 0 ]]; then 64 | if [[ $__INPUT -gt 0 && $__INPUT -le $maxValue ]]; then 65 | return $__INPUT 66 | else 67 | echo "${__ERROR_MESSAGE_LEFT}输入越界了,请重新输入${__ERROR_MESSAGE_RIGHT}" 68 | READ_USER_INPUT $title "${options[*]}" $maxValue 69 | fi 70 | else 71 | echo "${__ERROR_MESSAGE_LEFT}输入有误,请输入0~256之间的数字序号${__ERROR_MESSAGE_RIGHT}" 72 | READ_USER_INPUT $title "${options[*]}" $maxValue 73 | fi 74 | } 75 | 76 | # 打印信息 77 | function printMessage() { 78 | pMessage=$1 79 | echo "${__LINE_BREAK_LEFT}${pMessage}${__LINE_BREAK_RIGHT}" 80 | } 81 | 82 | # 1. 请选择 SCHEME 83 | __SELECT_TARGET_OPTIONS=("1.AutoPackingDemo") 84 | READ_USER_INPUT "请选择对应的Target: " "${__SELECT_TARGET_OPTIONS[*]}" ${#__SELECT_TARGET_OPTIONS[*]} 85 | 86 | __SELECT_TARGET_OPTION=$? 87 | if [[ $__SELECT_TARGET_OPTION -eq 1 ]]; then 88 | __BUILD_TARGET="AutoPackingDemo" 89 | __SCHEME_NAME="AutoPackingDemo" 90 | else 91 | printMessage "这里请填写好你工程的所有target, 如果只有一个建议写死如下" 92 | # __BUILD_TARGET="AutoPackingDemo" 93 | exit 1 94 | fi 95 | 96 | # 2.Debug 或者 Release 选项 97 | __PACK_ENV_OPTIONS=("1.Release" "2.Debug") 98 | READ_USER_INPUT "请选择打包类型: " "${__PACK_ENV_OPTIONS[*]}" ${#__PACK_ENV_OPTIONS[*]} 99 | 100 | __PACK_ENV_OPTION=$? 101 | if [[ $__PACK_ENV_OPTION -eq 1 ]]; then 102 | __BUILD_CONFIGURATION="Release" 103 | elif [[ $__PACK_ENV_OPTION -eq 2 ]]; then 104 | __BUILD_CONFIGURATION="Debug" 105 | fi 106 | 107 | # 3. 工程类型(.xcworkspace项目,赋值true; .xcodeproj项目, 赋值false) 108 | __IS_WORKSPACE_OPTIONS=("1.是" "2.否") 109 | READ_USER_INPUT "请选择是否是.xcworkspace项目: " "${__IS_WORKSPACE_OPTIONS[*]}" ${#__IS_WORKSPACE_OPTIONS[*]} 110 | 111 | __IS_WORKSPACE_OPTION=$? 112 | 113 | # 4.# AdHoc, AppStore, Enterprise, Development 114 | __PACK_TYPES=("1.AdHoc" "2.AppStore" "3.Enterprise" "4.Development") 115 | READ_USER_INPUT "请选择打包环境类型(输入序号,直接回车): " "${__PACK_TYPES[*]}" ${#__PACK_TYPES[*]} 116 | 117 | __PACK_TYPE=$? 118 | if [[ $__PACK_TYPE -eq 1 ]]; then 119 | __EXPORT_OPTIONS_PLIST_PATH="./AutoPacking/Plist/AdHocExportOptionsPlist.plist" 120 | __BUILD_METHOD_NAME="AdHoc" 121 | elif [[ $__PACK_TYPE -eq 2 ]]; then 122 | __EXPORT_OPTIONS_PLIST_PATH="./AutoPacking/Plist/AppStoreExportOptionsPlist.plist" 123 | __BUILD_METHOD_NAME="AppStore" 124 | elif [[ $__PACK_TYPE -eq 3 ]]; then 125 | __EXPORT_OPTIONS_PLIST_PATH="./AutoPacking/Plist/EnterpriseExportOptionsPlist.plist" 126 | __BUILD_METHOD_NAME="Enterprise" 127 | elif [[ $__PACK_TYPE -eq 4 ]]; then 128 | __EXPORT_OPTIONS_PLIST_PATH="./AutoPacking/Plist/DevelopmentExportOptionsPlist.plist" 129 | __BUILD_METHOD_NAME="Development" 130 | fi 131 | 132 | # 5.上传安装包到指定位置 133 | __UPLOAD_IPA_OPTIONS=("1.None" "2.Pgyer" "3.Fir" "4.Pgyer") 134 | READ_USER_INPUT "请选择ipa上传位置: " "${__UPLOAD_IPA_OPTIONS[*]}" ${#__UPLOAD_IPA_OPTIONS[*]} 135 | 136 | __UPLOAD_IPA_OPTION=$? 137 | 138 | # 6. 成功出包后是否自动打开文件夹 139 | __IS_AUTO_OPENT_FILE_OPTIONS=("1.是" "2.否") 140 | READ_USER_INPUT "是否自动打开文件夹: " "${__IS_AUTO_OPENT_FILE_OPTIONS[*]}" ${#__IS_AUTO_OPENT_FILE_OPTIONS[*]} 141 | 142 | __IS_AUTO_OPENT_FILE_OPTION=$? 143 | 144 | # 7. 是否立即开始打包 145 | __IS_NOW_STAR_PACKINGS=("1.是" "2.否") 146 | READ_USER_INPUT "是否立即开始打包: " "${__IS_NOW_STAR_PACKINGS[*]}" ${#__IS_NOW_STAR_PACKINGS[*]} 147 | 148 | __IS_NOW_STAR_PACKING=$? 149 | if [[ $__IS_NOW_STAR_PACKING -eq 1 ]]; then 150 | printMessage "已开始打包" 151 | elif [[ $__IS_NOW_STAR_PACKING -eq 2 ]]; then 152 | printMessage "您退出了自动打包脚本" 153 | exit 1 154 | fi 155 | 156 | # ===============================自动打包部分============================= 157 | # 打包计时 158 | __CONSUME_TIME=0 159 | # 回退到工程目录 160 | cd ../ 161 | __PROGECT_PATH=`pwd` 162 | 163 | # 获取项目名称 164 | __PROJECT_NAME=`find . -name *.xcodeproj | awk -F "[/.]" '{print $(NF-1)}'` 165 | 166 | # 已经指定Target的Info.plist文件路径 【配置Info.plist的名称】 167 | __CURRENT_INFO_PLIST_NAME="Info.plist" 168 | # 获取 Info.plist 路径 【配置Info.plist的路径】 169 | __CURRENT_INFO_PLIST_PATH="${__PROJECT_NAME}/${__CURRENT_INFO_PLIST_NAME}" 170 | # 获取版本号 171 | __BUNDLE_VERSION=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${__CURRENT_INFO_PLIST_PATH}` 172 | # 获取编译版本号 173 | __BUNDLE_BUILD_VERSION=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" ${__CURRENT_INFO_PLIST_PATH}` 174 | 175 | # Xcode11 以上版本 176 | if [[ $XCODE_BUILD_VERSION =~ "Xcode 11" || $XCODE_BUILD_VERSION =~ "Xcode11" ]]; then 177 | __BUNDLE_VERSION_TAG="MARKETING_VERSION" 178 | __BUNDLE_BUILD_VERSION_TAG="CURRENT_PROJECT_VERSION" 179 | __PROJECT_ROOT_PATH=`find . -name *.xcodeproj` 180 | __PBXPROJ_PATH="$__PROJECT_ROOT_PATH/project.pbxproj" 181 | __BUNDLE_VERSION_11=$(grep "${__BUNDLE_VERSION_TAG}" $__PBXPROJ_PATH | head -1 | awk -F '=' '{print $2}' | awk -F ';' '{print $1}' | sed s/[[:space:]]//g) 182 | __BUNDLE_BUILD_VERSION_11=$(grep "${__BUNDLE_BUILD_VERSION_TAG}" $__PBXPROJ_PATH | head -1 | awk -F '=' '{print $2}' | awk -F ';' '{print $1}' | sed s/[[:space:]]//g) 183 | 184 | if [[ -n "$__BUNDLE_VERSION_11" ]]; then 185 | __BUNDLE_VERSION="$__BUNDLE_VERSION_11"; 186 | fi 187 | 188 | if [[ -n "$__BUNDLE_BUILD_VERSION_11" ]]; then 189 | __BUNDLE_BUILD_VERSION="$__BUNDLE_BUILD_VERSION_11"; 190 | fi 191 | fi 192 | 193 | # 编译生成文件目录 194 | __EXPORT_PATH="./build" 195 | 196 | # 指定输出文件目录不存在则创建 197 | if test -d "${__EXPORT_PATH}" ; then 198 | rm -rf ${__EXPORT_PATH} 199 | else 200 | mkdir -pv ${__EXPORT_PATH} 201 | fi 202 | 203 | # 归档文件路径 204 | __EXPORT_ARCHIVE_PATH="${__EXPORT_PATH}/${__SCHEME_NAME}.xcarchive" 205 | # ipa 导出路径 206 | __EXPORT_IPA_PATH="${__EXPORT_PATH}" 207 | # 获取时间 如:201706011145 208 | __CURRENT_DATE="$(date +%Y%m%d_%H%M%S)" 209 | # ipa 名字 210 | __IPA_NAME="${__SCHEME_NAME}_V${__BUNDLE_BUILD_VERSION}_${__CURRENT_DATE}" 211 | 212 | function print_packing_message() { 213 | 214 | printMessage "打包类型 = ${__BUILD_CONFIGURATION}" 215 | printMessage "打包导出Plist路径 = ${__EXPORT_OPTIONS_PLIST_PATH}" 216 | printMessage "工程目录 = ${__PROGECT_PATH}" 217 | printMessage "当前Info.plist路径 = ${__CURRENT_INFO_PLIST_PATH}" 218 | } 219 | 220 | print_packing_message 221 | 222 | if [[ $__IS_WORKSPACE_OPTION -eq 1 ]]; then 223 | # pod install --verbose --no-repo-update 224 | 225 | if [[ ${__BUILD_CONFIGURATION} == "Debug" ]]; then 226 | # step 1. Clean 227 | xcodebuild clean -workspace ${__PROJECT_NAME}.xcworkspace \ 228 | -scheme ${__SCHEME_NAME} \ 229 | -configuration ${__BUILD_CONFIGURATION} 230 | 231 | # step 2. Archive 232 | xcodebuild archive -workspace ${__PROJECT_NAME}.xcworkspace \ 233 | -scheme ${__SCHEME_NAME} \ 234 | -configuration ${__BUILD_CONFIGURATION} \ 235 | -archivePath ${__EXPORT_ARCHIVE_PATH} \ 236 | CFBundleVersion=${__BUNDLE_BUILD_VERSION} \ 237 | -destination generic/platform=ios \ 238 | #CODE_SIGN_IDENTITY="${__CODE_SIGN_DEVELOPMENT}" 239 | 240 | elif [[ ${__BUILD_CONFIGURATION} == "Release" ]]; then 241 | # step 1. Clean 242 | xcodebuild clean -workspace ${__PROJECT_NAME}.xcworkspace \ 243 | -scheme ${__SCHEME_NAME} \ 244 | -configuration ${__BUILD_CONFIGURATION} 245 | 246 | # step 2. Archive 247 | xcodebuild archive -workspace ${__PROJECT_NAME}.xcworkspace \ 248 | -scheme ${__SCHEME_NAME} \ 249 | -configuration ${__BUILD_CONFIGURATION} \ 250 | -archivePath ${__EXPORT_ARCHIVE_PATH} \ 251 | CFBundleVersion=${__BUNDLE_BUILD_VERSION} \ 252 | -destination generic/platform=ios \ 253 | #CODE_SIGN_IDENTITY="${__CODE_SIGN_DISTRIBUTION}" 254 | fi 255 | 256 | else 257 | 258 | if [[ ${__BUILD_CONFIGURATION} == "Debug" ]] ; then 259 | # step 1. Clean 260 | xcodebuild clean -project ${__PROJECT_NAME}.xcodeproj \ 261 | -scheme ${__SCHEME_NAME} \ 262 | -configuration ${__BUILD_CONFIGURATION} \ 263 | #-alltargets 264 | 265 | # step 2. Archive 266 | xcodebuild archive -project ${__PROJECT_NAME}.xcodeproj \ 267 | -scheme ${__SCHEME_NAME} \ 268 | -configuration ${__BUILD_CONFIGURATION} \ 269 | -archivePath ${__EXPORT_ARCHIVE_PATH} \ 270 | CFBundleVersion=${__BUNDLE_BUILD_VERSION} \ 271 | -destination generic/platform=ios \ 272 | #CODE_SIGN_IDENTITY="${__CODE_SIGN_DEVELOPMENT}" 273 | 274 | elif [[ ${__BUILD_CONFIGURATION} == "Release" ]]; then 275 | # step 1. Clean 276 | xcodebuild clean -project ${__PROJECT_NAME}.xcodeproj \ 277 | -scheme ${__SCHEME_NAME} \ 278 | -configuration ${__BUILD_CONFIGURATION} \ 279 | -alltargets 280 | # step 2. Archive 281 | xcodebuild archive -project ${__PROJECT_NAME}.xcodeproj \ 282 | -scheme ${__SCHEME_NAME} \ 283 | -configuration ${__BUILD_CONFIGURATION} \ 284 | -archivePath ${__EXPORT_ARCHIVE_PATH} \ 285 | CFBundleVersion=${__BUNDLE_BUILD_VERSION} \ 286 | -destination generic/platform=ios \ 287 | #CODE_SIGN_IDENTITY="${__CODE_SIGN_DISTRIBUTION}" 288 | fi 289 | fi 290 | 291 | # 检查是否构建成功 292 | # xcarchive 实际是一个文件夹不是一个文件所以使用 -d 判断 293 | if test -d "${__EXPORT_ARCHIVE_PATH}" ; then 294 | printMessage "项目构建成功 🚀 🚀 🚀" 295 | else 296 | printMessage "项目构建失败 😢 😢 😢" 297 | exit 1 298 | fi 299 | 300 | printMessage "开始导出ipa文件" 301 | 302 | xcodebuild -exportArchive -archivePath ${__EXPORT_ARCHIVE_PATH} \ 303 | -exportPath ${__EXPORT_IPA_PATH} \ 304 | -destination generic/platform=ios \ 305 | -exportOptionsPlist ${__EXPORT_OPTIONS_PLIST_PATH} \ 306 | -allowProvisioningUpdates 307 | 308 | # 修改ipa文件名称 309 | mv ${__EXPORT_IPA_PATH}/${__SCHEME_NAME}.ipa ${__EXPORT_IPA_PATH}/${__IPA_NAME}.ipa 310 | 311 | # 检查文件是否存在 312 | if test -f "${__EXPORT_IPA_PATH}/${__IPA_NAME}.ipa" ; then 313 | 314 | printMessage "导出 ${__IPA_NAME}.ipa 包成功 🎉 🎉 🎉" 315 | 316 | if [[ $__UPLOAD_IPA_OPTION -eq 1 ]]; then 317 | printMessage "您选择了不上传到内测网站" 318 | elif [[ $__UPLOAD_IPA_OPTION -eq 2 ]]; then 319 | 320 | curl -F "file=@${__EXPORT_IPA_PATH}/${__IPA_NAME}.ipa" \ 321 | -F "uKey=$__PGYER_U_KEY" \ 322 | -F "_api_key=$__PGYER_API_KEY" \ 323 | "http://www.pgyer.com/apiv1/app/upload" 324 | 325 | printMessage "上传 ${__IPA_NAME}.ipa 包 到 pgyer 成功 🎉 🎉 🎉" 326 | 327 | elif [[ $__UPLOAD_IPA_OPTION -eq 3 ]]; then 328 | 329 | fir login -T ${__FIR_API_TOKEN} 330 | fir publish "${__EXPORT_IPA_PATH}/${__IPA_NAME}.ipa" 331 | 332 | printMessage "上传 ${__IPA_NAME}.ipa 包 到 fir 成功 🎉 🎉 🎉" 333 | 334 | elif [[ $__UPLOAD_IPA_OPTION -eq 4 ]]; then 335 | 336 | fir login -T ${__FIR_API_TOKEN} 337 | fir publish "${__EXPORT_IPA_PATH}/${__IPA_NAME}.ipa" 338 | 339 | printMessage "上传 ${__IPA_NAME}.ipa 包 到 fir 成功 🎉 🎉 🎉" 340 | 341 | curl -F "file=@{${__EXPORT_IPA_PATH}/${__IPA_NAME}.ipa}" \ 342 | -F "uKey=$__PGYER_U_KEY" \ 343 | -F "_api_key=$__PGYER_API_KEY" \ 344 | "http://www.pgyer.com/apiv1/app/upload" 345 | 346 | printMessage "上传 ${__IPA_NAME}.ipa 包 到 pgyer 成功 🎉 🎉 🎉" 347 | 348 | fi 349 | 350 | # 自动打开文件夹 351 | if [[ $__IS_AUTO_OPENT_FILE_OPTION -eq 1 ]]; then 352 | open ${__EXPORT_IPA_PATH} 353 | fi 354 | 355 | else 356 | printMessage "导出 ${__IPA_NAME}.ipa 包失败 😢 😢 😢" 357 | exit 1 358 | fi 359 | 360 | # 输出打包总用时 361 | printMessage "使用YJShell脚本打包总耗时: ${SECONDS}s" 362 | -------------------------------------------------------------------------------- /AutoPackingDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 000D13FF215BA8D50030E5C5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 000D13FE215BA8D50030E5C5 /* AppDelegate.m */; }; 11 | 000D1402215BA8D50030E5C5 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 000D1401215BA8D50030E5C5 /* ViewController.m */; }; 12 | 000D1405215BA8D50030E5C5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 000D1403215BA8D50030E5C5 /* Main.storyboard */; }; 13 | 000D1407215BA8D80030E5C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 000D1406215BA8D80030E5C5 /* Assets.xcassets */; }; 14 | 000D140A215BA8D80030E5C5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 000D1408215BA8D80030E5C5 /* LaunchScreen.storyboard */; }; 15 | 000D140D215BA8D80030E5C5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 000D140C215BA8D80030E5C5 /* main.m */; }; 16 | 841330745F8CC691858B9356 /* libPods-AutoPackingDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B62225D67E7620BFBCF40D6 /* libPods-AutoPackingDemo.a */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 000D13FA215BA8D50030E5C5 /* AutoPackingDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoPackingDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | 000D13FD215BA8D50030E5C5 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 22 | 000D13FE215BA8D50030E5C5 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 23 | 000D1400215BA8D50030E5C5 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 24 | 000D1401215BA8D50030E5C5 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 25 | 000D1404215BA8D50030E5C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 000D1406215BA8D80030E5C5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 27 | 000D1409215BA8D80030E5C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 28 | 000D140B215BA8D80030E5C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | 000D140C215BA8D80030E5C5 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | 3B62225D67E7620BFBCF40D6 /* libPods-AutoPackingDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AutoPackingDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | B8A768AE165457278977A507 /* Pods-AutoPackingDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AutoPackingDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo.debug.xcconfig"; sourceTree = ""; }; 32 | C56DA131C5EABA96B58E47FD /* Pods-AutoPackingDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AutoPackingDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo.release.xcconfig"; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | 000D13F7215BA8D50030E5C5 /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | 841330745F8CC691858B9356 /* libPods-AutoPackingDemo.a in Frameworks */, 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXFrameworksBuildPhase section */ 45 | 46 | /* Begin PBXGroup section */ 47 | 000D13F1215BA8D50030E5C5 = { 48 | isa = PBXGroup; 49 | children = ( 50 | 000D13FC215BA8D50030E5C5 /* AutoPackingDemo */, 51 | 000D13FB215BA8D50030E5C5 /* Products */, 52 | 80AB48C4AC1C326C3102A497 /* Pods */, 53 | F9705CEC8EE209E0BC648A3F /* Frameworks */, 54 | ); 55 | sourceTree = ""; 56 | }; 57 | 000D13FB215BA8D50030E5C5 /* Products */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | 000D13FA215BA8D50030E5C5 /* AutoPackingDemo.app */, 61 | ); 62 | name = Products; 63 | sourceTree = ""; 64 | }; 65 | 000D13FC215BA8D50030E5C5 /* AutoPackingDemo */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 000D13FD215BA8D50030E5C5 /* AppDelegate.h */, 69 | 000D13FE215BA8D50030E5C5 /* AppDelegate.m */, 70 | 000D1400215BA8D50030E5C5 /* ViewController.h */, 71 | 000D1401215BA8D50030E5C5 /* ViewController.m */, 72 | 000D1403215BA8D50030E5C5 /* Main.storyboard */, 73 | 000D1406215BA8D80030E5C5 /* Assets.xcassets */, 74 | 000D1408215BA8D80030E5C5 /* LaunchScreen.storyboard */, 75 | 000D140B215BA8D80030E5C5 /* Info.plist */, 76 | 000D140C215BA8D80030E5C5 /* main.m */, 77 | ); 78 | path = AutoPackingDemo; 79 | sourceTree = ""; 80 | }; 81 | 80AB48C4AC1C326C3102A497 /* Pods */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | B8A768AE165457278977A507 /* Pods-AutoPackingDemo.debug.xcconfig */, 85 | C56DA131C5EABA96B58E47FD /* Pods-AutoPackingDemo.release.xcconfig */, 86 | ); 87 | name = Pods; 88 | sourceTree = ""; 89 | }; 90 | F9705CEC8EE209E0BC648A3F /* Frameworks */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 3B62225D67E7620BFBCF40D6 /* libPods-AutoPackingDemo.a */, 94 | ); 95 | name = Frameworks; 96 | sourceTree = ""; 97 | }; 98 | /* End PBXGroup section */ 99 | 100 | /* Begin PBXNativeTarget section */ 101 | 000D13F9215BA8D50030E5C5 /* AutoPackingDemo */ = { 102 | isa = PBXNativeTarget; 103 | buildConfigurationList = 000D1410215BA8D80030E5C5 /* Build configuration list for PBXNativeTarget "AutoPackingDemo" */; 104 | buildPhases = ( 105 | 3863DA440028C92C0E777849 /* [CP] Check Pods Manifest.lock */, 106 | 000D13F6215BA8D50030E5C5 /* Sources */, 107 | 000D13F7215BA8D50030E5C5 /* Frameworks */, 108 | 000D13F8215BA8D50030E5C5 /* Resources */, 109 | 5FE27071F57E1AD0629F2671 /* [CP] Copy Pods Resources */, 110 | ); 111 | buildRules = ( 112 | ); 113 | dependencies = ( 114 | ); 115 | name = AutoPackingDemo; 116 | productName = AutoPackingDemo; 117 | productReference = 000D13FA215BA8D50030E5C5 /* AutoPackingDemo.app */; 118 | productType = "com.apple.product-type.application"; 119 | }; 120 | /* End PBXNativeTarget section */ 121 | 122 | /* Begin PBXProject section */ 123 | 000D13F2215BA8D50030E5C5 /* Project object */ = { 124 | isa = PBXProject; 125 | attributes = { 126 | LastUpgradeCheck = 0940; 127 | ORGANIZATIONNAME = com.hm; 128 | TargetAttributes = { 129 | 000D13F9215BA8D50030E5C5 = { 130 | CreatedOnToolsVersion = 9.4.1; 131 | }; 132 | }; 133 | }; 134 | buildConfigurationList = 000D13F5215BA8D50030E5C5 /* Build configuration list for PBXProject "AutoPackingDemo" */; 135 | compatibilityVersion = "Xcode 9.3"; 136 | developmentRegion = en; 137 | hasScannedForEncodings = 0; 138 | knownRegions = ( 139 | en, 140 | Base, 141 | ); 142 | mainGroup = 000D13F1215BA8D50030E5C5; 143 | productRefGroup = 000D13FB215BA8D50030E5C5 /* Products */; 144 | projectDirPath = ""; 145 | projectRoot = ""; 146 | targets = ( 147 | 000D13F9215BA8D50030E5C5 /* AutoPackingDemo */, 148 | ); 149 | }; 150 | /* End PBXProject section */ 151 | 152 | /* Begin PBXResourcesBuildPhase section */ 153 | 000D13F8215BA8D50030E5C5 /* Resources */ = { 154 | isa = PBXResourcesBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | 000D140A215BA8D80030E5C5 /* LaunchScreen.storyboard in Resources */, 158 | 000D1407215BA8D80030E5C5 /* Assets.xcassets in Resources */, 159 | 000D1405215BA8D50030E5C5 /* Main.storyboard in Resources */, 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXResourcesBuildPhase section */ 164 | 165 | /* Begin PBXShellScriptBuildPhase section */ 166 | 3863DA440028C92C0E777849 /* [CP] Check Pods Manifest.lock */ = { 167 | isa = PBXShellScriptBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | ); 171 | inputPaths = ( 172 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 173 | "${PODS_ROOT}/Manifest.lock", 174 | ); 175 | name = "[CP] Check Pods Manifest.lock"; 176 | outputPaths = ( 177 | "$(DERIVED_FILE_DIR)/Pods-AutoPackingDemo-checkManifestLockResult.txt", 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | shellPath = /bin/sh; 181 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 182 | showEnvVarsInLog = 0; 183 | }; 184 | 5FE27071F57E1AD0629F2671 /* [CP] Copy Pods Resources */ = { 185 | isa = PBXShellScriptBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | ); 189 | inputPaths = ( 190 | "${SRCROOT}/Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo-resources.sh", 191 | "${PODS_ROOT}/YJBannerView/YJBannerViewDemo/YJBannerView/Resource/YJBannerView.bundle", 192 | ); 193 | name = "[CP] Copy Pods Resources"; 194 | outputPaths = ( 195 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/YJBannerView.bundle", 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | shellPath = /bin/sh; 199 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo-resources.sh\"\n"; 200 | showEnvVarsInLog = 0; 201 | }; 202 | /* End PBXShellScriptBuildPhase section */ 203 | 204 | /* Begin PBXSourcesBuildPhase section */ 205 | 000D13F6215BA8D50030E5C5 /* Sources */ = { 206 | isa = PBXSourcesBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | 000D1402215BA8D50030E5C5 /* ViewController.m in Sources */, 210 | 000D140D215BA8D80030E5C5 /* main.m in Sources */, 211 | 000D13FF215BA8D50030E5C5 /* AppDelegate.m in Sources */, 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | }; 215 | /* End PBXSourcesBuildPhase section */ 216 | 217 | /* Begin PBXVariantGroup section */ 218 | 000D1403215BA8D50030E5C5 /* Main.storyboard */ = { 219 | isa = PBXVariantGroup; 220 | children = ( 221 | 000D1404215BA8D50030E5C5 /* Base */, 222 | ); 223 | name = Main.storyboard; 224 | sourceTree = ""; 225 | }; 226 | 000D1408215BA8D80030E5C5 /* LaunchScreen.storyboard */ = { 227 | isa = PBXVariantGroup; 228 | children = ( 229 | 000D1409215BA8D80030E5C5 /* Base */, 230 | ); 231 | name = LaunchScreen.storyboard; 232 | sourceTree = ""; 233 | }; 234 | /* End PBXVariantGroup section */ 235 | 236 | /* Begin XCBuildConfiguration section */ 237 | 000D140E215BA8D80030E5C5 /* Debug */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | ALWAYS_SEARCH_USER_PATHS = NO; 241 | CLANG_ANALYZER_NONNULL = YES; 242 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_MODULES = YES; 246 | CLANG_ENABLE_OBJC_ARC = YES; 247 | CLANG_ENABLE_OBJC_WEAK = YES; 248 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 249 | CLANG_WARN_BOOL_CONVERSION = YES; 250 | CLANG_WARN_COMMA = YES; 251 | CLANG_WARN_CONSTANT_CONVERSION = YES; 252 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 253 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 254 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 255 | CLANG_WARN_EMPTY_BODY = YES; 256 | CLANG_WARN_ENUM_CONVERSION = YES; 257 | CLANG_WARN_INFINITE_RECURSION = YES; 258 | CLANG_WARN_INT_CONVERSION = YES; 259 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 260 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 261 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 262 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 263 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 264 | CLANG_WARN_STRICT_PROTOTYPES = YES; 265 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 266 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 267 | CLANG_WARN_UNREACHABLE_CODE = YES; 268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 269 | CODE_SIGN_IDENTITY = "iPhone Developer"; 270 | COPY_PHASE_STRIP = NO; 271 | DEBUG_INFORMATION_FORMAT = dwarf; 272 | ENABLE_STRICT_OBJC_MSGSEND = YES; 273 | ENABLE_TESTABILITY = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu11; 275 | GCC_DYNAMIC_NO_PIC = NO; 276 | GCC_NO_COMMON_BLOCKS = YES; 277 | GCC_OPTIMIZATION_LEVEL = 0; 278 | GCC_PREPROCESSOR_DEFINITIONS = ( 279 | "DEBUG=1", 280 | "$(inherited)", 281 | ); 282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 284 | GCC_WARN_UNDECLARED_SELECTOR = YES; 285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 286 | GCC_WARN_UNUSED_FUNCTION = YES; 287 | GCC_WARN_UNUSED_VARIABLE = YES; 288 | IPHONEOS_DEPLOYMENT_TARGET = 11.4; 289 | MTL_ENABLE_DEBUG_INFO = YES; 290 | ONLY_ACTIVE_ARCH = YES; 291 | SDKROOT = iphoneos; 292 | }; 293 | name = Debug; 294 | }; 295 | 000D140F215BA8D80030E5C5 /* Release */ = { 296 | isa = XCBuildConfiguration; 297 | buildSettings = { 298 | ALWAYS_SEARCH_USER_PATHS = NO; 299 | CLANG_ANALYZER_NONNULL = YES; 300 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 301 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 302 | CLANG_CXX_LIBRARY = "libc++"; 303 | CLANG_ENABLE_MODULES = YES; 304 | CLANG_ENABLE_OBJC_ARC = YES; 305 | CLANG_ENABLE_OBJC_WEAK = YES; 306 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 307 | CLANG_WARN_BOOL_CONVERSION = YES; 308 | CLANG_WARN_COMMA = YES; 309 | CLANG_WARN_CONSTANT_CONVERSION = YES; 310 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 311 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 312 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 313 | CLANG_WARN_EMPTY_BODY = YES; 314 | CLANG_WARN_ENUM_CONVERSION = YES; 315 | CLANG_WARN_INFINITE_RECURSION = YES; 316 | CLANG_WARN_INT_CONVERSION = YES; 317 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 318 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 319 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 320 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 321 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 322 | CLANG_WARN_STRICT_PROTOTYPES = YES; 323 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 324 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 325 | CLANG_WARN_UNREACHABLE_CODE = YES; 326 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 327 | CODE_SIGN_IDENTITY = "iPhone Developer"; 328 | COPY_PHASE_STRIP = NO; 329 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 330 | ENABLE_NS_ASSERTIONS = NO; 331 | ENABLE_STRICT_OBJC_MSGSEND = YES; 332 | GCC_C_LANGUAGE_STANDARD = gnu11; 333 | GCC_NO_COMMON_BLOCKS = YES; 334 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 335 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 336 | GCC_WARN_UNDECLARED_SELECTOR = YES; 337 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 338 | GCC_WARN_UNUSED_FUNCTION = YES; 339 | GCC_WARN_UNUSED_VARIABLE = YES; 340 | IPHONEOS_DEPLOYMENT_TARGET = 11.4; 341 | MTL_ENABLE_DEBUG_INFO = NO; 342 | SDKROOT = iphoneos; 343 | VALIDATE_PRODUCT = YES; 344 | }; 345 | name = Release; 346 | }; 347 | 000D1411215BA8D80030E5C5 /* Debug */ = { 348 | isa = XCBuildConfiguration; 349 | baseConfigurationReference = B8A768AE165457278977A507 /* Pods-AutoPackingDemo.debug.xcconfig */; 350 | buildSettings = { 351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 352 | CODE_SIGN_STYLE = Automatic; 353 | DEVELOPMENT_TEAM = ""; 354 | INFOPLIST_FILE = AutoPackingDemo/Info.plist; 355 | LD_RUNPATH_SEARCH_PATHS = ( 356 | "$(inherited)", 357 | "@executable_path/Frameworks", 358 | ); 359 | PRODUCT_BUNDLE_IDENTIFIER = "--bundle-id"; 360 | PRODUCT_NAME = "$(TARGET_NAME)"; 361 | TARGETED_DEVICE_FAMILY = "1,2"; 362 | }; 363 | name = Debug; 364 | }; 365 | 000D1412215BA8D80030E5C5 /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | baseConfigurationReference = C56DA131C5EABA96B58E47FD /* Pods-AutoPackingDemo.release.xcconfig */; 368 | buildSettings = { 369 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 370 | CODE_SIGN_STYLE = Automatic; 371 | DEVELOPMENT_TEAM = ""; 372 | INFOPLIST_FILE = AutoPackingDemo/Info.plist; 373 | LD_RUNPATH_SEARCH_PATHS = ( 374 | "$(inherited)", 375 | "@executable_path/Frameworks", 376 | ); 377 | PRODUCT_BUNDLE_IDENTIFIER = "--bundle-id"; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | TARGETED_DEVICE_FAMILY = "1,2"; 380 | }; 381 | name = Release; 382 | }; 383 | /* End XCBuildConfiguration section */ 384 | 385 | /* Begin XCConfigurationList section */ 386 | 000D13F5215BA8D50030E5C5 /* Build configuration list for PBXProject "AutoPackingDemo" */ = { 387 | isa = XCConfigurationList; 388 | buildConfigurations = ( 389 | 000D140E215BA8D80030E5C5 /* Debug */, 390 | 000D140F215BA8D80030E5C5 /* Release */, 391 | ); 392 | defaultConfigurationIsVisible = 0; 393 | defaultConfigurationName = Release; 394 | }; 395 | 000D1410215BA8D80030E5C5 /* Build configuration list for PBXNativeTarget "AutoPackingDemo" */ = { 396 | isa = XCConfigurationList; 397 | buildConfigurations = ( 398 | 000D1411215BA8D80030E5C5 /* Debug */, 399 | 000D1412215BA8D80030E5C5 /* Release */, 400 | ); 401 | defaultConfigurationIsVisible = 0; 402 | defaultConfigurationName = Release; 403 | }; 404 | /* End XCConfigurationList section */ 405 | }; 406 | rootObject = 000D13F2215BA8D50030E5C5 /* Project object */; 407 | } 408 | -------------------------------------------------------------------------------- /AutoPackingDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AutoPackingDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AutoPackingDemo.xcodeproj/project.xcworkspace/xcuserdata/edz.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaye/AutoPacking-iOS/308024d23951079a316e7e18f7c14b79b97ee901/AutoPackingDemo.xcodeproj/project.xcworkspace/xcuserdata/edz.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /AutoPackingDemo.xcodeproj/xcuserdata/edz.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | AutoPackingDemo.xcscheme 8 | 9 | orderHint 10 | 3 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /AutoPackingDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AutoPackingDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AutoPackingDemo.xcworkspace/xcuserdata/edz.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaye/AutoPacking-iOS/308024d23951079a316e7e18f7c14b79b97ee901/AutoPackingDemo.xcworkspace/xcuserdata/edz.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /AutoPackingDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AutoPackingDemo 4 | // 5 | // Created by stackhou on 2016/4/21. 6 | // Copyright © 2016年 com.hm. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /AutoPackingDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AutoPackingDemo 4 | // 5 | // Created by stackhou on 2016/4/21. 6 | // Copyright © 2016年 com.hm. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | 21 | [self _initBugly]; 22 | 23 | return YES; 24 | } 25 | 26 | 27 | - (void)applicationWillResignActive:(UIApplication *)application { 28 | // 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. 29 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 30 | } 31 | 32 | 33 | - (void)applicationDidEnterBackground:(UIApplication *)application { 34 | // 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. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | 39 | - (void)applicationWillEnterForeground:(UIApplication *)application { 40 | // 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. 41 | } 42 | 43 | 44 | - (void)applicationDidBecomeActive:(UIApplication *)application { 45 | // 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. 46 | } 47 | 48 | 49 | - (void)applicationWillTerminate:(UIApplication *)application { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | #pragma mark - 初始化Bugly 54 | - (void)_initBugly { 55 | @try{ 56 | // 初始化SDK并设置属性 57 | BuglyConfig *bugluConfig = [[BuglyConfig alloc] init]; 58 | bugluConfig.channel = @"YJGithub"; 59 | bugluConfig.version = [NSString stringWithFormat:@"%@(%@)", [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"], [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"]]; 60 | bugluConfig.deviceIdentifier = @"11020101"; 61 | [Bugly startWithAppId:@"bef5c76b98" config:bugluConfig]; 62 | [Bugly setUserValue:@"20110101001" forKey:@"imeiAndIdfa"]; 63 | }@catch(NSException* e) { 64 | } 65 | } 66 | 67 | 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /AutoPackingDemo/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 | } -------------------------------------------------------------------------------- /AutoPackingDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /AutoPackingDemo/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 | -------------------------------------------------------------------------------- /AutoPackingDemo/Base.lproj/Main.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 | -------------------------------------------------------------------------------- /AutoPackingDemo/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 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /AutoPackingDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AutoPackingDemo 4 | // 5 | // Created by stackhou on 2016/4/21. 6 | // Copyright © 2016年 com.hm. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AutoPackingDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AutoPackingDemo 4 | // 5 | // Created by stackhou on 2016/4/21. 6 | // Copyright © 2016年 com.hm. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /AutoPackingDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AutoPackingDemo 4 | // 5 | // Created by stackhou on 2016/4/21. 6 | // Copyright © 2016年 com.hm. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Images/buildSucceed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaye/AutoPacking-iOS/308024d23951079a316e7e18f7c14b79b97ee901/Images/buildSucceed.png -------------------------------------------------------------------------------- /Images/plistConfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaye/AutoPacking-iOS/308024d23951079a316e7e18f7c14b79b97ee901/Images/plistConfig.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 houmanager 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 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'AutoPackingDemo' do 5 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks 6 | # use_frameworks! 7 | 8 | # Pods for AutoPackingDemo 9 | pod 'YJBannerView' 10 | pod 'ElegantTableView' 11 | pod 'Bugly' 12 | 13 | end 14 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Bugly (2.5.0) 3 | - ElegantTableView (0.0.3) 4 | - YJBannerView (2.4.0) 5 | 6 | DEPENDENCIES: 7 | - Bugly 8 | - ElegantTableView 9 | - YJBannerView 10 | 11 | SPEC REPOS: 12 | https://github.com/cocoapods/specs.git: 13 | - Bugly 14 | - ElegantTableView 15 | - YJBannerView 16 | 17 | SPEC CHECKSUMS: 18 | Bugly: 3ca9f255c01025582df26f9222893b383c7e4b4e 19 | ElegantTableView: 95e37428e31235a9851acdc6fd0cde24231e9737 20 | YJBannerView: 0c81b7bda592cd23b10ceae8f53c514dcd77e4c6 21 | 22 | PODFILE CHECKSUM: 45f445fe1a82226ca80c9d83d0972e129730d247 23 | 24 | COCOAPODS: 1.5.3 25 | -------------------------------------------------------------------------------- /Pods/Bugly/Bugly.framework/Bugly: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaye/AutoPacking-iOS/308024d23951079a316e7e18f7c14b79b97ee901/Pods/Bugly/Bugly.framework/Bugly -------------------------------------------------------------------------------- /Pods/Bugly/Bugly.framework/Headers/Bugly.h: -------------------------------------------------------------------------------- 1 | // 2 | // Bugly.h 3 | // 4 | // Version: 2.5(0) 5 | // 6 | // Copyright (c) 2017年 Tencent. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "BuglyConfig.h" 12 | #import "BuglyLog.h" 13 | 14 | BLY_START_NONNULL 15 | 16 | @interface Bugly : NSObject 17 | 18 | /** 19 | * 初始化Bugly,使用默认BuglyConfig 20 | * 21 | * @param appId 注册Bugly分配的应用唯一标识 22 | */ 23 | + (void)startWithAppId:(NSString * BLY_NULLABLE)appId; 24 | 25 | /** 26 | * 使用指定配置初始化Bugly 27 | * 28 | * @param appId 注册Bugly分配的应用唯一标识 29 | * @param config 传入配置的 BuglyConfig 30 | */ 31 | + (void)startWithAppId:(NSString * BLY_NULLABLE)appId 32 | config:(BuglyConfig * BLY_NULLABLE)config; 33 | 34 | /** 35 | * 使用指定配置初始化Bugly 36 | * 37 | * @param appId 注册Bugly分配的应用唯一标识 38 | * @param development 是否开发设备 39 | * @param config 传入配置的 BuglyConfig 40 | */ 41 | + (void)startWithAppId:(NSString * BLY_NULLABLE)appId 42 | developmentDevice:(BOOL)development 43 | config:(BuglyConfig * BLY_NULLABLE)config; 44 | 45 | /** 46 | * 设置用户标识 47 | * 48 | * @param userId 用户标识 49 | */ 50 | + (void)setUserIdentifier:(NSString *)userId; 51 | 52 | /** 53 | * 更新版本信息 54 | * 55 | * @param version 应用版本信息 56 | */ 57 | + (void)updateAppVersion:(NSString *)version; 58 | 59 | /** 60 | * 设置关键数据,随崩溃信息上报 61 | * 62 | * @param value KEY 63 | * @param key VALUE 64 | */ 65 | + (void)setUserValue:(NSString *)value 66 | forKey:(NSString *)key; 67 | 68 | /** 69 | * 获取关键数据 70 | * 71 | * @return 关键数据 72 | */ 73 | + (NSDictionary * BLY_NULLABLE)allUserValues; 74 | 75 | /** 76 | * 设置标签 77 | * 78 | * @param tag 标签ID,可在网站生成 79 | */ 80 | + (void)setTag:(NSUInteger)tag; 81 | 82 | /** 83 | * 获取当前设置标签 84 | * 85 | * @return 当前标签ID 86 | */ 87 | + (NSUInteger)currentTag; 88 | 89 | /** 90 | * 获取设备ID 91 | * 92 | * @return 设备ID 93 | */ 94 | + (NSString *)buglyDeviceId; 95 | 96 | /** 97 | * 上报自定义Objective-C异常 98 | * 99 | * @param exception 异常信息 100 | */ 101 | + (void)reportException:(NSException *)exception; 102 | 103 | /** 104 | * 上报错误 105 | * 106 | * @param error 错误信息 107 | */ 108 | + (void)reportError:(NSError *)error; 109 | 110 | /** 111 | * @brief 上报自定义错误 112 | * 113 | * @param category 类型(Cocoa=3,CSharp=4,JS=5,Lua=6) 114 | * @param aName 名称 115 | * @param aReason 错误原因 116 | * @param aStackArray 堆栈 117 | * @param info 附加数据 118 | * @param terminate 上报后是否退出应用进程 119 | */ 120 | + (void)reportExceptionWithCategory:(NSUInteger)category 121 | name:(NSString *)aName 122 | reason:(NSString *)aReason 123 | callStack:(NSArray *)aStackArray 124 | extraInfo:(NSDictionary *)info 125 | terminateApp:(BOOL)terminate; 126 | 127 | /** 128 | * SDK 版本信息 129 | * 130 | * @return SDK版本号 131 | */ 132 | + (NSString *)sdkVersion; 133 | 134 | /** 135 | * App 是否发生了连续闪退 136 | * 如果 启动SDK 且 5秒内 闪退,且次数达到 3次 则判定为连续闪退 137 | * 138 | * @return 是否连续闪退 139 | */ 140 | + (BOOL)isAppCrashedOnStartUpExceedTheLimit; 141 | 142 | BLY_END_NONNULL 143 | 144 | @end 145 | -------------------------------------------------------------------------------- /Pods/Bugly/Bugly.framework/Headers/BuglyConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // BuglyConfig.h 3 | // Bugly 4 | // 5 | // Copyright (c) 2016年 Tencent. All rights reserved. 6 | // 7 | 8 | #pragma once 9 | 10 | #define BLY_UNAVAILABLE(x) __attribute__((unavailable(x))) 11 | 12 | #if __has_feature(nullability) 13 | #define BLY_NONNULL __nonnull 14 | #define BLY_NULLABLE __nullable 15 | #define BLY_START_NONNULL _Pragma("clang assume_nonnull begin") 16 | #define BLY_END_NONNULL _Pragma("clang assume_nonnull end") 17 | #else 18 | #define BLY_NONNULL 19 | #define BLY_NULLABLE 20 | #define BLY_START_NONNULL 21 | #define BLY_END_NONNULL 22 | #endif 23 | 24 | #import 25 | 26 | #import "BuglyLog.h" 27 | 28 | BLY_START_NONNULL 29 | 30 | @protocol BuglyDelegate 31 | 32 | @optional 33 | /** 34 | * 发生异常时回调 35 | * 36 | * @param exception 异常信息 37 | * 38 | * @return 返回需上报记录,随异常上报一起上报 39 | */ 40 | - (NSString * BLY_NULLABLE)attachmentForException:(NSException * BLY_NULLABLE)exception; 41 | 42 | @end 43 | 44 | @interface BuglyConfig : NSObject 45 | 46 | /** 47 | * SDK Debug信息开关, 默认关闭 48 | */ 49 | @property (nonatomic, assign) BOOL debugMode; 50 | 51 | /** 52 | * 设置自定义渠道标识 53 | */ 54 | @property (nonatomic, copy) NSString *channel; 55 | 56 | /** 57 | * 设置自定义版本号 58 | */ 59 | @property (nonatomic, copy) NSString *version; 60 | 61 | /** 62 | * 设置自定义设备唯一标识 63 | */ 64 | @property (nonatomic, copy) NSString *deviceIdentifier; 65 | 66 | /** 67 | * 卡顿监控开关,默认关闭 68 | */ 69 | @property (nonatomic) BOOL blockMonitorEnable; 70 | 71 | /** 72 | * 卡顿监控判断间隔,单位为秒 73 | */ 74 | @property (nonatomic) NSTimeInterval blockMonitorTimeout; 75 | 76 | /** 77 | * 设置 App Groups Id (如有使用 Bugly iOS Extension SDK,请设置该值) 78 | */ 79 | @property (nonatomic, copy) NSString *applicationGroupIdentifier; 80 | 81 | /** 82 | * 进程内还原开关,默认开启 83 | */ 84 | @property (nonatomic) BOOL symbolicateInProcessEnable; 85 | 86 | /** 87 | * 非正常退出事件记录开关,默认关闭 88 | */ 89 | @property (nonatomic) BOOL unexpectedTerminatingDetectionEnable; 90 | 91 | /** 92 | * 页面信息记录开关,默认开启 93 | */ 94 | @property (nonatomic) BOOL viewControllerTrackingEnable; 95 | 96 | /** 97 | * Bugly Delegate 98 | */ 99 | @property (nonatomic, assign) id delegate; 100 | 101 | /** 102 | * 控制自定义日志上报,默认值为BuglyLogLevelSilent,即关闭日志记录功能。 103 | * 如果设置为BuglyLogLevelWarn,则在崩溃时会上报Warn、Error接口打印的日志 104 | */ 105 | @property (nonatomic, assign) BuglyLogLevel reportLogLevel; 106 | 107 | /** 108 | * 崩溃数据过滤器,如果崩溃堆栈的模块名包含过滤器中设置的关键字,则崩溃数据不会进行上报 109 | * 例如,过滤崩溃堆栈中包含搜狗输入法的数据,可以添加过滤器关键字SogouInputIPhone.dylib等 110 | */ 111 | @property (nonatomic, copy) NSArray *excludeModuleFilter; 112 | 113 | /** 114 | * 控制台日志上报开关,默认开启 115 | */ 116 | @property (nonatomic, assign) BOOL consolelogEnable; 117 | 118 | /** 119 | * 崩溃退出超时,如果监听到崩溃后,App一直没有退出,则到达超时时间后会自动abort进程退出 120 | * 默认值 5s, 单位 秒 121 | * 当赋值为0时,则不会自动abort进程退出 122 | */ 123 | @property (nonatomic, assign) NSUInteger crashAbortTimeout; 124 | 125 | @end 126 | BLY_END_NONNULL 127 | -------------------------------------------------------------------------------- /Pods/Bugly/Bugly.framework/Headers/BuglyLog.h: -------------------------------------------------------------------------------- 1 | // 2 | // BuglyLog.h 3 | // Bugly 4 | // 5 | // Copyright (c) 2017年 Tencent. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | // Log level for Bugly Log 11 | typedef NS_ENUM(NSUInteger, BuglyLogLevel) { 12 | BuglyLogLevelSilent = 0, 13 | BuglyLogLevelError = 1, 14 | BuglyLogLevelWarn = 2, 15 | BuglyLogLevelInfo = 3, 16 | BuglyLogLevelDebug = 4, 17 | BuglyLogLevelVerbose = 5, 18 | }; 19 | #pragma mark - 20 | 21 | OBJC_EXTERN void BLYLog(BuglyLogLevel level, NSString *format, ...) NS_FORMAT_FUNCTION(2, 3); 22 | 23 | OBJC_EXTERN void BLYLogv(BuglyLogLevel level, NSString *format, va_list args) NS_FORMAT_FUNCTION(2, 0); 24 | 25 | #pragma mark - 26 | #define BUGLY_LOG_MACRO(_level, fmt, ...) [BuglyLog level:_level tag:nil log:fmt, ##__VA_ARGS__] 27 | 28 | #define BLYLogError(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelError, fmt, ##__VA_ARGS__) 29 | #define BLYLogWarn(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelWarn, fmt, ##__VA_ARGS__) 30 | #define BLYLogInfo(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelInfo, fmt, ##__VA_ARGS__) 31 | #define BLYLogDebug(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelDebug, fmt, ##__VA_ARGS__) 32 | #define BLYLogVerbose(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelVerbose, fmt, ##__VA_ARGS__) 33 | 34 | #pragma mark - Interface 35 | @interface BuglyLog : NSObject 36 | 37 | /** 38 | * @brief 初始化日志模块 39 | * 40 | * @param level 设置默认日志级别,默认BLYLogLevelSilent 41 | * 42 | * @param printConsole 是否打印到控制台,默认NO 43 | */ 44 | + (void)initLogger:(BuglyLogLevel) level consolePrint:(BOOL)printConsole; 45 | 46 | /** 47 | * @brief 打印BLYLogLevelInfo日志 48 | * 49 | * @param format 日志内容 总日志大小限制为:字符串长度30k,条数200 50 | */ 51 | + (void)log:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2); 52 | 53 | /** 54 | * @brief 打印日志 55 | * 56 | * @param level 日志级别 57 | * @param message 日志内容 总日志大小限制为:字符串长度30k,条数200 58 | */ 59 | + (void)level:(BuglyLogLevel) level logs:(NSString *)message; 60 | 61 | /** 62 | * @brief 打印日志 63 | * 64 | * @param level 日志级别 65 | * @param format 日志内容 总日志大小限制为:字符串长度30k,条数200 66 | */ 67 | + (void)level:(BuglyLogLevel) level log:(NSString *)format, ... NS_FORMAT_FUNCTION(2, 3); 68 | 69 | /** 70 | * @brief 打印日志 71 | * 72 | * @param level 日志级别 73 | * @param tag 日志模块分类 74 | * @param format 日志内容 总日志大小限制为:字符串长度30k,条数200 75 | */ 76 | + (void)level:(BuglyLogLevel) level tag:(NSString *) tag log:(NSString *)format, ... NS_FORMAT_FUNCTION(3, 4); 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Pods/Bugly/Bugly.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module Bugly { 2 | umbrella header "Bugly.h" 3 | 4 | export * 5 | module * { export * } 6 | 7 | link framework "Foundation" 8 | link framework "Security" 9 | link framework "SystemConfiguration" 10 | link "c++" 11 | link "z" 12 | } 13 | -------------------------------------------------------------------------------- /Pods/ElegantTableView/ElegantTableView/ElegantTableViewGenerator.h: -------------------------------------------------------------------------------- 1 | // 2 | // ElegantTableViewGenerator.h 3 | // ElegantTableViewDemo 4 | // 5 | // Created by YJHou on 2017/7/3. 6 | // Copyright © 2017年 houmanager. All rights reserved. 7 | // 优雅的 创建简单的 TableView 8 | 9 | /** 当前版本: 0.0.3 */ 10 | 11 | #import 12 | 13 | typedef void(^didSelectRowHandleBlock)(UITableView *tableView, NSIndexPath *indexPath); 14 | typedef void(^didScrollHandleBlock)(UIScrollView *tableView, CGPoint contentOffset); 15 | 16 | @interface ElegantTableViewGenerator : NSObject 17 | 18 | /** 单例 */ 19 | + (ElegantTableViewGenerator *)shareInstance; 20 | 21 | /** 创建tableView */ 22 | - (UITableView *)createWithFrame:(CGRect)frame 23 | titles:(NSArray *)titles 24 | subTitles:(NSArray *)subTitles 25 | rowHeight:(CGFloat)rowHeight 26 | didSelectRowBlock:(didSelectRowHandleBlock)didSelectRowBlock 27 | didScrollBlock:(didScrollHandleBlock)didScrollBlock; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Pods/ElegantTableView/ElegantTableView/ElegantTableViewGenerator.m: -------------------------------------------------------------------------------- 1 | // 2 | // ElegantTableViewGenerator.m 3 | // ElegantTableViewDemo 4 | // 5 | // Created by YJHou on 2017/7/3. 6 | // Copyright © 2017年 houmanager. All rights reserved. 7 | // 8 | 9 | #import "ElegantTableViewGenerator.h" 10 | 11 | @interface ElegantTableViewGenerator () 12 | 13 | @property (nonatomic, strong) NSMutableArray *titles; /**< 主数据源 */ 14 | @property (nonatomic, strong) NSMutableArray *subTitles; /**< 主数据源 */ 15 | @property (nonatomic, copy) didSelectRowHandleBlock didselectRowBlock; /**< 点击row */ 16 | @property (nonatomic, copy) didScrollHandleBlock didScrollBlock; /**< 滚动block */ 17 | 18 | @end 19 | 20 | @implementation ElegantTableViewGenerator 21 | 22 | + (ElegantTableViewGenerator *)shareInstance{ 23 | static ElegantTableViewGenerator *_instance = nil; 24 | static dispatch_once_t onceToken; 25 | dispatch_once(&onceToken, ^{ 26 | _instance = [[ElegantTableViewGenerator alloc] init]; 27 | }); 28 | return _instance; 29 | } 30 | 31 | - (UITableView *)createWithFrame:(CGRect)frame 32 | titles:(NSArray *)titles 33 | subTitles:(NSArray *)subTitles 34 | rowHeight:(CGFloat)rowHeight 35 | didSelectRowBlock:(didSelectRowHandleBlock)didSelectRowBlock 36 | didScrollBlock:(didScrollHandleBlock)didScrollBlock{ 37 | 38 | self.titles = [NSMutableArray arrayWithArray:titles]; 39 | self.subTitles = [NSMutableArray arrayWithArray:subTitles]; 40 | self.didselectRowBlock = didSelectRowBlock; 41 | self.didScrollBlock = didScrollBlock; 42 | 43 | UITableView *tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain]; 44 | tableView.delegate = self; 45 | tableView.dataSource = self; 46 | tableView.rowHeight = rowHeight; 47 | tableView.tableFooterView = [UIView new]; 48 | 49 | tableView.estimatedSectionHeaderHeight = tableView.estimatedSectionFooterHeight = tableView.estimatedRowHeight = 0.0f; 50 | 51 | return tableView; 52 | } 53 | 54 | #pragma mark - UITableViewDataSource 55 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 56 | return self.titles.count; 57 | } 58 | 59 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 60 | 61 | NSString * cellId = @"ElegantTableViewGeneratorCellId"; 62 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; 63 | if (cell == nil) { 64 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId]; 65 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 66 | } 67 | 68 | cell.textLabel.text = [self.titles objectAtIndex:indexPath.row]; 69 | 70 | if (self.subTitles.count > 0) { 71 | if (indexPath.row > self.subTitles.count) { 72 | cell.detailTextLabel.text = @""; 73 | }else{ 74 | cell.detailTextLabel.text = [self.subTitles objectAtIndex:indexPath.row]; 75 | } 76 | } 77 | 78 | return cell; 79 | } 80 | 81 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 82 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 83 | if (self.didselectRowBlock) { 84 | self.didselectRowBlock(tableView, indexPath); 85 | } 86 | } 87 | 88 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 89 | if (self.didScrollBlock) { 90 | self.didScrollBlock(scrollView, scrollView.contentOffset); 91 | } 92 | } 93 | 94 | #pragma mark - Lazy 95 | - (NSMutableArray *)titles{ 96 | if (!_titles) { 97 | _titles = [NSMutableArray array]; 98 | } 99 | return _titles; 100 | } 101 | 102 | - (NSMutableArray *)subTitles{ 103 | if (!_subTitles) { 104 | _subTitles = [NSMutableArray array]; 105 | } 106 | return _subTitles; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /Pods/ElegantTableView/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 houmanager 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 | -------------------------------------------------------------------------------- /Pods/ElegantTableView/README.md: -------------------------------------------------------------------------------- 1 | [![CocoaPods](https://img.shields.io/cocoapods/v/ElegantTableView.svg)](https://github.com/stackhou/ElegantTableView.git) 2 | 3 | # ElegantTableView 4 | 优雅的创建TableView 5 | 6 | ### Cocoapods 7 | 8 | a. Add ElegantTableView to your Podfile.
9 | 10 | ```bash 11 | pod 'ElegantTableView' 12 | ``` 13 | 14 | b. Run 15 | 16 | ```bash 17 | pod install 18 | ``` 19 | 20 | 21 | ### Carthage 22 | 23 | a. Add ElegantTableView to your Cartfile.
24 | 25 | ```bash 26 | github "stackhou/ElegantTableView" 27 | ``` 28 | 29 | b. Run 30 | 31 | ```bash 32 | carthage update 33 | ``` 34 | c. Follow the rest of the [standard Carthage installation instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add ElegantTableView to your project. 35 | 36 | 37 | ## Use
38 | 39 | ```objc 40 | 41 | NSArray *dataSources = @[@"你", @"我", @"他", @"1", @"2", @"3"]; 42 | UITableView *tableView = [[ElegantTableViewGenerator shareInstance] createWithFrame:self.view.bounds titles:dataSources subTitles:nil rowHeight:44 didSelectRowBlock:^(UITableView *tableView, NSIndexPath *indexPath) { 43 | NSLog(@"点击TableView-->%ld", (long)indexPath.row); 44 | } didScrollBlock:^(UIScrollView *tableView, CGPoint contentOffset) { 45 | NSLog(@"滚动TableView-->%@", NSStringFromCGPoint(contentOffset)); 46 | }]; 47 | 48 | [self.view addSubview:tableView]; 49 | 50 | ``` 51 | -------------------------------------------------------------------------------- /Pods/Headers/Private/ElegantTableView/ElegantTableViewGenerator.h: -------------------------------------------------------------------------------- 1 | ../../../ElegantTableView/ElegantTableView/ElegantTableViewGenerator.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/UIView+YJBannerViewExt.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Tools/UIView+YJBannerViewExt.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/YJAbstractDotView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAbstractDotView.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/YJAnimatedDotView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAnimatedDotView.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/YJBannerView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/YJBannerView.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/YJBannerViewCell.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCell.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/YJBannerViewCollectionView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCollectionView.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/YJBannerViewFooter.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewFooter.h -------------------------------------------------------------------------------- /Pods/Headers/Private/YJBannerView/YJHollowPageControl.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJHollowPageControl.h -------------------------------------------------------------------------------- /Pods/Headers/Public/Bugly/Bugly/Bugly.h: -------------------------------------------------------------------------------- 1 | ../../../../Bugly/Bugly.framework/Headers/Bugly.h -------------------------------------------------------------------------------- /Pods/Headers/Public/Bugly/Bugly/BuglyConfig.h: -------------------------------------------------------------------------------- 1 | ../../../../Bugly/Bugly.framework/Headers/BuglyConfig.h -------------------------------------------------------------------------------- /Pods/Headers/Public/Bugly/Bugly/BuglyLog.h: -------------------------------------------------------------------------------- 1 | ../../../../Bugly/Bugly.framework/Headers/BuglyLog.h -------------------------------------------------------------------------------- /Pods/Headers/Public/ElegantTableView/ElegantTableViewGenerator.h: -------------------------------------------------------------------------------- 1 | ../../../ElegantTableView/ElegantTableView/ElegantTableViewGenerator.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/UIView+YJBannerViewExt.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Tools/UIView+YJBannerViewExt.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/YJAbstractDotView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAbstractDotView.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/YJAnimatedDotView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAnimatedDotView.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/YJBannerView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/YJBannerView.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/YJBannerViewCell.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCell.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/YJBannerViewCollectionView.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCollectionView.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/YJBannerViewFooter.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewFooter.h -------------------------------------------------------------------------------- /Pods/Headers/Public/YJBannerView/YJHollowPageControl.h: -------------------------------------------------------------------------------- 1 | ../../../YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJHollowPageControl.h -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Bugly (2.5.0) 3 | - ElegantTableView (0.0.3) 4 | - YJBannerView (2.4.0) 5 | 6 | DEPENDENCIES: 7 | - Bugly 8 | - ElegantTableView 9 | - YJBannerView 10 | 11 | SPEC REPOS: 12 | https://github.com/cocoapods/specs.git: 13 | - Bugly 14 | - ElegantTableView 15 | - YJBannerView 16 | 17 | SPEC CHECKSUMS: 18 | Bugly: 3ca9f255c01025582df26f9222893b383c7e4b4e 19 | ElegantTableView: 95e37428e31235a9851acdc6fd0cde24231e9737 20 | YJBannerView: 0c81b7bda592cd23b10ceae8f53c514dcd77e4c6 21 | 22 | PODFILE CHECKSUM: 45f445fe1a82226ca80c9d83d0972e129730d247 23 | 24 | COCOAPODS: 1.5.3 25 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/edz.xcuserdatad/xcschemes/ElegantTableView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/edz.xcuserdatad/xcschemes/Pods-AutoPackingDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/edz.xcuserdatad/xcschemes/YJBannerView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/edz.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ElegantTableView.xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | Pods-AutoPackingDemo.xcscheme 15 | 16 | isShown 17 | 18 | orderHint 19 | 1 20 | 21 | YJBannerView.xcscheme 22 | 23 | isShown 24 | 25 | orderHint 26 | 2 27 | 28 | 29 | SuppressBuildableAutocreation 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ElegantTableView/ElegantTableView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_ElegantTableView : NSObject 3 | @end 4 | @implementation PodsDummy_ElegantTableView 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ElegantTableView/ElegantTableView-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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ElegantTableView/ElegantTableView.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ElegantTableView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ElegantTableView" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/ElegantTableView" 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}/ElegantTableView 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Bugly 5 | 6 | Copyright (C) 2017 Tencent Bugly, Inc. All rights reserved. 7 | 8 | 9 | ## ElegantTableView 10 | 11 | MIT License 12 | 13 | Copyright (c) 2017 houmanager 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | 33 | 34 | ## YJBannerView 35 | 36 | MIT License 37 | 38 | Copyright (c) 2015 houmanager 39 | 40 | Permission is hereby granted, free of charge, to any person obtaining a copy 41 | of this software and associated documentation files (the "Software"), to deal 42 | in the Software without restriction, including without limitation the rights 43 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 44 | copies of the Software, and to permit persons to whom the Software is 45 | furnished to do so, subject to the following conditions: 46 | 47 | The above copyright notice and this permission notice shall be included in all 48 | copies or substantial portions of the Software. 49 | 50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 52 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 53 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 54 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 55 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 56 | SOFTWARE. 57 | 58 | Generated by CocoaPods - https://cocoapods.org 59 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (C) 2017 Tencent Bugly, Inc. All rights reserved. 18 | 19 | License 20 | Copyright 21 | Title 22 | Bugly 23 | Type 24 | PSGroupSpecifier 25 | 26 | 27 | FooterText 28 | MIT License 29 | 30 | Copyright (c) 2017 houmanager 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy 33 | of this software and associated documentation files (the "Software"), to deal 34 | in the Software without restriction, including without limitation the rights 35 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 36 | copies of the Software, and to permit persons to whom the Software is 37 | furnished to do so, subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in all 40 | copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 45 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 47 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 48 | SOFTWARE. 49 | 50 | License 51 | MIT 52 | Title 53 | ElegantTableView 54 | Type 55 | PSGroupSpecifier 56 | 57 | 58 | FooterText 59 | MIT License 60 | 61 | Copyright (c) 2015 houmanager 62 | 63 | Permission is hereby granted, free of charge, to any person obtaining a copy 64 | of this software and associated documentation files (the "Software"), to deal 65 | in the Software without restriction, including without limitation the rights 66 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 67 | copies of the Software, and to permit persons to whom the Software is 68 | furnished to do so, subject to the following conditions: 69 | 70 | The above copyright notice and this permission notice shall be included in all 71 | copies or substantial portions of the Software. 72 | 73 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 74 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 75 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 76 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 77 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 78 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 79 | SOFTWARE. 80 | 81 | License 82 | MIT 83 | Title 84 | YJBannerView 85 | Type 86 | PSGroupSpecifier 87 | 88 | 89 | FooterText 90 | Generated by CocoaPods - https://cocoapods.org 91 | Title 92 | 93 | Type 94 | PSGroupSpecifier 95 | 96 | 97 | StringsTable 98 | Acknowledgements 99 | Title 100 | Acknowledgements 101 | 102 | 103 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_AutoPackingDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_AutoPackingDemo 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo-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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo-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 | if [[ "$CONFIGURATION" == "Debug" ]]; then 95 | install_resource "${PODS_ROOT}/YJBannerView/YJBannerViewDemo/YJBannerView/Resource/YJBannerView.bundle" 96 | fi 97 | if [[ "$CONFIGURATION" == "Release" ]]; then 98 | install_resource "${PODS_ROOT}/YJBannerView/YJBannerViewDemo/YJBannerView/Resource/YJBannerView.bundle" 99 | fi 100 | 101 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 103 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 104 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 105 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 106 | fi 107 | rm -f "$RESOURCES_TO_COPY" 108 | 109 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 110 | then 111 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 112 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 113 | while read line; do 114 | if [[ $line != "${PODS_ROOT}*" ]]; then 115 | XCASSET_FILES+=("$line") 116 | fi 117 | done <<<"$OTHER_XCASSETS" 118 | 119 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 120 | 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}" 121 | else 122 | 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" 123 | fi 124 | fi 125 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Bugly" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Bugly" "${PODS_ROOT}/Headers/Public/ElegantTableView" "${PODS_ROOT}/Headers/Public/YJBannerView" 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ElegantTableView" "${PODS_CONFIGURATION_BUILD_DIR}/YJBannerView" 5 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Bugly" -isystem "${PODS_ROOT}/Headers/Public/ElegantTableView" -isystem "${PODS_ROOT}/Headers/Public/YJBannerView" 6 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ElegantTableView" -l"YJBannerView" -l"c++" -l"z" -framework "Bugly" -framework "Security" -framework "SystemConfiguration" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-AutoPackingDemo/Pods-AutoPackingDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Bugly" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Bugly" "${PODS_ROOT}/Headers/Public/ElegantTableView" "${PODS_ROOT}/Headers/Public/YJBannerView" 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ElegantTableView" "${PODS_CONFIGURATION_BUILD_DIR}/YJBannerView" 5 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Bugly" -isystem "${PODS_ROOT}/Headers/Public/ElegantTableView" -isystem "${PODS_ROOT}/Headers/Public/YJBannerView" 6 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ElegantTableView" -l"YJBannerView" -l"c++" -l"z" -framework "Bugly" -framework "Security" -framework "SystemConfiguration" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/YJBannerView/YJBannerView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_YJBannerView : NSObject 3 | @end 4 | @implementation PodsDummy_YJBannerView 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/YJBannerView/YJBannerView-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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/YJBannerView/YJBannerView.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/YJBannerView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/YJBannerView" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YJBannerView" 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}/YJBannerView 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Pods/YJBannerView/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015 houmanager 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 | -------------------------------------------------------------------------------- /Pods/YJBannerView/README.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://ws2.sinaimg.cn/large/006tNc79ly1fl3joaz995j31kw09htj4.jpg) 2 | 3 | 4 | [![Travis](https://img.shields.io/travis/stackhou/YJBannerViewOC.svg?style=flat)](https://github.com/stackhou/YJBannerViewOC.git) 5 | [![Language](https://img.shields.io/badge/Language-Objective--C-FF7F24.svg?style=flat)](https://github.com/YJManager/YJBannerViewOC.git) 6 | [![CocoaPods](https://img.shields.io/cocoapods/p/YJBannerView.svg)](https://github.com/stackhou/YJBannerViewOC.git) 7 | [![CocoaPods](https://img.shields.io/cocoapods/v/YJBannerView.svg)](https://github.com/stackhou/YJBannerViewOC.git) 8 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/stackhou/YJBannerViewOC.git) 9 | 10 | 11 | # YJBannerView 12 | - 使用简单、功能丰富的 `Objective-C版` 轮播控件, 基于 `UICollectionView` 实现, 多种场景均支持使用. 13 | 14 | ## 效果样例 15 | 普通 | 自定义View 16 | ---- | --- 17 | | 18 | 19 | 20 | ## Features 21 | 22 | - [x] 支持自带PageControl样式配置, 也支持自定义 23 | - [x] 支持上、下、左、右四个方向自动、手动动滚动 24 | - [x] 支持自动滚动时间设置 25 | - [x] 支持首尾循环滚动的开关 26 | - [x] 支持滚动相关手势的开关 27 | - [x] 支持ContentMode的设置 28 | - [x] 支持Banner标题的设置自定义 29 | - [x] 支持自定义UICollectionViewCell 30 | - [x] 支持在Storyboard\xib中创建并配置其属性 31 | - [x] 支持非首尾循环的Footer样式和进入详情回调 32 | - [x] 不依赖其他三方SDWebImage或者AFNetworking设置图片 33 | - [x] 支持CocoaPods 34 | - [x] 支持Carthage 35 | - [x] 支持获取当前位置的自身偏移量 36 | 37 | 38 | ## Installation 39 | 40 | ### Cocoapods 41 | 42 | YJBannerView is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your Podfile: 43 | 44 | ```ruby 45 | pod 'YJBannerView' 46 | ``` 47 | 48 | ### Carthage 49 | ```ruby 50 | github "stackhou/YJBannerView" 51 | ``` 52 | 53 | ## Usage 54 | 55 | ### 1.创建BannerView: 56 | ```objc 57 | -(YJBannerView *)normalBannerView{ 58 | if (!_normalBannerView) { 59 | _normalBannerView = [YJBannerView bannerViewWithFrame:CGRectMake(0, 20, kSCREEN_WIDTH, 180) dataSource:self delegate:self placeholderImageName:@"placeholder" selectorString:@"sd_setImageWithURL:placeholderImage:"]; 60 | _normalBannerView.pageControlAliment = PageControlAlimentRight; 61 | _normalBannerView.autoDuration = 2.5f; 62 | } 63 | return _normalBannerView; 64 | } 65 | ``` 66 | ### 2.实现数据源方法和代理: 67 | ```objc 68 | // 将网络图片或者本地图片 或者混合数组 69 | - (NSArray *)bannerViewImages:(YJBannerView *)bannerView{ 70 | return self.imageDataSources; 71 | } 72 | 73 | // 将标题对应数组传递给bannerView 如果不需要, 可以不实现该方法 74 | - (NSArray *)bannerViewTitles:(YJBannerView *)bannerView{ 75 | return self.titlesDataSources; 76 | } 77 | 78 | // 代理方法 点击了哪个bannerView 的 第几个元素 79 | -(void)bannerView:(YJBannerView *)bannerView didSelectItemAtIndex:(NSInteger)index{ 80 | NSString *title = [self.titlesDataSources objectAtIndex:index]; 81 | NSLog(@"当前%@-->%@", bannerView, title); 82 | } 83 | ``` 84 | 85 | ### 扩展自定义方法 86 | ```objc 87 | // 自定义Cell方法 88 | - (Class)bannerViewCustomCellClass:(YJBannerView *)bannerView{ 89 | return [HeadLinesCell class]; 90 | } 91 | 92 | // 自定义Cell的数据刷新方法 93 | - (void)bannerView:(YJBannerView *)bannerView customCell:(UICollectionViewCell *)customCell index:(NSInteger)index{ 94 | 95 | HeadLinesCell *cell = (HeadLinesCell *)customCell; 96 | [cell cellWithHeadHotLineCellData:@"打折活动开始了~~快来抢购啊"]; 97 | } 98 | ``` 99 | 100 | ## 版本记录 101 | 102 | 日期 | 版本号 | 更新内容 103 | ------ | ----- | ---- 104 | 2015-5-10~2016-10-17 | 1.0~2.0 | 2.0之前的更新内容没有实际意义,省略... 105 | 2016-10-17~2017-01-01 | 2.0~2.1 | 功能完善Bug修复等 106 | 2017-01-01~2017-07-30 | 2.1~2.2 | 主要功能优化,新增FooterView等 107 | 2017-7-30~2017-09-30 | 2.2.0~2.3.0 | 调优、降低内存消耗等 108 | 2017-9-30 | 2.3.0 | 调优 创建该控件由原来的120毫秒 优化到只需要60毫秒左右,和创建一个UILabel相当。 109 | 2017-11-1 | 2.3.1 | 增加停止定时器和重新开启定时器API 110 | 2017-11-16 | 2.3.2 | 修复当数据为空时刷新后再次有数据刷新不滚动问题 111 | 2017-12-05 | 2.3.4 | 规范图片加载流程 112 | 2017-12-06 | 2.3.5 | 区分没有数据的占位图片和图片未加载的占位图片 113 | 2017-12-14 | 2.3.6 | 数据安全保护和数据更新速度优化 114 | 2017-12-15 | 2.3.7 | 增加当前滚动位置相对偏移量API 115 | 2018-01-18 | 2.3.8 | 优化自定义View的实现方式,支持不同位置的Banner自由选择显示类型 116 | 2018-06-21 | 2.3.9 | 更新 Cocoapods 配置 Source 的修正 117 | 2018-07-09 | 2.4.0 | 修改手势在iOS 8.1上面的 Crash Bug 118 | 119 | ## 性能表现 120 | 121 | - 简单设置时: 122 | 123 | ![](https://ws2.sinaimg.cn/large/006tKfTcly1fk1lk1i4d7j30c903uwf8.jpg) 124 | 125 | - 复杂设置时: 126 | 127 | ![](https://ws2.sinaimg.cn/large/006tKfTcly1fk1lktrc6fj30bu03q750.jpg) 128 | 129 | --- 130 | 131 | ## License 132 | 133 | This code is distributed under the terms and conditions of the [MIT license](LICENSE). 134 | 135 | ## Change-log 136 | 137 | A brief summary of each YJBannerView release can be found in the [CHANGELOG](CHANGELOG.mdown). 138 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAbstractDotView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YJAbstractDotView.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface YJAbstractDotView : UIView 12 | 13 | - (void)changeActivityState:(BOOL)active; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAbstractDotView.m: -------------------------------------------------------------------------------- 1 | // 2 | // YJAbstractDotView.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "YJAbstractDotView.h" 10 | 11 | @implementation YJAbstractDotView 12 | 13 | - (id)init{ 14 | @throw [NSException exceptionWithName:NSInternalInconsistencyException 15 | reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class] 16 | userInfo:nil]; 17 | } 18 | 19 | 20 | - (void)changeActivityState:(BOOL)active{ 21 | @throw [NSException exceptionWithName:NSInternalInconsistencyException 22 | reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class] 23 | userInfo:nil]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAnimatedDotView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YJAnimatedDotView.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "YJAbstractDotView.h" 10 | 11 | @interface YJAnimatedDotView : YJAbstractDotView 12 | 13 | @property (nonatomic, strong) UIColor *dotColor; 14 | @property (nonatomic, strong) UIColor *currentDotColor; 15 | @property (nonatomic, assign) CGFloat resizeScale; /**< 调整比例 */ 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJAnimatedDotView.m: -------------------------------------------------------------------------------- 1 | // 2 | // YJAnimatedDotView.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "YJAnimatedDotView.h" 10 | 11 | static CGFloat const kAnimateDuration = 0; 12 | 13 | @implementation YJAnimatedDotView 14 | 15 | - (instancetype)init{ 16 | self = [super init]; 17 | if (self) { 18 | [self initialization]; 19 | } 20 | return self; 21 | } 22 | 23 | - (id)initWithFrame:(CGRect)frame{ 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | [self initialization]; 27 | } 28 | return self; 29 | } 30 | 31 | - (id)initWithCoder:(NSCoder *)aDecoder{ 32 | self = [super initWithCoder:aDecoder]; 33 | if (self) { 34 | [self initialization]; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)setDotColor:(UIColor *)dotColor{ 40 | _dotColor = dotColor; 41 | self.layer.borderColor = dotColor.CGColor; 42 | } 43 | 44 | - (void)setCurrentDotColor:(UIColor *)currentDotColor{ 45 | _currentDotColor = currentDotColor; 46 | self.backgroundColor = [UIColor clearColor]; 47 | } 48 | 49 | - (void)initialization{ 50 | _dotColor = [UIColor whiteColor]; 51 | _currentDotColor = [UIColor whiteColor]; 52 | self.backgroundColor = [UIColor clearColor]; 53 | self.layer.cornerRadius = CGRectGetWidth(self.frame) * 0.5; 54 | self.layer.borderColor = [UIColor whiteColor].CGColor; 55 | self.layer.borderWidth = 1.5; 56 | self.resizeScale = 1.4f; 57 | } 58 | 59 | - (void)changeActivityState:(BOOL)active{ 60 | if (active) { 61 | [self animateToActiveState]; 62 | } else { 63 | [self animateToDeactiveState]; 64 | } 65 | } 66 | 67 | - (void)animateToActiveState{ 68 | [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:-20 options:UIViewAnimationOptionCurveLinear animations:^{ 69 | self.backgroundColor = self.currentDotColor; 70 | self.layer.borderColor = [UIColor clearColor].CGColor; 71 | self.transform = CGAffineTransformMakeScale(self.resizeScale, self.resizeScale); 72 | } completion:nil]; 73 | } 74 | 75 | - (void)animateToDeactiveState{ 76 | [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{ 77 | self.backgroundColor = [UIColor clearColor]; 78 | self.layer.borderColor = self.dotColor.CGColor; 79 | self.transform = CGAffineTransformIdentity; 80 | } completion:nil]; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJHollowPageControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // YJHollowPageControl.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import 10 | #import "YJAbstractDotView.h" 11 | 12 | @class YJHollowPageControl; 13 | @protocol YJHollowPageControlDelegate 14 | 15 | @optional 16 | - (void)yjHollowPageControl:(YJHollowPageControl *)pageControl didSelectPageAtIndex:(NSInteger)index; 17 | 18 | @end 19 | 20 | @interface YJHollowPageControl : UIControl 21 | 22 | @property (nonatomic, assign) CGSize dotSize; /**< 圆点大小 默认8*8 */ 23 | @property (nonatomic, strong) UIImage *dotNormalImage; /**< 普通样式 */ 24 | @property (nonatomic, strong) UIImage *dotCurrentImage; /**< 选中样式 */ 25 | 26 | @property (nonatomic, strong) UIColor *dotNormalColor; /**< 点色 */ 27 | @property (nonatomic, strong) UIColor *dotCurrentColor; /**< 当前圆点的颜色 */ 28 | 29 | @property (nonatomic, strong) Class dotViewClass; /**< 圆点类 */ 30 | @property (nonatomic, weak) id delegate; /**< 代理 */ 31 | @property (nonatomic, assign) CGFloat spacing; /**< 间距 默认 8 */ 32 | @property (nonatomic, assign) NSInteger numberOfPages; /**< 数量 */ 33 | @property (nonatomic, assign) NSInteger currentPage; /**< 当前位置 */ 34 | @property (nonatomic, assign) BOOL hidesForSinglePage; /**< 单个不显示 默认NO*/ 35 | @property (nonatomic, assign) BOOL shouldResizeFromCenter; /**< 是否调整大小 */ 36 | @property (nonatomic, assign) CGFloat resizeScale; /**< 调整比例 */ 37 | 38 | - (CGSize)sizeForNumberOfPages:(NSInteger)pageCount; 39 | 40 | @end 41 | 42 | 43 | @interface YJDotView : YJAbstractDotView 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/PageControls/YJHollowPageControl/YJHollowPageControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // YJHollowPageControl.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "YJHollowPageControl.h" 10 | #import "YJAnimatedDotView.h" 11 | 12 | static CGSize const kDefaultDotSize = {8, 8}; 13 | static NSInteger const kDefaultNumberOfPages = 0; 14 | static NSInteger const kDefaultCurrentPage = 0; 15 | static BOOL const kDefaultHideForSinglePage = NO; 16 | static BOOL const kDefaultShouldResizeFromCenter = YES; 17 | static NSInteger const kDefaultSpacingBetweenDots = 8; 18 | 19 | @interface YJHollowPageControl () 20 | 21 | @property (nonatomic, strong) NSMutableArray *dots; /**< 保存所有的点 */ 22 | 23 | @end 24 | 25 | @implementation YJHollowPageControl 26 | 27 | - (id)init{ 28 | self = [super init]; 29 | if (self) { 30 | [self _initializationSetting]; 31 | } 32 | return self; 33 | } 34 | 35 | - (id)initWithFrame:(CGRect)frame{ 36 | self = [super initWithFrame:frame]; 37 | if (self) { 38 | [self _initializationSetting]; 39 | } 40 | return self; 41 | } 42 | 43 | - (id)initWithCoder:(NSCoder *)aDecoder{ 44 | self = [super initWithCoder:aDecoder]; 45 | if (self) { 46 | [self _initializationSetting]; 47 | } 48 | return self; 49 | } 50 | 51 | - (void)_initializationSetting{ 52 | self.dotViewClass = [YJAnimatedDotView class]; 53 | self.spacing = kDefaultSpacingBetweenDots; 54 | self.numberOfPages = kDefaultNumberOfPages; 55 | self.currentPage = kDefaultCurrentPage; 56 | self.hidesForSinglePage = kDefaultHideForSinglePage; 57 | self.shouldResizeFromCenter = kDefaultShouldResizeFromCenter; 58 | } 59 | 60 | 61 | #pragma mark - Touch event 62 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 63 | UITouch *touch = [touches anyObject]; 64 | if (touch.view != self) { 65 | NSInteger index = [self.dots indexOfObject:touch.view]; 66 | if ([self.delegate respondsToSelector:@selector(yjHollowPageControl:didSelectPageAtIndex:)]) { 67 | [self.delegate yjHollowPageControl:self didSelectPageAtIndex:index]; 68 | } 69 | } 70 | } 71 | 72 | - (void)sizeToFit{ 73 | [self updateFrame:YES]; 74 | } 75 | 76 | - (CGSize)sizeForNumberOfPages:(NSInteger)pageCount{ 77 | return CGSizeMake((self.dotSize.width + self.spacing) * pageCount - self.spacing , self.dotSize.height); 78 | } 79 | 80 | 81 | - (void)updateDots{ 82 | if (self.numberOfPages == 0) {return;} 83 | 84 | for (NSInteger i = 0; i < self.numberOfPages; i++) { 85 | 86 | UIView *dot; 87 | if (i < self.dots.count) { 88 | dot = [self.dots objectAtIndex:i]; 89 | } else { 90 | dot = [self generateDotView]; 91 | } 92 | [self updateDotFrame:dot atIndex:i]; 93 | } 94 | [self changeActivity:YES atIndex:self.currentPage]; 95 | 96 | [self hideForSinglePage]; 97 | } 98 | 99 | /** 100 | Update frame to fit current number of pages. 101 | 102 | @param newFrame override Existing Frame 103 | */ 104 | - (void)updateFrame:(BOOL)newFrame{ 105 | CGPoint center = self.center; 106 | CGSize requiredSize = [self sizeForNumberOfPages:self.numberOfPages]; 107 | 108 | // We apply requiredSize only if authorize to and necessary 109 | if (newFrame || ((CGRectGetWidth(self.frame) < requiredSize.width || CGRectGetHeight(self.frame) < requiredSize.height) && !newFrame)) { 110 | self.frame = CGRectMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame), requiredSize.width, requiredSize.height); 111 | if (self.shouldResizeFromCenter) { 112 | self.center = center; 113 | } 114 | } 115 | [self resetDotViews]; 116 | } 117 | 118 | /** 119 | * Update the frame of a specific dot at a specific index 120 | * 121 | * @param dot Dot view 122 | * @param index Page index of dot 123 | */ 124 | - (void)updateDotFrame:(UIView *)dot atIndex:(NSInteger)index{ 125 | // Dots are always centered within view 126 | CGFloat x = (self.dotSize.width + self.spacing) * index + ( (CGRectGetWidth(self.frame) - [self sizeForNumberOfPages:self.numberOfPages].width) / 2); 127 | CGFloat y = (CGRectGetHeight(self.frame) - self.dotSize.height) / 2; 128 | 129 | dot.frame = CGRectMake(x, y, self.dotSize.width, self.dotSize.height); 130 | } 131 | 132 | - (void)setDotCurrentColor:(UIColor *)currentDotColor{ 133 | _dotCurrentColor = currentDotColor; 134 | } 135 | 136 | - (void)setDotNormalColor:(UIColor *)dotColor{ 137 | _dotNormalColor = dotColor; 138 | } 139 | 140 | 141 | #pragma mark - Utils 142 | /** 143 | * Generate a dot view and add it to the collection 144 | * 145 | * @return The UIView object representing a dot 146 | */ 147 | - (UIView *)generateDotView{ 148 | UIView *dotView; 149 | 150 | if (self.dotViewClass) { 151 | dotView = [[self.dotViewClass alloc] initWithFrame:CGRectMake(0, 0, self.dotSize.width, self.dotSize.height)]; 152 | if ([dotView isKindOfClass:[YJAnimatedDotView class]]) { 153 | if (self.resizeScale > 0) { 154 | ((YJAnimatedDotView *)dotView).resizeScale = self.resizeScale; 155 | } 156 | if (self.dotNormalColor) { 157 | ((YJAnimatedDotView *)dotView).dotColor = self.dotNormalColor; 158 | } 159 | if (self.dotCurrentColor){ 160 | ((YJAnimatedDotView *)dotView).currentDotColor = self.dotCurrentColor; 161 | } 162 | } 163 | } else { 164 | dotView = [[UIImageView alloc] initWithImage:self.dotNormalImage]; 165 | dotView.contentMode = UIViewContentModeScaleAspectFit; 166 | dotView.frame = CGRectMake(0, 0, self.dotSize.width, self.dotSize.height); 167 | } 168 | 169 | if (dotView) { 170 | [self addSubview:dotView]; 171 | [self.dots addObject:dotView]; 172 | } 173 | 174 | dotView.userInteractionEnabled = YES; 175 | return dotView; 176 | } 177 | 178 | 179 | /** 180 | * Change activity state of a dot view. Current/not currrent. 181 | * 182 | * @param active Active state to apply 183 | * @param index Index of dot for state update 184 | */ 185 | - (void)changeActivity:(BOOL)active atIndex:(NSInteger)index{ 186 | if (self.dotViewClass) { 187 | YJAbstractDotView *abstractDotView = (YJAbstractDotView *)[self.dots objectAtIndex:index]; 188 | if ([abstractDotView respondsToSelector:@selector(changeActivityState:)]) { 189 | [abstractDotView changeActivityState:active]; 190 | } else { 191 | NSLog(@"Custom view : %@ must implement an 'changeActivityState' method or you can subclass %@ to help you.", self.dotViewClass, [YJAbstractDotView class]); 192 | } 193 | } else if (self.dotNormalImage && self.dotCurrentImage) { 194 | UIImageView *dotView = (UIImageView *)[self.dots objectAtIndex:index]; 195 | dotView.image = (active) ? self.dotCurrentImage : self.dotNormalImage; 196 | } 197 | } 198 | 199 | - (void)resetDotViews{ 200 | for (UIView *dotView in self.dots) { 201 | [dotView removeFromSuperview]; 202 | } 203 | [self.dots removeAllObjects]; 204 | [self updateDots]; 205 | } 206 | 207 | - (void)hideForSinglePage{ 208 | if (self.dots.count == 1 && self.hidesForSinglePage) { 209 | self.hidden = YES; 210 | } else { 211 | self.hidden = NO; 212 | } 213 | } 214 | 215 | #pragma mark - Setters 216 | - (void)setNumberOfPages:(NSInteger)numberOfPages{ 217 | _numberOfPages = numberOfPages; 218 | // Update dot position to fit new number of pages 219 | [self resetDotViews]; 220 | } 221 | 222 | - (void)setSpacing:(CGFloat)spacing{ 223 | _spacing = spacing; 224 | [self resetDotViews]; 225 | } 226 | 227 | - (void)setCurrentPage:(NSInteger)currentPage{ 228 | // If no pages, no current page to treat. 229 | if (self.numberOfPages == 0 || currentPage == _currentPage) { 230 | _currentPage = currentPage; 231 | return; 232 | } 233 | 234 | // Pre set 235 | [self changeActivity:NO atIndex:_currentPage]; 236 | _currentPage = currentPage; 237 | // Post set 238 | [self changeActivity:YES atIndex:_currentPage]; 239 | } 240 | 241 | - (void)setDotNormalImage:(UIImage *)dotImage{ 242 | _dotNormalImage = dotImage; 243 | [self resetDotViews]; 244 | self.dotViewClass = nil; 245 | } 246 | 247 | - (void)setDotCurrentImage:(UIImage *)currentDotimage{ 248 | _dotCurrentImage = currentDotimage; 249 | [self resetDotViews]; 250 | self.dotViewClass = nil; 251 | } 252 | 253 | - (void)setDotViewClass:(Class)dotViewClass{ 254 | _dotViewClass = dotViewClass; 255 | self.dotSize = CGSizeZero; 256 | [self resetDotViews]; 257 | } 258 | 259 | #pragma mark - Getter 260 | - (CGSize)dotSize{ 261 | if (self.dotNormalImage && CGSizeEqualToSize(_dotSize, CGSizeZero)) { 262 | _dotSize = self.dotNormalImage.size; 263 | } else if (self.dotViewClass && CGSizeEqualToSize(_dotSize, CGSizeZero)) { 264 | _dotSize = kDefaultDotSize; 265 | return _dotSize; 266 | } 267 | return _dotSize; 268 | } 269 | 270 | #pragma mark - Lazy 271 | - (NSMutableArray *)dots{ 272 | if (!_dots) { 273 | _dots = [NSMutableArray array]; 274 | } 275 | return _dots; 276 | } 277 | 278 | @end 279 | 280 | 281 | @implementation YJDotView 282 | 283 | - (instancetype)init{ 284 | self = [super init]; 285 | if (self) { 286 | [self _initializationSetting]; 287 | } 288 | return self; 289 | } 290 | 291 | - (id)initWithFrame:(CGRect)frame{ 292 | self = [super initWithFrame:frame]; 293 | if (self) { 294 | [self _initializationSetting]; 295 | } 296 | return self; 297 | } 298 | 299 | - (id)initWithCoder:(NSCoder *)aDecoder{ 300 | self = [super initWithCoder:aDecoder]; 301 | if (self) { 302 | [self _initializationSetting]; 303 | } 304 | return self; 305 | } 306 | 307 | - (void)_initializationSetting{ 308 | self.backgroundColor = [UIColor clearColor]; 309 | self.layer.cornerRadius = CGRectGetWidth(self.frame) * 0.5; 310 | self.layer.borderColor = [UIColor whiteColor].CGColor; 311 | self.layer.borderWidth = 2; 312 | } 313 | 314 | - (void)changeActivityState:(BOOL)active{ 315 | if (active) { 316 | self.backgroundColor = [UIColor whiteColor]; 317 | } else { 318 | self.backgroundColor = [UIColor clearColor]; 319 | } 320 | } 321 | 322 | @end 323 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Resource/YJBannerView.bundle/yjbanner_arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaye/AutoPacking-iOS/308024d23951079a316e7e18f7c14b79b97ee901/Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Resource/YJBannerView.bundle/yjbanner_arrow@2x.png -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Resource/YJBannerView.bundle/yjbanner_arrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaye/AutoPacking-iOS/308024d23951079a316e7e18f7c14b79b97ee901/Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Resource/YJBannerView.bundle/yjbanner_arrow@3x.png -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Tools/UIView+YJBannerViewExt.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+YJBannerViewExt.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (YJBannerViewExt) 12 | 13 | @property (nonatomic, assign) CGFloat x_bannerView; 14 | @property (nonatomic, assign) CGFloat y_bannerView; 15 | 16 | @property (nonatomic, assign) CGFloat width_bannerView; 17 | @property (nonatomic, assign) CGFloat height_bannerView; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Tools/UIView+YJBannerViewExt.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+YJBannerViewExt.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "UIView+YJBannerViewExt.h" 10 | 11 | @implementation UIView (YJBannerViewExt) 12 | 13 | - (void)setX_bannerView:(CGFloat)x_bannerView{ 14 | CGRect temp = self.frame; 15 | temp.origin.x = x_bannerView; 16 | self.frame = temp; 17 | } 18 | 19 | - (CGFloat)x_bannerView{ 20 | return self.frame.origin.x; 21 | } 22 | 23 | - (void)setY_bannerView:(CGFloat)y_bannerView{ 24 | CGRect temp = self.frame; 25 | temp.origin.y = y_bannerView; 26 | self.frame = temp; 27 | } 28 | 29 | - (CGFloat)y_bannerView{ 30 | return self.frame.origin.y; 31 | } 32 | 33 | - (void)setWidth_bannerView:(CGFloat)width_bannerView{ 34 | CGRect temp = self.frame; 35 | temp.size.width = width_bannerView; 36 | self.frame = temp; 37 | } 38 | 39 | - (CGFloat)width_bannerView{ 40 | return self.frame.size.width; 41 | } 42 | 43 | - (void)setHeight_bannerView:(CGFloat)height_bannerView{ 44 | CGRect temp = self.frame; 45 | temp.size.height = height_bannerView; 46 | self.frame = temp; 47 | } 48 | 49 | - (CGFloat)height_bannerView{ 50 | return self.frame.size.height; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerViewCell.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface YJBannerViewCell : UICollectionViewCell 12 | 13 | @property (nonatomic, strong) UIColor *titleLabelTextColor; 14 | @property (nonatomic, strong) UIFont *titleLabelTextFont; 15 | @property (nonatomic, strong) UIColor *titleLabelBackgroundColor; 16 | @property (nonatomic, assign) CGFloat titleLabelHeight; 17 | @property (nonatomic, assign) CGFloat titleLabelEdgeMargin; 18 | @property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment; 19 | @property (nonatomic, assign) UIViewContentMode showImageViewContentMode; /**< 填充样式 默认UIViewContentModeScaleToFill */ 20 | @property (nonatomic, assign) BOOL isConfigured; 21 | 22 | - (void)cellWithSelectorString:(NSString *)selectorString imagePath:(NSString *)imagePath placeholderImage:(UIImage *)placeholderImage title:(NSString *)title; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerViewCell.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "YJBannerViewCell.h" 10 | #import "UIView+YJBannerViewExt.h" 11 | 12 | @interface YJBannerViewCell () 13 | 14 | @property (nonatomic, strong) UIImageView *showImageView; /**< 显示图片 */ 15 | @property (nonatomic, strong) UILabel *titleLabel; /**< 标题头 */ 16 | @property (nonatomic, strong) UIView *titleLabelBgView; /**< 标题背景 */ 17 | 18 | @end 19 | 20 | @implementation YJBannerViewCell 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame{ 23 | if (self = [super initWithFrame:frame]) { 24 | [self _setUpMainView]; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)_setUpMainView{ 30 | [self.contentView addSubview:self.showImageView]; 31 | [self.contentView addSubview:self.titleLabelBgView]; 32 | [self.contentView addSubview:self.titleLabel]; 33 | } 34 | 35 | #pragma mark - Setter && Getter 36 | - (void)setTitleLabelBackgroundColor:(UIColor *)titleLabelBackgroundColor{ 37 | _titleLabelBackgroundColor = titleLabelBackgroundColor; 38 | self.titleLabelBgView.backgroundColor = titleLabelBackgroundColor; 39 | } 40 | 41 | - (void)setTitleLabelTextColor:(UIColor *)titleLabelTextColor{ 42 | _titleLabelTextColor = titleLabelTextColor; 43 | self.titleLabel.textColor = titleLabelTextColor; 44 | } 45 | 46 | - (void)setTitleLabelTextFont:(UIFont *)titleLabelTextFont{ 47 | _titleLabelTextFont = titleLabelTextFont; 48 | self.titleLabel.font = titleLabelTextFont; 49 | } 50 | 51 | -(void)setTitleLabelTextAlignment:(NSTextAlignment)titleLabelTextAlignment{ 52 | _titleLabelTextAlignment = titleLabelTextAlignment; 53 | self.titleLabel.textAlignment = titleLabelTextAlignment; 54 | } 55 | 56 | - (void)setShowImageViewContentMode:(UIViewContentMode)showImageViewContentMode{ 57 | _showImageViewContentMode = showImageViewContentMode; 58 | self.showImageView.contentMode = showImageViewContentMode; 59 | } 60 | 61 | - (void)layoutSubviews{ 62 | [super layoutSubviews]; 63 | 64 | CGFloat titleBgViewlH = self.titleLabelHeight; 65 | self.showImageView.frame = self.bounds; 66 | titleBgViewlH = self.titleLabelHeight; 67 | 68 | CGFloat titlBgViewX = 0.0f; 69 | CGFloat titleBgViewY = self.height_bannerView - titleBgViewlH; 70 | CGFloat titleBgViewW = self.width_bannerView - 2 * titlBgViewX; 71 | _titleLabelBgView.frame = CGRectMake(titlBgViewX, titleBgViewY, titleBgViewW, titleBgViewlH); 72 | 73 | CGFloat titleLabelH = titleBgViewlH; 74 | CGFloat titleLabelX = self.titleLabelEdgeMargin; 75 | CGFloat titleLabelY = titleBgViewY; 76 | CGFloat titleLabelW = self.width_bannerView - 2 * titleLabelX; 77 | _titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH); 78 | } 79 | 80 | #pragma mark - 刷新数据 81 | - (void)cellWithSelectorString:(NSString *)selectorString imagePath:(NSString *)imagePath placeholderImage:(UIImage *)placeholderImage title:(NSString *)title{ 82 | 83 | if (imagePath) { 84 | self.showImageView.hidden = NO; 85 | if ([imagePath isKindOfClass:[NSString class]]) { 86 | if ([imagePath hasPrefix:@"http"]) { 87 | 88 | // 检验方法是否可用 89 | SEL selector = NSSelectorFromString(selectorString); 90 | if ([self.showImageView respondsToSelector:selector]) { 91 | #pragma clang diagnostic push 92 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 93 | [self.showImageView performSelector:selector withObject:[NSURL URLWithString:imagePath] withObject:placeholderImage]; 94 | #pragma clang diagnostic pop 95 | } 96 | } else { 97 | if (imagePath.length > 0) { 98 | UIImage *image = [UIImage imageNamed:imagePath]; 99 | if (!image) { 100 | image = [UIImage imageWithContentsOfFile:imagePath]; 101 | } 102 | self.showImageView.image = image; 103 | } 104 | } 105 | } else if ([imagePath isKindOfClass:[UIImage class]]) { 106 | self.showImageView.image = (UIImage *)imagePath; 107 | }else{ 108 | self.showImageView.image = placeholderImage; 109 | } 110 | }else{ 111 | self.showImageView.hidden = YES; 112 | } 113 | 114 | if (title.length > 0) { 115 | self.titleLabel.text = title; 116 | self.titleLabel.hidden = NO; 117 | self.titleLabelBgView.hidden = NO; 118 | }else{ 119 | self.titleLabel.hidden = YES; 120 | self.titleLabelBgView.hidden = YES; 121 | } 122 | } 123 | 124 | #pragma mark - Lazy 125 | - (UIImageView *)showImageView{ 126 | if (!_showImageView) { 127 | _showImageView = [[UIImageView alloc] init]; 128 | } 129 | return _showImageView; 130 | } 131 | 132 | - (UILabel *)titleLabel{ 133 | if (!_titleLabel) { 134 | _titleLabel = [[UILabel alloc] init]; 135 | _titleLabel.hidden = YES; 136 | _titleLabel.backgroundColor = [UIColor clearColor]; 137 | } 138 | return _titleLabel; 139 | } 140 | 141 | - (UIView *)titleLabelBgView{ 142 | if (!_titleLabelBgView) { 143 | _titleLabelBgView = [[UIView alloc] init]; 144 | _titleLabelBgView.hidden = YES; 145 | } 146 | return _titleLabelBgView; 147 | } 148 | 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCollectionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerViewCollectionView.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2017/11/21. 6 | // Copyright © 2017年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface YJBannerViewCollectionView : UICollectionView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewCollectionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerViewCollectionView.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2017/11/21. 6 | // Copyright © 2017年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "YJBannerViewCollectionView.h" 10 | 11 | @implementation YJBannerViewCollectionView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerViewFooter.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, YJBannerViewStatus) { 12 | YJBannerViewStatusIdle = 0, // 闲置 13 | YJBannerViewStatusTrigger // 触发 14 | }; 15 | 16 | @interface YJBannerViewFooter : UICollectionReusableView 17 | 18 | @property (nonatomic, assign) YJBannerViewStatus state; 19 | 20 | @property (nonatomic, strong) UIFont *footerTitleFont; 21 | @property (nonatomic, strong) UIColor *footerTitleColor; 22 | @property (nonatomic, copy) NSString *IndicateImageName; /**< 指示图片的名字 */ 23 | @property (nonatomic, copy) NSString *idleTitle; /**< 闲置 */ 24 | @property (nonatomic, copy) NSString *triggerTitle; /**< 触发 */ 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/Views/YJBannerViewFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerViewFooter.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | #import "YJBannerViewFooter.h" 10 | 11 | #define YJ_ARROW_SIZE 15.0f 12 | 13 | @interface YJBannerViewFooter () 14 | 15 | @property (nonatomic, strong) UIImageView *arrowView; 16 | @property (nonatomic, strong) UILabel *label; 17 | 18 | @end 19 | 20 | @implementation YJBannerViewFooter 21 | 22 | @synthesize idleTitle = _idleTitle; 23 | @synthesize triggerTitle = _triggerTitle; 24 | 25 | 26 | - (instancetype)initWithFrame:(CGRect)frame{ 27 | self = [super initWithFrame:frame]; 28 | if (self) { 29 | [self addSubview:self.arrowView]; 30 | [self addSubview:self.label]; 31 | 32 | self.state = YJBannerViewStatusIdle; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)layoutSubviews{ 38 | [super layoutSubviews]; 39 | 40 | CGFloat arrowX = self.bounds.size.width * 0.5 - YJ_ARROW_SIZE - 2.5; 41 | CGFloat arrowY = (self.bounds.size.height - YJ_ARROW_SIZE) * 0.5; 42 | CGFloat arrowW = YJ_ARROW_SIZE; 43 | CGFloat arrowH = YJ_ARROW_SIZE; 44 | self.arrowView.frame = CGRectMake(arrowX, arrowY, arrowW, arrowH); 45 | 46 | CGFloat labelX = self.bounds.size.width * 0.5 + 2.5; 47 | CGFloat labelY = 0; 48 | CGFloat labelW = YJ_ARROW_SIZE; 49 | CGFloat labelH = self.bounds.size.height; 50 | self.label.frame = CGRectMake(labelX, labelY, labelW, labelH); 51 | } 52 | 53 | #pragma mark - setters & getters 54 | - (void)setState:(YJBannerViewStatus)state{ 55 | _state = state; 56 | 57 | switch (state) { 58 | case YJBannerViewStatusIdle:{ 59 | self.label.text = self.idleTitle; 60 | [UIView animateWithDuration:0.25 animations:^{ 61 | self.arrowView.transform = CGAffineTransformMakeRotation(0); 62 | }]; 63 | } 64 | break; 65 | case YJBannerViewStatusTrigger:{ 66 | self.label.text = self.triggerTitle; 67 | [UIView animateWithDuration:0.25 animations:^{ 68 | self.arrowView.transform = CGAffineTransformMakeRotation(M_PI); 69 | }]; 70 | } 71 | break; 72 | default: 73 | break; 74 | } 75 | } 76 | 77 | #pragma mark - Setter 78 | - (void)setFooterTitleFont:(UIFont *)footerTitleFont{ 79 | _footerTitleFont = footerTitleFont; 80 | self.label.font = _footerTitleFont; 81 | } 82 | 83 | - (void)setFooterTitleColor:(UIColor *)footerTitleColor{ 84 | _footerTitleColor = footerTitleColor; 85 | self.label.textColor = _footerTitleColor; 86 | } 87 | 88 | - (void)setIndicateImageName:(NSString *)IndicateImageName{ 89 | _IndicateImageName = IndicateImageName; 90 | if (_IndicateImageName.length > 0 && self.arrowView.image == nil) { 91 | self.arrowView.image = [UIImage imageNamed:_IndicateImageName]; 92 | } 93 | } 94 | 95 | #pragma mark - Lazy 96 | - (UIImageView *)arrowView{ 97 | if (!_arrowView) { 98 | _arrowView = [[UIImageView alloc] init]; 99 | } 100 | return _arrowView; 101 | } 102 | 103 | - (UILabel *)label{ 104 | if (!_label) { 105 | _label = [[UILabel alloc] init]; 106 | _label.numberOfLines = 0; 107 | } 108 | return _label; 109 | } 110 | 111 | - (void)setIdleTitle:(NSString *)idleTitle{ 112 | _idleTitle = idleTitle; 113 | if (self.state == YJBannerViewStatusIdle) { 114 | self.label.text = idleTitle; 115 | } 116 | } 117 | 118 | - (void)setTriggerTitle:(NSString *)triggerTitle{ 119 | _triggerTitle = triggerTitle; 120 | if (self.state == YJBannerViewStatusTrigger) { 121 | self.label.text = triggerTitle; 122 | } 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/YJBannerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerView.h 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved. 7 | // 8 | 9 | /** 10 | __ __ _ ____ __ ___ 11 | \ \ / / | | __ ) __ _ _ __ _ __ ___ _ __ \ / (_) _____ __ 12 | \ V / | | _ \ / _` | '_ \| '_ \ / _ \ '__\ \ / /| |/ _ \ \ /\ / / 13 | | | |_| | |_) | (_| | | | | | | | __/ | \ V / | | __/\ V V / 14 | |_|\___/|____/ \__,_|_| |_|_| |_|\___|_| \_/ |_|\___| \_/\_/ 15 | 16 | ********* Current-Version : 2.4.0 ************ 17 | 18 | Version record: https://github.com/stackhou/YJBannerViewOC 19 | 20 | */ 21 | 22 | #import 23 | #import "YJBannerViewCollectionView.h" 24 | 25 | /** 指示器位置 */ 26 | typedef NS_ENUM(NSInteger, PageControlAliment) { 27 | PageControlAlimentLeft = 0, // 居左 28 | PageControlAlimentCenter, // 居中 29 | PageControlAlimentRight // 居右 30 | }; 31 | 32 | /** 指示器样式 */ 33 | typedef NS_ENUM(NSInteger, PageControlStyle) { 34 | PageControlNone = 0, // 无 35 | PageControlSystem, // 系统自带 36 | PageControlHollow, // 空心的 37 | PageControlCustom // 自定义 需要图片Dot 38 | }; 39 | 40 | /** 滚动方向 */ 41 | typedef NS_ENUM(NSInteger, BannerViewDirection) { 42 | BannerViewDirectionLeft = 0, // 水平向左 43 | BannerViewDirectionRight, // 水平向右 44 | BannerViewDirectionTop, // 竖直向上 45 | BannerViewDirectionBottom // 竖直向下 46 | }; 47 | 48 | 49 | @class YJBannerView; 50 | @protocol YJBannerViewDataSource, YJBannerViewDelegate; 51 | 52 | @interface YJBannerView : UIView 53 | 54 | @property (nonatomic, strong) UIImageView *backgroundImageView; /**< 数据为空时的背景图 */ 55 | @property (nonatomic, strong, readonly) UICollectionViewFlowLayout *flowLayout; 56 | @property (nonatomic, strong, readonly) YJBannerViewCollectionView *collectionView; 57 | 58 | @property (nonatomic, weak) IBOutlet id dataSource; /**< 数据源代理 */ 59 | @property (nonatomic, weak) IBOutlet id delegate; /**< 代理 */ 60 | 61 | @property (nonatomic, assign) IBInspectable BOOL autoScroll; /**< 是否自动 默认YES */ 62 | 63 | @property (nonatomic, assign) IBInspectable CGFloat autoDuration; /**< 自动滚动时间间隔 默认3s */ 64 | 65 | @property (nonatomic, assign) IBInspectable BOOL cycleScrollEnable; /**< 是否首尾循环 默认是YES */ 66 | 67 | @property (nonatomic, assign) BannerViewDirection bannerViewScrollDirection; /**< 滚动方向 默认水平向左 */ 68 | 69 | @property (nonatomic, assign) BOOL bannerGestureEnable; /**< 手势是否可用 默认可用YES */ 70 | 71 | @property (nonatomic, assign) IBInspectable BOOL showFooter; /**< 显示footerView 默认是 NO 设置为YES 后将 autoScroll和cycleScrollEnable 自动置为NO 只支持水平向左 */ 72 | @property (nonatomic, assign) NSInteger repeatCount; /**< 数据源重复次数 默认是200 若循环必须大于2的偶数 */ 73 | 74 | @property (nonatomic, strong) UIImage *placeholderImage; /**< 默认图片 */ 75 | @property (nonatomic, strong) UIImage *emptyImage; /**< 空数据图片 */ 76 | 77 | @property (nonatomic, copy) NSString *bannerViewSelectorString; /**< 自定义设置网络和默认图片的方法 */ 78 | 79 | @property (nonatomic, assign) UIViewContentMode bannerImageViewContentMode; /**< 填充样式 默认UIViewContentModeScaleAspectFill */ 80 | 81 | @property (nonatomic, assign) PageControlAliment pageControlAliment; /**< 指示器的位置 默认是Center */ 82 | 83 | @property (nonatomic, assign) PageControlStyle pageControlStyle; /**< 指示器样式 默认System */ 84 | 85 | @property (nonatomic, assign) CGFloat pageControlBottomMargin; /**< 指示器距离底部的间距 默认10 */ 86 | 87 | @property (nonatomic, assign) CGFloat pageControlHorizontalEdgeMargin; /**< 指示器水平方向上的边缘间距 默认10 */ 88 | 89 | @property (nonatomic, assign) CGFloat pageControlPadding; /**< 指示器水平方向上间距 默认 5 系统样式无效 */ 90 | 91 | @property (nonatomic, assign) CGSize pageControlDotSize; /**< 指示器圆标大小 默认 8*8*/ 92 | 93 | @property (nonatomic, strong) UIColor *pageControlNormalColor; /**< 指示器正常颜色 */ 94 | 95 | @property (nonatomic, strong) UIColor *pageControlHighlightColor; /**< 指示器小圆标颜色 */ 96 | 97 | @property (nonatomic, strong) UIImage *customPageControlNormalImage; /**< 指示器小圆点正常的图片 */ 98 | 99 | @property (nonatomic, strong) UIImage *customPageControlHighlightImage; /**< 当前分页控件图片 */ 100 | 101 | @property (nonatomic, strong) UIFont *titleFont; /**< 文字大小 默认14.0f */ 102 | 103 | @property (nonatomic, strong) UIColor *titleTextColor; /**< 文字颜色 默认 whiteColor */ 104 | 105 | @property (nonatomic, assign) NSTextAlignment titleAlignment; /**< 文字对齐方式 默认 Left */ 106 | 107 | @property (nonatomic, strong) UIColor *titleBackgroundColor; /**< 文字背景颜色 默认 黑0.5 */ 108 | 109 | @property (nonatomic, assign) CGFloat titleHeight; /**< 文字高度 默认30 */ 110 | 111 | @property (nonatomic, assign) CGFloat titleEdgeMargin; /**< 文字边缘间距 默认是10 */ 112 | 113 | @property (nonatomic, copy) NSString *footerIndicateImageName; /**< footer 指示图片名字 默认是自带的 */ 114 | 115 | @property (nonatomic, copy) NSString *footerNormalTitle; /**< footer 常态Title 默认 "拖动查看详情" */ 116 | 117 | @property (nonatomic, copy) NSString *footerTriggerTitle; /**< footer Trigger Title 默认 "释放查看详情" */ 118 | 119 | @property (nonatomic, strong) UIFont *footerTitleFont; /**< footer Font 默认 12 */ 120 | 121 | @property (nonatomic, strong) UIColor *footerTitleColor; /**< footer TitleColoe 默认是 darkGrayColor */ 122 | 123 | @property (nonatomic, copy) void(^didScroll2IndexBlock)(NSInteger index); 124 | @property (nonatomic, copy) void(^didSelectItemAtIndexBlock)(NSInteger index); 125 | @property (nonatomic, copy) void(^didEndTriggerFooterBlock)(); 126 | 127 | /** 128 | 创建bannerView实例的方法 129 | 130 | @param frame bannerView的Frame 131 | @param dataSource 数据源代理 132 | @param delegate 普通代理 133 | @param emptyImage 空数据图片 134 | @param placeholderImage 默认图片 135 | @param selectorString 必须是 UIImageView 设置图片和placeholderImage的方法 如: @"sd_setImageWithURL:placeholderImage:", 分别接收NSURL和UIImage两个参数 136 | @return YJBannerView 实例 137 | */ 138 | + (YJBannerView *)bannerViewWithFrame:(CGRect)frame 139 | dataSource:(id)dataSource 140 | delegate:(id)delegate 141 | emptyImage:(UIImage *)emptyImage 142 | placeholderImage:(UIImage *)placeholderImage 143 | selectorString:(NSString *)selectorString; 144 | 145 | /** 刷新BannerView数据 */ 146 | - (void)reloadData; 147 | 148 | /** 停止定时器接口 */ 149 | - (void)invalidateTimerWhenAutoScroll; 150 | 151 | /** 重新开启定时器 */ 152 | - (void)startTimerWhenAutoScroll; 153 | 154 | /** 调整滚动到指定位置 */ 155 | - (void)adjustBannerViewScrollToIndex:(NSInteger)index animated:(BOOL)animated; 156 | 157 | /** 如果卡屏请在控制器 viewWillAppear 内调用此方法 */ 158 | - (void)adjustBannerViewWhenCardScreen; 159 | 160 | @end 161 | 162 | #pragma mark - 协议部分 163 | @protocol YJBannerViewDataSource 164 | 165 | @required 166 | /** 167 | 显示Banner数据源代理方法 168 | 169 | @param bannerView 当前Banner 170 | @return 兼容 http(s):// 和 本地图片Name 类型: NSString 数组 171 | */ 172 | - (NSArray *)bannerViewImages:(YJBannerView *)bannerView; 173 | 174 | @optional 175 | /** 文字数据源 */ 176 | - (NSArray *)bannerViewTitles:(YJBannerView *)bannerView; 177 | 178 | /** 179 | 自定义 View 要同时配合实现以下3个方法 180 | 181 | @param bannerView 当前的Banner 182 | @return 需要注册的自定义View类的集合. e.g.: @[[CustomViewA class], [CustomViewB class]] 183 | */ 184 | - (NSArray *)bannerViewRegistCustomCellClass:(YJBannerView *)bannerView; 185 | /** 根据 Index 选择使用哪个 reuseIdentifier */ 186 | - (Class)bannerView:(YJBannerView *)bannerView reuseIdentifierForIndex:(NSInteger)index; 187 | /** 自定义 View 刷新数据或者其他配置 */ 188 | - (UICollectionViewCell *)bannerView:(YJBannerView *)bannerView customCell:(UICollectionViewCell *)customCell index:(NSInteger)index; 189 | 190 | /** Footer 高度 默认是 49.0 */ 191 | - (CGFloat)bannerViewFooterViewHeight:(YJBannerView *)bannerView; 192 | 193 | @end 194 | 195 | @protocol YJBannerViewDelegate 196 | 197 | @optional 198 | /** 正在滚动的位置及偏移量 */ 199 | - (void)bannerView:(YJBannerView *)bannerView didScrollCurrentIndex:(NSInteger)currentIndex contentOffset:(CGFloat)contentOffset; 200 | 201 | /** 滚动到 index */ 202 | - (void)bannerView:(YJBannerView *)bannerView didScroll2Index:(NSInteger)index; 203 | 204 | /** 点击回调 */ 205 | - (void)bannerView:(YJBannerView *)bannerView didSelectItemAtIndex:(NSInteger)index; 206 | 207 | /** BannerView Footer 回调 */ 208 | - (void)bannerViewFooterDidEndTrigger:(YJBannerView *)bannerView; 209 | 210 | @end 211 | 212 | -------------------------------------------------------------------------------- /Pods/YJBannerView/YJBannerViewDemo/YJBannerView/YJBannerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // YJBannerView.m 3 | // YJBannerViewDemo 4 | // 5 | // Created by YJHou on 2015/5/24. 6 | // Copyright © 2015年 Address:https://github.com/stackhou/YJBannerViewOC . All rights reserved. 7 | // 8 | 9 | /** 10 | __ __ _ ____ __ ___ 11 | \ \ / / | | __ ) __ _ _ __ _ __ ___ _ __ \ / (_) _____ __ 12 | \ V / | | _ \ / _` | '_ \| '_ \ / _ \ '__\ \ / /| |/ _ \ \ /\ / / 13 | | | |_| | |_) | (_| | | | | | | | __/ | \ V / | | __/\ V V / 14 | |_|\___/|____/ \__,_|_| |_|_| |_|\___|_| \_/ |_|\___| \_/\_/ 15 | 16 | */ 17 | 18 | #import "YJBannerView.h" 19 | #import "YJBannerViewCell.h" 20 | #import "UIView+YJBannerViewExt.h" 21 | #import "YJHollowPageControl.h" 22 | #import "YJBannerViewFooter.h" 23 | 24 | static NSString *const bannerViewCellId = @"YJBannerView"; 25 | static NSString *const bannerViewFooterId = @"YJBannerViewFooter"; 26 | static NSInteger const totalCollectionViewCellCount = 200; 27 | #define kPageControlDotDefaultSize CGSizeMake(8, 8) 28 | #define BANNER_FOOTER_HEIGHT 49.0 29 | 30 | @interface YJBannerView () { 31 | YJBannerViewCollectionView *_collectionView; 32 | UICollectionViewFlowLayout *_flowLayout; 33 | } 34 | 35 | @property (nonatomic, weak) UIControl *pageControl; 36 | @property (nonatomic, weak) NSTimer *timer; 37 | @property (nonatomic, assign) NSInteger totalBannerItemsCount; 38 | @property (nonatomic, strong) NSArray *saveScrollViewGestures; 39 | @property (nonatomic, strong) YJBannerViewFooter *bannerFooter; 40 | @property (nonatomic, strong) NSArray *showNewDatasource; 41 | @property (nonatomic, assign) CGFloat lastContentOffset; 42 | 43 | @end 44 | 45 | @implementation YJBannerView 46 | @synthesize autoScroll = _autoScroll; 47 | @synthesize cycleScrollEnable = _cycleScrollEnable; 48 | @synthesize bannerImageViewContentMode = _bannerImageViewContentMode; 49 | @synthesize pageControlNormalColor = _pageControlNormalColor; 50 | @synthesize pageControlHighlightColor = _pageControlHighlightColor; 51 | 52 | #pragma mark - Public API 53 | + (YJBannerView *)bannerViewWithFrame:(CGRect)frame 54 | dataSource:(id)dataSource 55 | delegate:(id)delegate 56 | emptyImage:(UIImage *)emptyImage 57 | placeholderImage:(UIImage *)placeholderImage 58 | selectorString:(NSString *)selectorString{ 59 | 60 | YJBannerView *bannerView = [[YJBannerView alloc] initWithFrame:frame]; 61 | bannerView.dataSource = dataSource; 62 | bannerView.delegate = delegate; 63 | bannerView.bannerViewSelectorString = selectorString; 64 | bannerView.emptyImage = emptyImage; 65 | bannerView.placeholderImage = placeholderImage; 66 | 67 | return bannerView; 68 | } 69 | 70 | - (void)reloadData{ 71 | 72 | [self invalidateTimer]; 73 | self.showNewDatasource = [self _getImageDataSources]; 74 | 75 | // Hidden when data source is greater than zero 76 | self.backgroundImageView.hidden = ([self _imageDataSources].count > 0); 77 | 78 | if ([self _imageDataSources].count > 1) { 79 | self.collectionView.scrollEnabled = YES; 80 | [self setAutoScroll:self.autoScroll]; 81 | } else { 82 | 83 | if ([self _imageDataSources].count == 0) { self.showFooter = NO; } 84 | 85 | BOOL isCan = ([self _imageDataSources].count == 0)?NO:(self.showFooter?YES:NO); 86 | 87 | self.collectionView.scrollEnabled = isCan; 88 | 89 | [self invalidateTimerWhenAutoScroll]; 90 | } 91 | 92 | [self _setFooterViewCanShow:self.showFooter]; 93 | [self _setupPageControl]; 94 | 95 | // Regist Custom Cell 96 | if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewRegistCustomCellClass:)] && [self.dataSource bannerViewRegistCustomCellClass:self]) { 97 | NSArray *clazzs = [self.dataSource bannerViewRegistCustomCellClass:self]; 98 | for (Class clazz in clazzs) { 99 | [self.collectionView registerClass:clazz forCellWithReuseIdentifier:NSStringFromClass(clazz)]; 100 | } 101 | } 102 | 103 | [self.collectionView reloadData]; 104 | } 105 | 106 | - (instancetype)initWithFrame:(CGRect)frame{ 107 | self = [super initWithFrame:frame]; 108 | if (self) { 109 | [self _initSetting]; 110 | [self addSubview:self.collectionView]; 111 | } 112 | return self; 113 | } 114 | 115 | - (id)initWithCoder:(NSCoder *)aDecoder{ 116 | if (self = [super initWithCoder:aDecoder]) { 117 | [self _initSetting]; 118 | [self addSubview:self.collectionView]; 119 | } 120 | return self; 121 | } 122 | 123 | - (void)awakeFromNib{ 124 | [super awakeFromNib]; 125 | [self _initSetting]; 126 | [self addSubview:self.collectionView]; 127 | } 128 | 129 | /** Initialize the default settings */ 130 | - (void)_initSetting{ 131 | 132 | self.backgroundColor = [UIColor whiteColor]; 133 | _autoDuration = 3.0; 134 | _autoScroll = YES; 135 | _pageControlStyle = PageControlSystem; 136 | _pageControlAliment = PageControlAlimentCenter; 137 | _pageControlDotSize = kPageControlDotDefaultSize; 138 | _pageControlBottomMargin = 10.0f; 139 | _pageControlHorizontalEdgeMargin = 10.0f; 140 | _pageControlPadding = 5.0f; 141 | 142 | _titleHeight = 30.0f; 143 | _titleEdgeMargin = 10.0f; 144 | _titleAlignment = NSTextAlignmentLeft; 145 | _bannerGestureEnable = YES; 146 | _cycleScrollEnable = YES; 147 | 148 | _showFooter = NO; 149 | _footerIndicateImageName = @"YJBannerView.bundle/yjbanner_arrow.png"; 150 | _footerNormalTitle = @"拖动查看详情"; 151 | _footerTriggerTitle = @"释放查看详情"; 152 | } 153 | 154 | #pragma mark - Setter && Getter 155 | - (void)setEmptyImage:(UIImage *)emptyImage{ 156 | _emptyImage = emptyImage; 157 | if (emptyImage) { 158 | self.backgroundImageView.image = emptyImage; 159 | } 160 | } 161 | 162 | - (void)setPageControlDotSize:(CGSize)pageControlDotSize{ 163 | 164 | _pageControlDotSize = pageControlDotSize; 165 | 166 | [self _setupPageControl]; 167 | if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) { 168 | YJHollowPageControl *pageContol = (YJHollowPageControl *)_pageControl; 169 | pageContol.dotSize = pageControlDotSize; 170 | } 171 | } 172 | 173 | - (void)setPageControlStyle:(PageControlStyle)pageControlStyle{ 174 | 175 | _pageControlStyle = pageControlStyle; 176 | 177 | [self _setupPageControl]; 178 | } 179 | 180 | - (void)setPageControlNormalColor:(UIColor *)pageControlNormalColor{ 181 | 182 | _pageControlNormalColor = pageControlNormalColor; 183 | 184 | if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) { 185 | YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl; 186 | pageControl.dotNormalColor = pageControlNormalColor; 187 | }else if ([self.pageControl isKindOfClass:[UIPageControl class]]) { 188 | UIPageControl *pageControl = (UIPageControl *)_pageControl; 189 | pageControl.pageIndicatorTintColor = pageControlNormalColor; 190 | } 191 | } 192 | 193 | - (void)setPageControlHighlightColor:(UIColor *)pageControlHighlightColor{ 194 | 195 | _pageControlHighlightColor = pageControlHighlightColor; 196 | 197 | if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) { 198 | YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl; 199 | pageControl.dotCurrentColor = pageControlHighlightColor; 200 | } else if ([self.pageControl isKindOfClass:[UIPageControl class]]){ 201 | UIPageControl *pageControl = (UIPageControl *)_pageControl; 202 | pageControl.currentPageIndicatorTintColor = pageControlHighlightColor; 203 | } 204 | } 205 | 206 | - (void)setCustomPageControlNormalImage:(UIImage *)customPageControlNormalImage{ 207 | _customPageControlNormalImage = customPageControlNormalImage; 208 | [self setCustomPageControlDotImage:customPageControlNormalImage isCurrentPageDot:NO]; 209 | } 210 | 211 | - (void)setCustomPageControlHighlightImage:(UIImage *)customPageControlHighlightImage{ 212 | _customPageControlHighlightImage = customPageControlHighlightImage; 213 | [self setCustomPageControlDotImage:customPageControlHighlightImage isCurrentPageDot:YES]; 214 | } 215 | 216 | - (void)setCustomPageControlDotImage:(UIImage *)image isCurrentPageDot:(BOOL)isCurrentPageDot{ 217 | 218 | if (!image || !self.pageControl) return; 219 | 220 | if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) { 221 | YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl; 222 | if (isCurrentPageDot) { 223 | pageControl.dotCurrentImage = image; 224 | } else { 225 | pageControl.dotNormalImage = image; 226 | } 227 | } 228 | } 229 | 230 | - (void)setAutoScroll:(BOOL)autoScroll{ 231 | 232 | _autoScroll = autoScroll; 233 | [self invalidateTimer]; 234 | if (autoScroll) { 235 | [self _setupTimer]; 236 | } 237 | } 238 | 239 | - (void)setBannerViewScrollDirection:(BannerViewDirection)bannerViewScrollDirection{ 240 | 241 | if (self.showFooter && bannerViewScrollDirection != BannerViewDirectionLeft) { 242 | bannerViewScrollDirection = BannerViewDirectionLeft; 243 | } 244 | 245 | _bannerViewScrollDirection = bannerViewScrollDirection; 246 | 247 | if (bannerViewScrollDirection == BannerViewDirectionLeft || bannerViewScrollDirection == BannerViewDirectionRight) { 248 | self.flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 249 | }else if (bannerViewScrollDirection == BannerViewDirectionTop || bannerViewScrollDirection == BannerViewDirectionBottom){ 250 | self.flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; 251 | } 252 | } 253 | 254 | - (void)setAutoDuration:(CGFloat)autoDuration{ 255 | 256 | _autoDuration = autoDuration; 257 | [self setAutoScroll:self.autoScroll]; 258 | } 259 | 260 | - (void)setBannerGestureEnable:(BOOL)bannerGestureEnable{ 261 | if (_bannerGestureEnable && bannerGestureEnable) { // 不操作 262 | }else if (!_bannerGestureEnable && bannerGestureEnable){ 263 | self.collectionView.canCancelContentTouches = YES; 264 | for (NSInteger i = 0; i < self.saveScrollViewGestures.count; i++) { 265 | UIGestureRecognizer *gesture = self.saveScrollViewGestures[i]; 266 | if (![self.collectionView.gestureRecognizers containsObject:gesture]) { 267 | [self.collectionView addGestureRecognizer:gesture]; 268 | } 269 | } 270 | }else if (_bannerGestureEnable && !bannerGestureEnable){ 271 | self.collectionView.canCancelContentTouches = NO; 272 | for (UIGestureRecognizer *gesture in self.collectionView.gestureRecognizers) { 273 | if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) { 274 | [self.collectionView removeGestureRecognizer:gesture]; 275 | } 276 | } 277 | } 278 | _bannerGestureEnable = bannerGestureEnable; 279 | } 280 | 281 | - (void)setBannerImageViewContentMode:(UIViewContentMode)bannerImageViewContentMode{ 282 | _bannerImageViewContentMode = bannerImageViewContentMode; 283 | self.backgroundImageView.contentMode = bannerImageViewContentMode; 284 | } 285 | 286 | - (NSInteger)repeatCount{ 287 | if (_repeatCount <= 0) { 288 | return totalCollectionViewCellCount; 289 | }else{ 290 | if (_repeatCount % 2 != 0) { 291 | return _repeatCount + 1; 292 | }else{ 293 | return _repeatCount; 294 | } 295 | } 296 | } 297 | 298 | #pragma mark - Getter 299 | - (NSInteger)totalBannerItemsCount{ 300 | 301 | return self.cycleScrollEnable?(([self _imageDataSources].count > 1)?([self _imageDataSources].count * self.repeatCount):[self _imageDataSources].count):([self _imageDataSources].count); 302 | } 303 | 304 | - (BOOL)autoScroll{ 305 | if (self.showFooter) { 306 | return NO; 307 | } 308 | return _autoScroll; 309 | } 310 | 311 | - (BOOL)cycleScrollEnable{ 312 | if (self.showFooter) { 313 | return NO; 314 | } 315 | return _cycleScrollEnable; 316 | } 317 | 318 | - (UIFont *)titleFont{ 319 | if (!_titleFont) { 320 | _titleFont = [UIFont systemFontOfSize:14.0f]; 321 | } 322 | return _titleFont; 323 | } 324 | 325 | - (UIColor *)titleTextColor{ 326 | if (!_titleTextColor) { 327 | _titleTextColor = [UIColor whiteColor]; 328 | } 329 | return _titleTextColor; 330 | } 331 | 332 | - (UIColor *)titleBackgroundColor{ 333 | if (!_titleBackgroundColor) { 334 | _titleBackgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]; 335 | } 336 | return _titleBackgroundColor; 337 | } 338 | 339 | - (UIFont *)footerTitleFont{ 340 | if (!_footerTitleFont) { 341 | _footerTitleFont = [UIFont systemFontOfSize:12.0f]; 342 | } 343 | return _footerTitleFont; 344 | } 345 | 346 | - (UIColor *)footerTitleColor{ 347 | if (!_footerTitleColor) { 348 | _footerTitleColor = [UIColor darkGrayColor]; 349 | } 350 | return _footerTitleColor; 351 | } 352 | 353 | - (UIViewContentMode)bannerImageViewContentMode{ 354 | if (!_bannerImageViewContentMode) { 355 | _bannerImageViewContentMode = UIViewContentModeScaleAspectFill; 356 | } 357 | return _bannerImageViewContentMode; 358 | } 359 | 360 | - (UIColor *)pageControlNormalColor{ 361 | if (!_pageControlNormalColor) { 362 | _pageControlNormalColor = [UIColor lightGrayColor]; 363 | } 364 | return _pageControlNormalColor; 365 | } 366 | 367 | - (UIColor *)pageControlHighlightColor{ 368 | if (!_pageControlHighlightColor) { 369 | _pageControlHighlightColor = [UIColor whiteColor]; 370 | } 371 | return _pageControlHighlightColor; 372 | } 373 | 374 | - (NSArray *)saveScrollViewGestures{ 375 | if (!_saveScrollViewGestures) { 376 | _saveScrollViewGestures = [self.collectionView.gestureRecognizers copy]; 377 | } 378 | return _saveScrollViewGestures; 379 | } 380 | 381 | #pragma mark - layoutSubviews 382 | - (void)layoutSubviews{ 383 | [super layoutSubviews]; 384 | 385 | self.dataSource = self.dataSource; 386 | [super layoutSubviews]; 387 | 388 | self.flowLayout.itemSize = self.frame.size; 389 | 390 | self.collectionView.frame = self.bounds; 391 | 392 | if (self.collectionView.contentOffset.x == 0 && self.totalBannerItemsCount) { 393 | NSInteger targetIndex = self.cycleScrollEnable?(self.totalBannerItemsCount * 0.5):(0); 394 | [self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO]; 395 | } 396 | 397 | CGSize size = CGSizeZero; 398 | 399 | if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) { 400 | 401 | YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl; 402 | 403 | if (!(self.customPageControlNormalImage && self.customPageControlHighlightImage && CGSizeEqualToSize(kPageControlDotDefaultSize, self.pageControlDotSize))) { 404 | pageControl.dotSize = self.pageControlDotSize; 405 | } 406 | 407 | size = [pageControl sizeForNumberOfPages:[self _imageDataSources].count]; 408 | } else { 409 | size = CGSizeMake([self _imageDataSources].count * self.pageControlDotSize.width * 1.5, self.pageControlDotSize.height); 410 | } 411 | CGFloat x = (self.width_bannerView - size.width) * 0.5; 412 | if (self.pageControlAliment == PageControlAlimentLeft) { 413 | x = 0.0f; 414 | }else if (self.pageControlAliment == PageControlAlimentCenter){ 415 | }else if (self.pageControlAliment == PageControlAlimentRight){ 416 | x = self.collectionView.width_bannerView - size.width; 417 | } 418 | 419 | CGFloat y = self.collectionView.height_bannerView - size.height; 420 | 421 | if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) { 422 | 423 | YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl; 424 | [pageControl sizeToFit]; 425 | } 426 | 427 | CGRect pageControlFrame = CGRectMake(x, y, size.width, size.height); 428 | if (self.pageControlAliment == PageControlAlimentLeft) { 429 | pageControlFrame.origin.x += self.pageControlHorizontalEdgeMargin; 430 | }else if (self.pageControlAliment == PageControlAlimentRight){ 431 | pageControlFrame.origin.x -= self.pageControlHorizontalEdgeMargin; 432 | } 433 | pageControlFrame.origin.y -= self.pageControlBottomMargin; 434 | self.pageControl.frame = pageControlFrame; 435 | 436 | self.pageControl.hidden = self.pageControlStyle == PageControlNone; 437 | 438 | if (self.backgroundImageView) { 439 | self.backgroundImageView.frame = self.bounds; 440 | } 441 | } 442 | 443 | #pragma mark - Resolve compatibility optimization issues 444 | - (void)willMoveToSuperview:(UIView *)newSuperview{ 445 | if (!newSuperview) { 446 | [self invalidateTimer]; 447 | } 448 | } 449 | 450 | - (void)adjustBannerViewScrollToIndex:(NSInteger)index animated:(BOOL)animated{ 451 | 452 | if (self.showNewDatasource.count == 0) { return; } 453 | if (index >= 0 && index < self.showNewDatasource.count) { 454 | if (self.autoScroll) { [self invalidateTimer]; } 455 | 456 | [self _scrollToIndex:((int)(self.totalBannerItemsCount * 0.5 + index)) animated:animated]; 457 | 458 | if (self.autoScroll) { [self _setupTimer]; } 459 | } 460 | } 461 | 462 | - (void)adjustBannerViewWhenCardScreen{ 463 | 464 | long targetIndex = [self _currentPageIndex]; 465 | if (targetIndex < self.totalBannerItemsCount) { 466 | [self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO]; 467 | } 468 | } 469 | 470 | #pragma mark - UICollectionViewDataSource 471 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ 472 | return self.totalBannerItemsCount; 473 | } 474 | 475 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 476 | 477 | YJBannerViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:bannerViewCellId forIndexPath:indexPath]; 478 | long itemIndex = [self _getRealIndexFromCurrentCellIndex:indexPath.item]; 479 | 480 | // Custom Cell 481 | if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewRegistCustomCellClass:)] && [self.dataSource bannerViewRegistCustomCellClass:self] && [self.dataSource respondsToSelector:@selector(bannerView:customCell:index:)] && [self.dataSource respondsToSelector:@selector(bannerView:reuseIdentifierForIndex:)]) { 482 | 483 | NSString *reuseIdentifier = NSStringFromClass([self.dataSource bannerView:self reuseIdentifierForIndex:itemIndex]); 484 | if (reuseIdentifier.length > 0) { 485 | UICollectionViewCell *customCell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 486 | 487 | if ([self.dataSource bannerView:self customCell:customCell index:itemIndex]) { 488 | return customCell; 489 | } 490 | } 491 | } 492 | 493 | NSString *imagePath = (itemIndex < [self _imageDataSources].count)?[self _imageDataSources][itemIndex]:nil; 494 | NSString *title = (itemIndex < [self _titlesDataSources].count)?[self _titlesDataSources][itemIndex]:nil; 495 | 496 | if (!cell.isConfigured) { 497 | cell.titleLabelBackgroundColor = self.titleBackgroundColor; 498 | cell.titleLabelHeight = self.titleHeight; 499 | cell.titleLabelEdgeMargin = self.titleEdgeMargin; 500 | cell.titleLabelTextAlignment = self.titleAlignment; 501 | cell.titleLabelTextColor = self.titleTextColor; 502 | cell.titleLabelTextFont = self.titleFont; 503 | cell.showImageViewContentMode = self.bannerImageViewContentMode; 504 | cell.clipsToBounds = YES; 505 | cell.isConfigured = YES; 506 | } 507 | 508 | [cell cellWithSelectorString:self.bannerViewSelectorString imagePath:imagePath placeholderImage:self.placeholderImage title:title]; 509 | 510 | return cell; 511 | } 512 | 513 | // Setting Footer Size 514 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{ 515 | return CGSizeMake((self.showFooter && [self _imageDataSources].count != 0)?[self _bannerViewFooterHeight]:0.0f, self.frame.size.height); 516 | } 517 | 518 | // Footer 519 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ 520 | 521 | if(kind == UICollectionElementKindSectionFooter){ 522 | 523 | YJBannerViewFooter *footer = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:bannerViewFooterId forIndexPath:indexPath]; 524 | self.bannerFooter = footer; 525 | 526 | footer.IndicateImageName = self.footerIndicateImageName; 527 | footer.footerTitleFont = self.footerTitleFont; 528 | footer.footerTitleColor = self.footerTitleColor; 529 | footer.idleTitle = self.footerNormalTitle; 530 | footer.triggerTitle = self.footerTriggerTitle; 531 | 532 | footer.hidden = !(self.showFooter && [self _imageDataSources].count != 0); 533 | 534 | return footer; 535 | } 536 | return nil; 537 | } 538 | 539 | #pragma mark - UIScrollViewDelegate 540 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ 541 | if (self.delegate && [self.delegate respondsToSelector:@selector(bannerView:didSelectItemAtIndex:)]) { 542 | [self.delegate bannerView:self didSelectItemAtIndex:[self _getRealIndexFromCurrentCellIndex:indexPath.item]]; 543 | } 544 | if (self.didSelectItemAtIndexBlock) { 545 | self.didSelectItemAtIndexBlock([self _getRealIndexFromCurrentCellIndex:indexPath.item]); 546 | } 547 | } 548 | 549 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ 550 | 551 | if (![self _imageDataSources].count) return; 552 | int itemIndex = [self _currentPageIndex]; 553 | int indexOnPageControl = [self _getRealIndexFromCurrentCellIndex:itemIndex]; 554 | 555 | // 手动退拽时左右两端 556 | if (scrollView == self.collectionView && scrollView.isDragging && self.cycleScrollEnable) { 557 | NSInteger targetIndex = self.totalBannerItemsCount * 0.5; 558 | if (itemIndex == 0) { // top 559 | [self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO]; 560 | }else if (itemIndex == (self.totalBannerItemsCount - 1)){ // bottom 561 | targetIndex -= 1; 562 | [self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO]; 563 | } 564 | } 565 | 566 | // pageControl 567 | if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) { 568 | YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl; 569 | pageControl.currentPage = indexOnPageControl; 570 | } else { 571 | UIPageControl *pageControl = (UIPageControl *)_pageControl; 572 | pageControl.currentPage = indexOnPageControl; 573 | } 574 | 575 | // Footer 576 | if (self.showFooter) { 577 | static CGFloat lastOffset; 578 | CGFloat footerDisplayOffset = (self.collectionView.contentOffset.x - (self.flowLayout.itemSize.width * (self.totalBannerItemsCount - 1))); 579 | 580 | if (footerDisplayOffset > 0){ 581 | if (footerDisplayOffset > [self _bannerViewFooterHeight]) { 582 | if (lastOffset > 0) return; 583 | self.bannerFooter.state = YJBannerViewStatusTrigger; 584 | } else { 585 | if (lastOffset < 0) return; 586 | self.bannerFooter.state = YJBannerViewStatusIdle; 587 | } 588 | lastOffset = footerDisplayOffset - [self _bannerViewFooterHeight]; 589 | } 590 | } 591 | 592 | // contentOffset 593 | [self _saveInitializationContentOffsetJudgeZero:YES]; 594 | CGFloat contentOffset = 0.0f; 595 | if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) { 596 | contentOffset = self.collectionView.contentOffset.x; 597 | } else { 598 | contentOffset = self.collectionView.contentOffset.y; 599 | } 600 | CGFloat distance = fabs(self.lastContentOffset - contentOffset); 601 | 602 | if (self.delegate && [self.delegate respondsToSelector:@selector(bannerView:didScrollCurrentIndex:contentOffset:)]) { 603 | [self.delegate bannerView:self didScrollCurrentIndex:indexOnPageControl contentOffset:distance]; 604 | } 605 | } 606 | 607 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ 608 | [self invalidateTimerWhenAutoScroll]; 609 | } 610 | 611 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 612 | 613 | [self startTimerWhenAutoScroll]; 614 | 615 | if (self.showFooter) { 616 | CGFloat footerDisplayOffset = (self.collectionView.contentOffset.x - (self.flowLayout.itemSize.width * (self.totalBannerItemsCount - 1))); 617 | 618 | if (footerDisplayOffset > [self _bannerViewFooterHeight]) { 619 | if (self.delegate && [self.delegate respondsToSelector:@selector(bannerViewFooterDidEndTrigger:)]) { 620 | [self.delegate bannerViewFooterDidEndTrigger:self]; 621 | } 622 | 623 | if (self.didEndTriggerFooterBlock) { 624 | self.didEndTriggerFooterBlock(); 625 | } 626 | } 627 | } 628 | } 629 | 630 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ 631 | [self scrollViewDidEndScrollingAnimation:self.collectionView]; 632 | } 633 | 634 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{ 635 | if (![self _imageDataSources].count) return; 636 | int itemIndex = [self _currentPageIndex]; 637 | int indexOnPageControl = [self _getRealIndexFromCurrentCellIndex:itemIndex]; 638 | 639 | if (self.delegate && [self.delegate respondsToSelector:@selector(bannerView:didScroll2Index:)]) { 640 | [self.delegate bannerView:self didScroll2Index:indexOnPageControl]; 641 | } 642 | if (self.didScroll2IndexBlock) { 643 | self.didScroll2IndexBlock(indexOnPageControl); 644 | } 645 | 646 | [self _saveInitializationContentOffsetJudgeZero:NO]; 647 | } 648 | 649 | #pragma mark - Private function method 650 | /** install PageControl */ 651 | - (void)_setupPageControl{ 652 | 653 | if (_pageControl) [_pageControl removeFromSuperview]; 654 | 655 | if ([self _imageDataSources].count == 0) {return;} 656 | 657 | if ([self _imageDataSources].count == 1) {return;} 658 | 659 | int indexOnPageControl = [self _getRealIndexFromCurrentCellIndex:[self _currentPageIndex]]; 660 | 661 | switch (self.pageControlStyle) { 662 | case PageControlNone:{ 663 | break; 664 | } 665 | case PageControlSystem:{ 666 | UIPageControl *pageControl = [[UIPageControl alloc] init]; 667 | pageControl.numberOfPages = [self _imageDataSources].count; 668 | pageControl.currentPageIndicatorTintColor = self.pageControlHighlightColor; 669 | pageControl.pageIndicatorTintColor = self.pageControlNormalColor; 670 | pageControl.userInteractionEnabled = NO; 671 | pageControl.currentPage = indexOnPageControl; 672 | [self addSubview:pageControl]; 673 | _pageControl = pageControl; 674 | break; 675 | } 676 | case PageControlHollow:{ 677 | YJHollowPageControl *pageControl = [[YJHollowPageControl alloc] init]; 678 | pageControl.numberOfPages = [self _imageDataSources].count; 679 | pageControl.dotNormalColor = self.pageControlNormalColor; 680 | pageControl.dotCurrentColor = self.pageControlHighlightColor; 681 | pageControl.userInteractionEnabled = NO; 682 | pageControl.resizeScale = 1.0; 683 | pageControl.spacing = self.pageControlPadding; 684 | pageControl.currentPage = indexOnPageControl; 685 | [self addSubview:pageControl]; 686 | _pageControl = pageControl; 687 | break; 688 | } 689 | case PageControlCustom:{ 690 | 691 | YJHollowPageControl *pageControl = [[YJHollowPageControl alloc] init]; 692 | pageControl.numberOfPages = [self _imageDataSources].count; 693 | pageControl.dotNormalColor = self.pageControlNormalColor; 694 | pageControl.dotCurrentColor = self.pageControlHighlightColor; 695 | pageControl.userInteractionEnabled = NO; 696 | pageControl.resizeScale = 1.0; 697 | pageControl.spacing = self.pageControlPadding; 698 | pageControl.currentPage = indexOnPageControl; 699 | [self addSubview:pageControl]; 700 | _pageControl = pageControl; 701 | 702 | if (self.customPageControlNormalImage) { 703 | self.customPageControlNormalImage = self.customPageControlNormalImage; 704 | } 705 | 706 | if (self.customPageControlHighlightImage) { 707 | self.customPageControlHighlightImage = self.customPageControlHighlightImage; 708 | } 709 | } 710 | default: 711 | break; 712 | } 713 | } 714 | 715 | /** install Timer */ 716 | - (void)_setupTimer{ 717 | 718 | [self invalidateTimer]; 719 | NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:self.autoDuration target:self selector:@selector(_automaticScrollAction) userInfo:nil repeats:YES]; 720 | _timer = timer; 721 | [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 722 | } 723 | 724 | /** stop timer */ 725 | - (void)invalidateTimer{ 726 | 727 | [_timer invalidate]; 728 | _timer = nil; 729 | } 730 | 731 | /** stop timer api */ 732 | - (void)invalidateTimerWhenAutoScroll{ 733 | if (self.autoScroll) { 734 | [self invalidateTimer]; 735 | } 736 | } 737 | 738 | /** restart timer api */ 739 | - (void)startTimerWhenAutoScroll{ 740 | if (self.autoScroll) { 741 | [self _setupTimer]; 742 | } 743 | } 744 | 745 | - (void)_automaticScrollAction{ 746 | 747 | if (self.totalBannerItemsCount == 0) return; 748 | int currentIndex = [self _currentPageIndex]; 749 | if (self.bannerViewScrollDirection == BannerViewDirectionLeft || self.bannerViewScrollDirection == BannerViewDirectionTop) { 750 | [self _scrollToIndex:(currentIndex + 1) animated:YES]; 751 | }else if (self.bannerViewScrollDirection == BannerViewDirectionRight || self.bannerViewScrollDirection == BannerViewDirectionBottom){ 752 | if ((currentIndex - 1) < 0) { // 小于零 753 | currentIndex = self.cycleScrollEnable?(self.totalBannerItemsCount * 0.5):(0); 754 | [self _scrollBannerViewToSpecifiedPositionIndex:(currentIndex - 1) animated:NO]; 755 | }else{ 756 | [self _scrollToIndex:(currentIndex - 1) animated:YES]; 757 | } 758 | } 759 | } 760 | 761 | - (void)_scrollToIndex:(int)targetIndex animated:(BOOL)animated{ 762 | 763 | if (targetIndex >= self.totalBannerItemsCount) { // 超过最大 764 | targetIndex = self.cycleScrollEnable?(self.totalBannerItemsCount * 0.5):(0); 765 | [self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO]; 766 | }else{ 767 | [self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:animated]; 768 | } 769 | } 770 | 771 | /** current page index */ 772 | - (int)_currentPageIndex{ 773 | 774 | if (self.collectionView.width_bannerView == 0 || self.collectionView.height_bannerView == 0) {return 0;} 775 | int index = 0; 776 | if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) { 777 | index = (self.collectionView.contentOffset.x + self.flowLayout.itemSize.width * 0.5) / self.flowLayout.itemSize.width; 778 | } else { 779 | index = (self.collectionView.contentOffset.y + self.flowLayout.itemSize.height * 0.5) / self.flowLayout.itemSize.height; 780 | } 781 | return MAX(0, index); 782 | } 783 | 784 | /** current real index */ 785 | - (int)_getRealIndexFromCurrentCellIndex:(NSInteger)cellIndex{ 786 | return (int)cellIndex % [self _imageDataSources].count; 787 | } 788 | 789 | - (NSArray *)_imageDataSources{ 790 | return self.showNewDatasource; 791 | } 792 | 793 | /** Get new data from the proxy method */ 794 | - (NSArray *)_getImageDataSources{ 795 | if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewImages:)]) { 796 | return [self.dataSource bannerViewImages:self]; 797 | } 798 | return @[]; 799 | } 800 | 801 | /** Get new data from the proxy method */ 802 | - (NSArray *)_titlesDataSources{ 803 | if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewTitles:)]) { 804 | return [self.dataSource bannerViewTitles:self]; 805 | } 806 | return @[]; 807 | } 808 | 809 | /** Footer Height */ 810 | - (CGFloat)_bannerViewFooterHeight{ 811 | if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewFooterViewHeight:)]) { 812 | return [self.dataSource bannerViewFooterViewHeight:self]; 813 | } 814 | return BANNER_FOOTER_HEIGHT; 815 | } 816 | 817 | /** reload 时控制尾巴的显示和消失 */ 818 | - (void)_setFooterViewCanShow:(BOOL)showFooter{ 819 | 820 | if (showFooter) { 821 | self.bannerViewScrollDirection = BannerViewDirectionLeft; 822 | self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, 0, -[self _bannerViewFooterHeight]); 823 | }else{ 824 | self.collectionView.contentInset = UIEdgeInsetsZero; 825 | } 826 | 827 | if (self.bannerViewScrollDirection == BannerViewDirectionLeft) { 828 | self.collectionView.alwaysBounceHorizontal = showFooter; 829 | }else { 830 | self.collectionView.accessibilityViewIsModal = showFooter; 831 | } 832 | } 833 | 834 | /** Scroll the CollectionView to the specified location */ 835 | - (void)_scrollBannerViewToSpecifiedPositionIndex:(NSInteger)targetIndex animated:(BOOL)animated{ 836 | NSInteger itemCount = [self.collectionView numberOfItemsInSection:0]; 837 | if (targetIndex < itemCount) { 838 | [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:animated]; 839 | } 840 | } 841 | 842 | /** Save the current offset */ 843 | - (void)_saveInitializationContentOffsetJudgeZero:(BOOL)judgeZero{ 844 | 845 | if (self.collectionView.width_bannerView == 0 || self.collectionView.height_bannerView == 0) { return; } 846 | if (judgeZero) { 847 | if (self.lastContentOffset == 0) { 848 | 849 | if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) { 850 | self.lastContentOffset = self.collectionView.contentOffset.x; 851 | } else { 852 | self.lastContentOffset = self.collectionView.contentOffset.y; 853 | } 854 | } 855 | }else{ 856 | if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) { 857 | self.lastContentOffset = self.collectionView.contentOffset.x; 858 | } else { 859 | self.lastContentOffset = self.collectionView.contentOffset.y; 860 | } 861 | } 862 | } 863 | 864 | #pragma mark - Lazy 865 | - (UIImageView *)backgroundImageView{ 866 | if (!_backgroundImageView) { 867 | _backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; 868 | _backgroundImageView.contentMode = self.bannerImageViewContentMode; 869 | _backgroundImageView.clipsToBounds = YES; 870 | [self insertSubview:_backgroundImageView belowSubview:self.collectionView]; 871 | } 872 | return _backgroundImageView; 873 | } 874 | 875 | - (UICollectionViewFlowLayout *)flowLayout{ 876 | if (!_flowLayout) { 877 | _flowLayout = [[UICollectionViewFlowLayout alloc] init]; 878 | _flowLayout.minimumLineSpacing = 0.0f; 879 | _flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 880 | } 881 | return _flowLayout; 882 | } 883 | 884 | - (YJBannerViewCollectionView *)collectionView{ 885 | if (!_collectionView) { 886 | _collectionView = [[YJBannerViewCollectionView alloc] initWithFrame:self.bounds collectionViewLayout:self.flowLayout]; 887 | _collectionView.pagingEnabled = YES; 888 | _collectionView.showsHorizontalScrollIndicator = NO; 889 | _collectionView.showsVerticalScrollIndicator = NO; 890 | _collectionView.backgroundColor = [UIColor clearColor]; 891 | 892 | [_collectionView registerClass:[YJBannerViewCell class] forCellWithReuseIdentifier:bannerViewCellId]; 893 | [_collectionView registerClass:[YJBannerViewFooter class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:bannerViewFooterId]; 894 | 895 | _collectionView.dataSource = self; 896 | _collectionView.delegate = self; 897 | _collectionView.scrollsToTop = NO; 898 | } 899 | return _collectionView; 900 | } 901 | 902 | - (void)dealloc { 903 | self.collectionView.delegate = nil; 904 | self.collectionView.dataSource = nil; 905 | } 906 | 907 | @end 908 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 一、背景 2 | 3 | 在实际多业务迭代开发中,持续打包是必须的工作,自动化实现是必须实现的功能,编辑脚本实现自动化打包上传指定位置。 4 | 5 | ## 1.1、知识储备 6 | 7 | 需要了解打包命令 xcodebuild 的基本知识 8 | 9 | # 二、预览效果图 10 | 11 | ## 2.1 执行脚本 和 选项配置 12 | 13 | ![](http://ww2.sinaimg.cn/large/006tNc79ly1g37m4a2iy9j30k20u2gor.jpg) 14 | 15 | ## 2.2 开始构建 16 | 17 | ![](http://ww3.sinaimg.cn/large/006tNc79ly1g37m57lw1fj310e08ggn1.jpg) 18 | 19 | ## 2.3 构建成功并开始导出ipa 并上传到指定位置 20 | 21 | ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gjnwwbwdtlj30r105t3zk.jpg) 22 | 23 | # 二、脚本环境 24 | 25 | 基于 Xcode 10+ 设计,注意Xcode 8和9有所区别,请参考作者的另一篇:[http://www.jianshu.com/p/ba179c731e3f](http://www.jianshu.com/p/ba179c731e3f) , 26 | 如有问题,欢迎指正。 27 | 28 | # 三、功能 29 | 30 | * 支持 xcworkspace 和 xcodeproj 两种类型的工程; 31 | * 可以自动化清理、编译、构建工程导出ipa; 32 | * 支持Debug 和 Release; 33 | * 支持导出app-store, ad-hoc, enterprise, development的包; 34 | * 支持自动上传到蒲公英或者Fir等内测网站 35 | 36 | # 四、实现 37 | 38 | ## 4.1 更新RVM 39 | 40 | ```bash 41 | curl -L get.rvm.io | bash -s stable 42 | ``` 43 | 44 | ## 4.2 所需知识点 45 | 46 | ```bash 47 | 48 | xcodebuild clean // 等同于Xcode下点击Product -> Clean 49 | xcodebuild -xcworkspace // 等同于xcworkspace工程 command+B 50 | xcodebuild -xcodeproj // 等同于xcworkspace工程 command+B 51 | xcodebuild archive // 等同于Xcode下点击Product -> Archive 52 | xcodebuild -exportArchive // 等同于点击 export 53 | 54 | ``` 55 | # 五、脚本 56 | 57 | ## 配置完项目结构(可以根据自己喜好自由定义) 58 | 59 | 可以仿照Demo调整 60 | 61 | ### 测试体验Demo的话, 62 | 63 | 需要更换的地方: 64 | 65 | - 1. 你的Bundle identifier 66 | - 2.还有Plist里面的相应plist文件 67 | - 3、上传蒲公英或者Fir的相关APPID和Key, 68 | - 4.(可选) 如果是多个证书的话,需要指定证书,并打开下面的注释 69 | 70 | # 六、注意事项 71 | 72 | 注意ExportOptions.plist配置,如下所示: 73 | 74 | ```plist 75 | 76 | 77 | 78 | 79 | compileBitcode 80 | 81 | method 82 | enterprise 83 | provisioningProfiles 84 | 85 | com.houmanager.enterprise.test 86 | com.houmanager.enterprise.test 87 | 88 | signingCertificate 89 | iPhone Distribution 90 | signingStyle 91 | manual 92 | stripSwiftSymbols 93 | 94 | teamID 95 | 5XXXXXXXXXXXHM 96 | thinning 97 | 98 | 99 | 100 | ``` 101 | 102 | 如果不知道怎么填写,手动用**Xcode**打包,导出文件中会有ExportOptions.plist 103 | 104 | ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gjnx0of0olj30yc0cgjtz.jpg) 105 | 106 | 直接复制到指定路径或者手动copy即可。 107 | 108 | --- 109 | 110 | # FAQ 111 | 112 | ## 1.脚本支持多个target打包吗? 113 | 答:支持的,将您的所有target 写在 `__SELECT_TARGET_OPTIONS=("1.AutoPackingDemo")` 这个集合里面,比如:``__SELECT_TARGET_OPTIONS=("1.Tatget1" "2.Target2" "3.Target3")`, 同时修改下面的if else 判断。还有就是如果您是多个Target 对应多个Info.plist,请自行处理对应关系. so easy~ 114 | 115 | ## 2. 编译报错,报 Print: Entry, "CFBundleVersion", Does Not Exist 类似错误怎么解决? 116 | 答:报这样的错误多半是Info.plist对应的路径不对 或者 Info.plist名称被修改,脚本 `__CURRENT_INFO_PLIST_NAME="Info.plist"` 处Info.plist 名称和你项目里的相对路径要对。如果是多个Targget对应多个Info.plist,请自行处理对应关系。 117 | 118 | 119 | --------------------------------------------------------------------------------