├── .github └── ISSUE_TEMPLATE │ ├── bug--.md │ └── feature--.md ├── .gitignore ├── .travis.yml ├── Examples ├── MJRefreshExample │ ├── MJRefreshExample.xcodeproj │ │ └── project.pbxproj │ ├── MJRefreshExample │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.xib │ │ │ └── Main.storyboard │ │ ├── Classes │ │ │ ├── Category │ │ │ │ ├── UIViewController+Example.h │ │ │ │ └── UIViewController+Example.m │ │ │ ├── DIY │ │ │ │ ├── MJChiBaoZiFooter.h │ │ │ │ ├── MJChiBaoZiFooter.m │ │ │ │ ├── MJChiBaoZiFooter2.h │ │ │ │ ├── MJChiBaoZiFooter2.m │ │ │ │ ├── MJChiBaoZiHeader.h │ │ │ │ ├── MJChiBaoZiHeader.m │ │ │ │ ├── MJDIYAutoFooter.h │ │ │ │ ├── MJDIYAutoFooter.m │ │ │ │ ├── MJDIYBackFooter.h │ │ │ │ ├── MJDIYBackFooter.m │ │ │ │ ├── MJDIYHeader.h │ │ │ │ └── MJDIYHeader.m │ │ │ ├── First │ │ │ │ ├── MJExample.h │ │ │ │ ├── MJExample.m │ │ │ │ ├── MJExampleViewController.h │ │ │ │ ├── MJExampleViewController.m │ │ │ │ ├── MJExampleWindow.h │ │ │ │ ├── MJExampleWindow.m │ │ │ │ ├── MJSingleViewController.h │ │ │ │ ├── MJSingleViewController.m │ │ │ │ ├── MJTempViewController.h │ │ │ │ └── MJTempViewController.m │ │ │ ├── Other │ │ │ │ ├── AppDelegate.h │ │ │ │ └── AppDelegate.m │ │ │ ├── Second │ │ │ │ ├── MJCollectionViewController.h │ │ │ │ ├── MJCollectionViewController.m │ │ │ │ ├── MJHorizontalCollectionViewController.h │ │ │ │ ├── MJHorizontalCollectionViewController.m │ │ │ │ ├── MJPinHeaderCollectionViewController.swift │ │ │ │ ├── MJTableViewController.h │ │ │ │ ├── MJTableViewController.m │ │ │ │ ├── MJTestViewController.h │ │ │ │ ├── MJTestViewController.m │ │ │ │ ├── MJTestViewController.xib │ │ │ │ ├── MJWebViewViewController.h │ │ │ │ ├── MJWebViewViewController.m │ │ │ │ └── MJWebViewViewController.xib │ │ │ ├── SwiftExample │ │ │ │ └── MJWKWebViewController.swift │ │ │ └── i18n │ │ │ │ ├── CustomLanguages.bundle │ │ │ │ ├── en.lproj │ │ │ │ │ └── Localizable.strings │ │ │ │ ├── ko.lproj │ │ │ │ │ └── Localizable.strings │ │ │ │ ├── ru.lproj │ │ │ │ │ └── Localizable.strings │ │ │ │ ├── uk.lproj │ │ │ │ │ └── Localizable.strings │ │ │ │ ├── zh-Hans.lproj │ │ │ │ │ └── Localizable.strings │ │ │ │ └── zh-Hant.lproj │ │ │ │ │ └── Localizable.strings │ │ │ │ ├── I18NExampleViewController.swift │ │ │ │ ├── ar.lproj │ │ │ │ └── MJRefresh_i18n.strings │ │ │ │ ├── en.lproj │ │ │ │ └── MJRefresh_i18n.strings │ │ │ │ ├── ko.lproj │ │ │ │ └── MJRefresh_i18n.strings │ │ │ │ ├── ru.lproj │ │ │ │ └── MJRefresh_i18n.strings │ │ │ │ ├── uk.lproj │ │ │ │ └── MJRefresh_i18n.strings │ │ │ │ ├── zh-Hans.lproj │ │ │ │ └── MJRefresh_i18n.strings │ │ │ │ └── zh-Hant.lproj │ │ │ │ └── MJRefresh_i18n.strings │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── ios-marketing-1024x1024.png │ │ │ │ ├── ipad-20x20.png │ │ │ │ ├── ipad-20x20@2x.png │ │ │ │ ├── ipad-29x29-1.png │ │ │ │ ├── ipad-29x29.png │ │ │ │ ├── ipad-29x29@2x.png │ │ │ │ ├── ipad-40x40.png │ │ │ │ ├── ipad-40x40@2x.png │ │ │ │ ├── ipad-76x76.png │ │ │ │ ├── ipad-76x76@2x.png │ │ │ │ ├── ipad-83.5x83.5@2x.png │ │ │ │ ├── iphone-20x20@2x.png │ │ │ │ ├── iphone-20x20@3x.png │ │ │ │ ├── iphone-29x29@2x.png │ │ │ │ ├── iphone-29x29@3x.png │ │ │ │ ├── iphone-40x40@2x.png │ │ │ │ ├── iphone-40x40@3x.png │ │ │ │ ├── iphone-60x60@2x.png │ │ │ │ └── iphone-60x60@3x.png │ │ │ ├── Contents.json │ │ │ ├── DianPing │ │ │ │ ├── dropdown_anim__0001.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0001@2x.png │ │ │ │ ├── dropdown_anim__00010.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00010@2x.png │ │ │ │ ├── dropdown_anim__00011.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00011@2x.png │ │ │ │ ├── dropdown_anim__00012.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00012@2x.png │ │ │ │ ├── dropdown_anim__00013.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00013@2x.png │ │ │ │ ├── dropdown_anim__00014.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00014@2x.png │ │ │ │ ├── dropdown_anim__00015.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00015@2x.png │ │ │ │ ├── dropdown_anim__00016.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00016@2x.png │ │ │ │ ├── dropdown_anim__00017.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00017@2x.png │ │ │ │ ├── dropdown_anim__00018.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00018@2x.png │ │ │ │ ├── dropdown_anim__00019.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00019@2x.png │ │ │ │ ├── dropdown_anim__0002.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0002@2x.png │ │ │ │ ├── dropdown_anim__00020.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00020@2x.png │ │ │ │ ├── dropdown_anim__00021.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00021@2x.png │ │ │ │ ├── dropdown_anim__00022.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00022@2x.png │ │ │ │ ├── dropdown_anim__00023.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00023@2x.png │ │ │ │ ├── dropdown_anim__00024.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00024@2x.png │ │ │ │ ├── dropdown_anim__00025.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00025@2x.png │ │ │ │ ├── dropdown_anim__00026.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00026@2x.png │ │ │ │ ├── dropdown_anim__00027.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00027@2x.png │ │ │ │ ├── dropdown_anim__00028.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00028@2x.png │ │ │ │ ├── dropdown_anim__00029.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00029@2x.png │ │ │ │ ├── dropdown_anim__0003.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0003@2x.png │ │ │ │ ├── dropdown_anim__00030.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00030@2x.png │ │ │ │ ├── dropdown_anim__00031.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00031@2x.png │ │ │ │ ├── dropdown_anim__00032.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00032@2x.png │ │ │ │ ├── dropdown_anim__00033.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00033@2x.png │ │ │ │ ├── dropdown_anim__00034.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00034@2x.png │ │ │ │ ├── dropdown_anim__00035.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00035@2x.png │ │ │ │ ├── dropdown_anim__00036.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00036@2x.png │ │ │ │ ├── dropdown_anim__00037.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00037@2x.png │ │ │ │ ├── dropdown_anim__00038.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00038@2x.png │ │ │ │ ├── dropdown_anim__00039.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00039@2x.png │ │ │ │ ├── dropdown_anim__0004.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0004@2x.png │ │ │ │ ├── dropdown_anim__00040.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00040@2x.png │ │ │ │ ├── dropdown_anim__00041.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00041@2x.png │ │ │ │ ├── dropdown_anim__00042.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00042@2x.png │ │ │ │ ├── dropdown_anim__00043.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00043@2x.png │ │ │ │ ├── dropdown_anim__00044.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00044@2x.png │ │ │ │ ├── dropdown_anim__00045.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00045@2x.png │ │ │ │ ├── dropdown_anim__00046.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00046@2x.png │ │ │ │ ├── dropdown_anim__00047.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00047@2x.png │ │ │ │ ├── dropdown_anim__00048.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00048@2x.png │ │ │ │ ├── dropdown_anim__00049.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00049@2x.png │ │ │ │ ├── dropdown_anim__0005.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0005@2x.png │ │ │ │ ├── dropdown_anim__00050.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00050@2x.png │ │ │ │ ├── dropdown_anim__00051.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00051@2x.png │ │ │ │ ├── dropdown_anim__00052.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00052@2x.png │ │ │ │ ├── dropdown_anim__00053.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00053@2x.png │ │ │ │ ├── dropdown_anim__00054.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00054@2x.png │ │ │ │ ├── dropdown_anim__00055.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00055@2x.png │ │ │ │ ├── dropdown_anim__00056.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00056@2x.png │ │ │ │ ├── dropdown_anim__00057.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00057@2x.png │ │ │ │ ├── dropdown_anim__00058.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00058@2x.png │ │ │ │ ├── dropdown_anim__00059.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00059@2x.png │ │ │ │ ├── dropdown_anim__0006.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0006@2x.png │ │ │ │ ├── dropdown_anim__00060.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__00060@2x.png │ │ │ │ ├── dropdown_anim__0007.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0007@2x.png │ │ │ │ ├── dropdown_anim__0008.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0008@2x.png │ │ │ │ ├── dropdown_anim__0009.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_anim__0009@2x.png │ │ │ │ ├── dropdown_loading_01.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_loading_01@2x.png │ │ │ │ ├── dropdown_loading_02.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_loading_02@2x.png │ │ │ │ └── dropdown_loading_03.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── dropdown_loading_03@2x.png │ │ │ ├── MJRefresh.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── MJRefresh.png │ │ │ ├── NavBar.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── NavBar@2x.png │ │ │ ├── NavBar64.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── NavBar64@2x.png │ │ │ └── logo.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── logo.png │ │ │ │ └── logo@2x.png │ │ ├── Info.plist │ │ ├── MJRefreshExample-Bridging-Header.h │ │ ├── PrefixHeader.pch │ │ └── main.m │ └── MJRefreshExampleTests │ │ ├── Info.plist │ │ └── MJRefreshExampleTests.m └── SPMTestExample │ ├── SPMTestExample.xcodeproj │ └── project.pbxproj │ └── SPMTestExample │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift ├── Gif └── trailer_refresh.gif ├── LICENSE ├── MJRefresh.podspec ├── MJRefresh.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── MJRefresh.xcscheme ├── MJRefresh ├── Base │ ├── MJRefreshAutoFooter.h │ ├── MJRefreshAutoFooter.m │ ├── MJRefreshBackFooter.h │ ├── MJRefreshBackFooter.m │ ├── MJRefreshComponent.h │ ├── MJRefreshComponent.m │ ├── MJRefreshFooter.h │ ├── MJRefreshFooter.m │ ├── MJRefreshHeader.h │ ├── MJRefreshHeader.m │ ├── MJRefreshTrailer.h │ └── MJRefreshTrailer.m ├── Custom │ ├── Footer │ │ ├── Auto │ │ │ ├── MJRefreshAutoGifFooter.h │ │ │ ├── MJRefreshAutoGifFooter.m │ │ │ ├── MJRefreshAutoNormalFooter.h │ │ │ ├── MJRefreshAutoNormalFooter.m │ │ │ ├── MJRefreshAutoStateFooter.h │ │ │ └── MJRefreshAutoStateFooter.m │ │ └── Back │ │ │ ├── MJRefreshBackGifFooter.h │ │ │ ├── MJRefreshBackGifFooter.m │ │ │ ├── MJRefreshBackNormalFooter.h │ │ │ ├── MJRefreshBackNormalFooter.m │ │ │ ├── MJRefreshBackStateFooter.h │ │ │ └── MJRefreshBackStateFooter.m │ ├── Header │ │ ├── MJRefreshGifHeader.h │ │ ├── MJRefreshGifHeader.m │ │ ├── MJRefreshNormalHeader.h │ │ ├── MJRefreshNormalHeader.m │ │ ├── MJRefreshStateHeader.h │ │ └── MJRefreshStateHeader.m │ └── Trailer │ │ ├── MJRefreshNormalTrailer.h │ │ ├── MJRefreshNormalTrailer.m │ │ ├── MJRefreshStateTrailer.h │ │ └── MJRefreshStateTrailer.m ├── Info.plist ├── MJRefresh.bundle │ ├── arrow@2x.png │ ├── en.lproj │ │ └── Localizable.strings │ ├── ko.lproj │ │ └── Localizable.strings │ ├── ru.lproj │ │ └── Localizable.strings │ ├── trail_arrow@2x.png │ ├── uk.lproj │ │ └── Localizable.strings │ ├── zh-Hans.lproj │ │ └── Localizable.strings │ └── zh-Hant.lproj │ │ └── Localizable.strings ├── MJRefresh.h ├── MJRefreshConfig.h ├── MJRefreshConfig.m ├── MJRefreshConst.h ├── MJRefreshConst.m ├── NSBundle+MJRefresh.h ├── NSBundle+MJRefresh.m ├── PrivacyInfo.xcprivacy ├── UICollectionViewLayout+MJRefresh.h ├── UICollectionViewLayout+MJRefresh.m ├── UIScrollView+MJExtension.h ├── UIScrollView+MJExtension.m ├── UIScrollView+MJRefresh.h ├── UIScrollView+MJRefresh.m ├── UIView+MJExtension.h ├── UIView+MJExtension.m └── include │ ├── MJRefresh.h │ ├── MJRefreshAutoFooter.h │ ├── MJRefreshAutoGifFooter.h │ ├── MJRefreshAutoNormalFooter.h │ ├── MJRefreshAutoStateFooter.h │ ├── MJRefreshBackFooter.h │ ├── MJRefreshBackGifFooter.h │ ├── MJRefreshBackNormalFooter.h │ ├── MJRefreshBackStateFooter.h │ ├── MJRefreshComponent.h │ ├── MJRefreshConfig.h │ ├── MJRefreshConst.h │ ├── MJRefreshFooter.h │ ├── MJRefreshGifHeader.h │ ├── MJRefreshHeader.h │ ├── MJRefreshNormalHeader.h │ ├── MJRefreshNormalTrailer.h │ ├── MJRefreshStateHeader.h │ ├── MJRefreshStateTrailer.h │ ├── MJRefreshTrailer.h │ ├── NSBundle+MJRefresh.h │ ├── UIScrollView+MJExtension.h │ ├── UIScrollView+MJRefresh.h │ └── UIView+MJExtension.h ├── Package.swift └── README.md /.github/ISSUE_TEMPLATE/bug--.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug上报 3 | about: 提交Bug让框架更加健壮 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | 🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶 11 | 12 | 😁为了能够更好地复现问题和修复问题, 请提供 Demo 和详细的 bug 重现步骤😭 13 | 14 | 🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶 15 | > 记得删除以上内容 16 | 17 | **描述bug** 18 | 清晰简单地描述这个bug是啥 19 | 20 | **必现/偶发?** 21 | 必现 22 | 23 | **怎么样重现这个bug** 24 | 1. 显示哪个页面 25 | 2. 点击哪个位置 26 | 3. 滚动到哪个位置 27 | 4. 发生了什么错误 28 | 29 | **你期望的结果是什么?** 30 | 你本来期望得到的正确结果是怎样的?就是解决bug之后的结果 31 | 32 | **截图** 33 | 如果有必要的话,请上传几张截图 34 | 35 | **运行环境** 36 | - iPhone6 37 | - iOS8.1 38 | - Xcode10 39 | 40 | **额外的** 41 | 最好能提供出现bug的Demo 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature--.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature建议 3 | about: 为框架提供新功能建议 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | **你的新功能建议是否牵扯到某个常见的问题?** 11 | 比如,在开发中,经常遇到XXX问题,目前框架的功能不足以解决这个问题 12 | 13 | **你希望达到的效果** 14 | 比如,我希望框架能够帮助我解决XXX问题,实现XXXX那样的效果 15 | 16 | **你能考虑到的可选实现方案** 17 | 描述一下你认为要实现这个功能,有哪些可行的一些实现方案? 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Xcode 4 | build/* 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | *.xcworkspace 14 | !default.xcworkspace 15 | xcuserdata 16 | profile 17 | *.moved-aside 18 | *.xcuserstate 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | xcode_project: MJRefreshExample.xcodeproj 3 | xcode_scheme: MJRefresh 4 | 5 | env: 6 | global: 7 | - FRAMEWORK_NAME=MJRefresh 8 | before_install: 9 | - gem install xcpretty 10 | 11 | script: 12 | - xcodebuild -project $xcode_project -scheme $FRAMEWORK_NAME build | xcpretty 13 | - pod lib lint 14 | - carthage build --no-skip-current 15 | 16 | notifications: 17 | email: false 18 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Category/UIViewController+Example.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Example.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/12. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (Example) 12 | @property (copy, nonatomic) NSString *method; 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Category/UIViewController+Example.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Example.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/12. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+Example.h" 10 | #import 11 | 12 | @implementation UIViewController (Example) 13 | 14 | #pragma mark - swizzle 15 | + (void)load 16 | { 17 | Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"dealloc")); 18 | Method method2 = class_getInstanceMethod([self class], @selector(deallocSwizzle)); 19 | method_exchangeImplementations(method1, method2); 20 | } 21 | 22 | - (void)deallocSwizzle 23 | { 24 | NSLog(@"%@被销毁了", self); 25 | 26 | [self deallocSwizzle]; 27 | } 28 | 29 | static char MethodKey; 30 | - (void)setMethod:(NSString *)method 31 | { 32 | objc_setAssociatedObject(self, &MethodKey, method, OBJC_ASSOCIATION_COPY_NONATOMIC); 33 | } 34 | 35 | - (NSString *)method 36 | { 37 | return objc_getAssociatedObject(self, &MethodKey); 38 | } 39 | @end 40 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJChiBaoZiFooter.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/12. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | @import MJRefresh; 10 | 11 | @interface MJChiBaoZiFooter : MJRefreshAutoGifFooter 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJChiBaoZiFooter.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/12. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJChiBaoZiFooter.h" 10 | 11 | @implementation MJChiBaoZiFooter 12 | #pragma mark - 重写方法 13 | #pragma mark 基本设置 14 | - (void)prepare 15 | { 16 | [super prepare]; 17 | 18 | // 设置正在刷新状态的动画图片 19 | NSMutableArray *refreshingImages = [NSMutableArray array]; 20 | for (NSUInteger i = 1; i<=3; i++) { 21 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]]; 22 | [refreshingImages addObject:image]; 23 | } 24 | [self setImages:refreshingImages forState:MJRefreshStateRefreshing]; 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJChiBaoZiFooter2.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/12. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | @import MJRefresh; 10 | 11 | @interface MJChiBaoZiFooter2 : MJRefreshBackGifFooter 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJChiBaoZiFooter2.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/12. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJChiBaoZiFooter2.h" 10 | 11 | @implementation MJChiBaoZiFooter2 12 | #pragma mark - 重写方法 13 | #pragma mark 基本设置 14 | - (void)prepare 15 | { 16 | [super prepare]; 17 | 18 | // 设置普通状态的动画图片 19 | NSMutableArray *idleImages = [NSMutableArray array]; 20 | for (NSUInteger i = 1; i<=60; i++) { 21 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd", i]]; 22 | [idleImages addObject:image]; 23 | } 24 | [self setImages:idleImages forState:MJRefreshStateIdle]; 25 | 26 | // 设置即将刷新状态的动画图片(一松开就会刷新的状态) 27 | NSMutableArray *refreshingImages = [NSMutableArray array]; 28 | for (NSUInteger i = 1; i<=3; i++) { 29 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]]; 30 | [refreshingImages addObject:image]; 31 | } 32 | [self setImages:refreshingImages forState:MJRefreshStatePulling]; 33 | 34 | // 设置正在刷新状态的动画图片 35 | [self setImages:refreshingImages forState:MJRefreshStateRefreshing]; 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJChiBaoZiHeader.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/12. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 吃包子效果的头部控件 8 | 9 | @import MJRefresh; 10 | 11 | @interface MJChiBaoZiHeader : MJRefreshGifHeader 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJChiBaoZiHeader.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/12. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJChiBaoZiHeader.h" 10 | 11 | @implementation MJChiBaoZiHeader 12 | #pragma mark - 重写方法 13 | #pragma mark 基本设置 14 | - (void)prepare 15 | { 16 | [super prepare]; 17 | 18 | // 设置普通状态的动画图片 19 | NSMutableArray *idleImages = [NSMutableArray array]; 20 | for (NSUInteger i = 1; i<=60; i++) { 21 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd", i]]; 22 | [idleImages addObject:image]; 23 | } 24 | [self setImages:idleImages forState:MJRefreshStateIdle]; 25 | 26 | // 设置即将刷新状态的动画图片(一松开就会刷新的状态) 27 | NSMutableArray *refreshingImages = [NSMutableArray array]; 28 | for (NSUInteger i = 1; i<=3; i++) { 29 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]]; 30 | [refreshingImages addObject:image]; 31 | } 32 | [self setImages:refreshingImages forState:MJRefreshStatePulling]; 33 | 34 | // 设置正在刷新状态的动画图片 35 | [self setImages:refreshingImages forState:MJRefreshStateRefreshing]; 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJDIYAutoFooter.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | @import MJRefresh; 10 | 11 | @interface MJDIYAutoFooter : MJRefreshAutoFooter 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJDIYAutoFooter.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJDIYAutoFooter.h" 10 | 11 | @interface MJDIYAutoFooter() 12 | @property (weak, nonatomic) UILabel *label; 13 | @property (weak, nonatomic) UISwitch *s; 14 | @property (weak, nonatomic) UIActivityIndicatorView *loading; 15 | @end 16 | 17 | @implementation MJDIYAutoFooter 18 | #pragma mark - 重写方法 19 | #pragma mark 在这里做一些初始化配置(比如添加子控件) 20 | - (void)prepare 21 | { 22 | [super prepare]; 23 | 24 | // 设置控件的高度 25 | self.mj_h = 50; 26 | 27 | // 添加label 28 | UILabel *label = [[UILabel alloc] init]; 29 | label.textColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.0 alpha:1.0]; 30 | label.font = [UIFont boldSystemFontOfSize:16]; 31 | label.textAlignment = NSTextAlignmentCenter; 32 | [self addSubview:label]; 33 | self.label = label; 34 | 35 | // 打酱油的开关 36 | UISwitch *s = [[UISwitch alloc] init]; 37 | [self addSubview:s]; 38 | self.s = s; 39 | 40 | // loading 41 | UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 42 | [self addSubview:loading]; 43 | self.loading = loading; 44 | } 45 | 46 | #pragma mark 在这里设置子控件的位置和尺寸 47 | - (void)placeSubviews 48 | { 49 | [super placeSubviews]; 50 | 51 | self.label.frame = self.bounds; 52 | self.s.center = CGPointMake(self.mj_w - 20, self.mj_h - 20); 53 | 54 | self.loading.center = CGPointMake(30, self.mj_h * 0.5); 55 | } 56 | 57 | #pragma mark 监听scrollView的contentOffset改变 58 | - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change 59 | { 60 | [super scrollViewContentOffsetDidChange:change]; 61 | 62 | } 63 | 64 | #pragma mark 监听scrollView的contentSize改变 65 | - (void)scrollViewContentSizeDidChange:(NSDictionary *)change 66 | { 67 | [super scrollViewContentSizeDidChange:change]; 68 | 69 | } 70 | 71 | #pragma mark 监听scrollView的拖拽状态改变 72 | - (void)scrollViewPanStateDidChange:(NSDictionary *)change 73 | { 74 | [super scrollViewPanStateDidChange:change]; 75 | 76 | } 77 | 78 | #pragma mark 监听控件的刷新状态 79 | - (void)setState:(MJRefreshState)state 80 | { 81 | MJRefreshCheckState; 82 | 83 | switch (state) { 84 | case MJRefreshStateIdle: 85 | self.label.text = @"赶紧上拉吖(开关是打酱油滴)"; 86 | [self.loading stopAnimating]; 87 | [self.s setOn:NO animated:YES]; 88 | break; 89 | case MJRefreshStateRefreshing: 90 | [self.s setOn:YES animated:YES]; 91 | self.label.text = @"加载数据中(开关是打酱油滴)"; 92 | [self.loading startAnimating]; 93 | break; 94 | case MJRefreshStateNoMoreData: 95 | self.label.text = @"木有数据了(开关是打酱油滴)"; 96 | [self.s setOn:NO animated:YES]; 97 | [self.loading stopAnimating]; 98 | break; 99 | default: 100 | break; 101 | } 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJDIYBackFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJDIYBackFooter.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | @import MJRefresh; 10 | 11 | @interface MJDIYBackFooter : MJRefreshBackFooter 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/DIY/MJDIYHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJDIYHeader.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | @import MJRefresh; 10 | 11 | @interface MJDIYHeader : MJRefreshHeader 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJExample.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJExample.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/5. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJExample : NSObject 12 | @property (copy, nonatomic) NSString *header; 13 | @property (strong, nonatomic) NSArray *titles; 14 | @property (strong, nonatomic) NSArray *methods; 15 | @property (strong, nonatomic) NSArray *vcClasses; 16 | @end 17 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJExample.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJExample.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/5. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJExample.h" 10 | 11 | @implementation MJExample 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJExampleViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/5. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJExampleViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJExampleWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJExampleWindow.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/8/17. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJExampleWindow : UIWindow 12 | + (void)show; 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJExampleWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJExampleWindow.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/8/17. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJExampleWindow.h" 10 | #import "MJTempViewController.h" 11 | 12 | @implementation MJExampleWindow 13 | 14 | static UIWindow *window_; 15 | + (void)show 16 | { 17 | window_ = [[UIWindow alloc] init]; 18 | CGFloat width = 150; 19 | CGFloat x = [UIScreen mainScreen].bounds.size.width - width - 10; 20 | CGFloat y = 0; 21 | 22 | if (@available(iOS 11.0, *)) { 23 | UIEdgeInsets safeInsets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets; 24 | y = safeInsets.top; 25 | } 26 | 27 | window_.frame = CGRectMake(x, y, width, 25); 28 | window_.windowLevel = UIWindowLevelAlert; 29 | window_.hidden = NO; 30 | window_.alpha = 0.5; 31 | window_.rootViewController = [[MJTempViewController alloc] init]; 32 | window_.backgroundColor = [UIColor clearColor]; 33 | } 34 | @end 35 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJSingleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJSingleViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJSingleViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJSingleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJSingleViewController.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJSingleViewController.h" 10 | #import "MJTestViewController.h" 11 | @import MJRefresh; 12 | 13 | @interface MJSingleViewController () 14 | @property (assign, nonatomic) int count; 15 | @end 16 | 17 | @implementation MJSingleViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | self.count = 0; 23 | 24 | __unsafe_unretained typeof(self) weakSelf = self; 25 | __unsafe_unretained UITableView *tableView = self.tableView; 26 | 27 | tableView.mj_header= [MJRefreshNormalHeader headerWithRefreshingBlock:^{ 28 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 29 | weakSelf.count += 12; 30 | [tableView reloadData]; 31 | [tableView.mj_header endRefreshing]; 32 | }); 33 | }]; 34 | tableView.mj_header.automaticallyChangeAlpha = YES; 35 | 36 | MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ 37 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 38 | weakSelf.count += 5; 39 | [tableView reloadData]; 40 | [tableView.mj_footer endRefreshing]; 41 | }); 42 | }]; 43 | footer.hidden = YES; 44 | tableView.mj_footer = footer; 45 | } 46 | 47 | - (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section 48 | { 49 | return self.count; 50 | } 51 | 52 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 53 | { 54 | static NSString *ID = @"cell"; 55 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 56 | if (cell == nil) { 57 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 58 | } 59 | if (indexPath.row % 2 && self.navigationController) { 60 | cell.textLabel.text = @"push"; 61 | } else { 62 | cell.textLabel.text = @"modal"; 63 | } 64 | return cell; 65 | } 66 | 67 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 68 | { 69 | MJTestViewController *test = [[MJTestViewController alloc] init]; 70 | if (indexPath.row % 2 && self.navigationController) { 71 | test.hidesBottomBarWhenPushed = YES; 72 | [self.navigationController pushViewController:test animated:YES]; 73 | } else { 74 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:test]; 75 | [self presentViewController:nav animated:YES completion:nil]; 76 | } 77 | } 78 | @end 79 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJTempViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJTempViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/9/22. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJTempViewController : UIViewController 12 | 13 | + (instancetype)sharedInstance; 14 | 15 | @property (assign, nonatomic) UIStatusBarStyle statusBarStyle; 16 | @property (assign, nonatomic) BOOL statusBarHidden; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/First/MJTempViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJTempViewController.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/9/22. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJTempViewController.h" 10 | 11 | @interface MJTempViewController () 12 | 13 | @end 14 | 15 | @implementation MJTempViewController 16 | #pragma mark - 单例 17 | static id instance_; 18 | 19 | + (instancetype)sharedInstance 20 | { 21 | static dispatch_once_t onceToken; 22 | dispatch_once(&onceToken, ^{ 23 | instance_ = [[self alloc] init]; 24 | }); 25 | return instance_; 26 | } 27 | 28 | + (instancetype)allocWithZone:(struct _NSZone *)zone 29 | { 30 | static dispatch_once_t onceToken; 31 | dispatch_once(&onceToken, ^{ 32 | instance_ = [super allocWithZone:zone]; 33 | }); 34 | return instance_; 35 | } 36 | 37 | #pragma mark - 初始化 38 | - (void)viewDidLoad { 39 | [super viewDidLoad]; 40 | 41 | self.statusBarStyle = UIStatusBarStyleLightContent; 42 | 43 | self.view.backgroundColor = [UIColor clearColor]; 44 | 45 | UISegmentedControl *control = [[UISegmentedControl alloc] initWithItems:@[@"示例1", @"i18n", @"示例3"]]; 46 | control.tintColor = [UIColor orangeColor]; 47 | control.frame = self.view.bounds; 48 | control.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 49 | control.selectedSegmentIndex = 0; 50 | [control addTarget:self action:@selector(contorlSelect:) forControlEvents:UIControlEventValueChanged]; 51 | [self.view addSubview:control]; 52 | } 53 | 54 | - (void)contorlSelect:(UISegmentedControl *)control 55 | { 56 | UIWindow *keyWindow = [UIApplication sharedApplication].windows.firstObject; 57 | keyWindow.rootViewController = [keyWindow.rootViewController.storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:@"%zd", control.selectedSegmentIndex]]; 58 | 59 | if (control.selectedSegmentIndex == 0) { 60 | self.statusBarStyle = UIStatusBarStyleLightContent; 61 | self.statusBarHidden = NO; 62 | } else if (control.selectedSegmentIndex == 1) { 63 | self.statusBarHidden = YES; 64 | } else if (control.selectedSegmentIndex == 2) { 65 | self.statusBarStyle = UIStatusBarStyleDefault; 66 | self.statusBarHidden = NO; 67 | } 68 | } 69 | 70 | - (UIStatusBarStyle)preferredStatusBarStyle 71 | { 72 | return self.statusBarStyle; 73 | } 74 | 75 | - (BOOL)prefersStatusBarHidden 76 | { 77 | return self.statusBarHidden; 78 | } 79 | 80 | - (void)setStatusBarHidden:(BOOL)statusBarHidden 81 | { 82 | _statusBarHidden = statusBarHidden; 83 | 84 | [self setNeedsStatusBarAppearanceUpdate]; 85 | } 86 | 87 | - (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle 88 | { 89 | _statusBarStyle = statusBarStyle; 90 | 91 | [self setNeedsStatusBarAppearanceUpdate]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Other/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // AppDelegate.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. 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 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Other/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // AppDelegate.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "MJExampleWindow.h" 11 | 12 | @interface AppDelegate () 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 18 | 19 | [self setupNavigationBarAppearance]; 20 | 21 | return YES; 22 | } 23 | 24 | - (void)applicationDidBecomeActive:(UIApplication *)application { 25 | // 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. 26 | static dispatch_once_t onceToken; 27 | dispatch_once(&onceToken, ^{ 28 | [MJExampleWindow show]; 29 | }); 30 | } 31 | 32 | - (void)setupNavigationBarAppearance { 33 | // 1.取出设置主题的对象 34 | UINavigationBar *navBar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[UINavigationController.class]]; 35 | 36 | // 2.设置导航栏的背景图片 37 | UIImage *backgroundImage = [UIImage imageNamed:@"NavBar64"]; 38 | NSDictionary *titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]}; 39 | 40 | if (@available(iOS 13.0, *)) { 41 | UINavigationBarAppearance *appearance = [UINavigationBarAppearance new]; 42 | appearance.backgroundImage = backgroundImage; 43 | appearance.backgroundImageContentMode = UIViewContentModeScaleToFill; 44 | appearance.titleTextAttributes = titleTextAttributes; 45 | 46 | navBar.scrollEdgeAppearance = appearance; 47 | navBar.standardAppearance = appearance; 48 | } else { 49 | [[UINavigationBar appearance] setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault]; 50 | // 3.标题 51 | [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]}]; 52 | } 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJCollectionViewController.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJCollectionViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/6. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJCollectionViewController : UICollectionViewController 12 | 13 | - (void)example31; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJHorizontalCollectionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJHorizontalCollectionViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by libin14 on 2020/9/13. 6 | // Copyright © 2020 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MJHorizontalCollectionViewController : UICollectionViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJPinHeaderCollectionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MJPinHeaderCollectionViewController.swift 3 | // MJRefreshExample 4 | // 5 | // Created by Frank on 2023/9/18. 6 | // Copyright © 2023 小码哥. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @objcMembers 12 | class MJPinHeaderCollectionViewController: MJCollectionViewController { 13 | 14 | convenience init() { 15 | let pinHeaderLayout = PinHeaderFlowLayout() 16 | pinHeaderLayout.itemSize = CGSizeMake(80, 80) 17 | pinHeaderLayout.sectionInset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) 18 | pinHeaderLayout.minimumInteritemSpacing = 20 19 | pinHeaderLayout.minimumLineSpacing = 20 20 | pinHeaderLayout.headerReferenceSize = CGSize(width: 100, height: 30) 21 | 22 | self.init(collectionViewLayout: pinHeaderLayout) 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | } 28 | } 29 | 30 | @objcMembers 31 | class PinHeaderFlowLayout: UICollectionViewFlowLayout { 32 | override var flipsHorizontallyInOppositeLayoutDirection: Bool { 33 | true 34 | } 35 | 36 | override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { 37 | let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, with: indexPath) 38 | // TODO: Implementation of PinHeader 39 | 40 | return attributes 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJTableViewController.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJTableViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJTestViewController.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJTestViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define MJPerformSelectorLeakWarning(Stuff) \ 12 | do { \ 13 | _Pragma("clang diagnostic push") \ 14 | _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ 15 | Stuff; \ 16 | _Pragma("clang diagnostic pop") \ 17 | } while (0) 18 | 19 | @interface MJTestViewController : UIViewController 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJTestViewController.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJTestViewController.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJTestViewController.h" 10 | 11 | @interface MJTestViewController () 12 | 13 | @end 14 | 15 | @implementation MJTestViewController 16 | 17 | - (void)viewDidLoad 18 | { 19 | [super viewDidLoad]; 20 | 21 | self.title = @"测试控制器"; 22 | 23 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStyleDone target:self action:@selector(close)]; 24 | } 25 | 26 | - (void)close 27 | { 28 | if (self.presentingViewController) { 29 | [self dismissViewControllerAnimated:YES completion:nil]; 30 | } else { 31 | [self.navigationController popViewControllerAnimated:YES]; 32 | } 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJTestViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJWebViewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJWebViewViewController.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/12. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJWebViewViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/Second/MJWebViewViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJWebViewViewController.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/12. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJWebViewViewController.h" 10 | #import "UIViewController+Example.h" 11 | #import "MJChiBaoZiHeader.h" 12 | 13 | @import MJRefresh; 14 | 15 | @interface MJWebViewViewController () 16 | @property (weak, nonatomic) IBOutlet UIWebView *webView; 17 | @end 18 | 19 | @implementation MJWebViewViewController 20 | #pragma mark - 示例 21 | - (void)example40 22 | { 23 | __weak UIWebView *webView = self.webView; 24 | webView.delegate = self; 25 | 26 | __weak UIScrollView *scrollView = self.webView.scrollView; 27 | 28 | // 添加下拉刷新控件 29 | [[[MJChiBaoZiHeader headerWithRefreshingBlock:^{ 30 | [webView reload]; 31 | }] 32 | linkTo:scrollView] 33 | autoChangeTransparency:YES]; 34 | 35 | // 如果是上拉刷新,就以此类推 36 | [scrollView.mj_header beginRefreshing]; 37 | } 38 | 39 | #pragma mark - webViewDelegate 40 | - (void)webViewDidFinishLoad:(nonnull UIWebView *)webView 41 | { 42 | [self.webView.scrollView.mj_header endRefreshing]; 43 | } 44 | 45 | #pragma mark - 其他 46 | - (void)viewDidLoad { 47 | [super viewDidLoad]; 48 | 49 | // 加载页面 50 | [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://weibo.com/exceptions"]]]; 51 | 52 | #pragma clang diagnostic push 53 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 54 | [self performSelector:NSSelectorFromString(self.method) withObject:nil]; 55 | #pragma clang diagnostic pop 56 | } 57 | 58 | - (void)viewWillAppear:(BOOL)animated 59 | { 60 | [super viewWillAppear:animated]; 61 | 62 | [self.navigationController setNavigationBarHidden:YES animated:YES]; 63 | 64 | [self setNeedsStatusBarAppearanceUpdate]; 65 | } 66 | 67 | - (void)viewWillDisappear:(BOOL)animated 68 | { 69 | [super viewWillDisappear:animated]; 70 | 71 | [self.navigationController setNavigationBarHidden:NO animated:YES]; 72 | } 73 | 74 | - (BOOL)prefersStatusBarHidden 75 | { 76 | return YES; 77 | } 78 | 79 | - (IBAction)back { 80 | [self.navigationController popViewControllerAnimated:YES]; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/SwiftExample/MJWKWebViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MJWKWebViewController.swift 3 | // MJRefreshExample 4 | // 5 | // Created by Frank on 2021/3/3. 6 | // Copyright © 2021 小码哥. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WebKit 11 | // 在实际的工程中, 使用以下 Import module 即可 12 | //import MJRefresh 13 | 14 | @objc 15 | class MJWKWebViewController: UIViewController { 16 | var webView: WKWebView! 17 | 18 | func example41() { 19 | MJChiBaoZiHeader { [weak self] in 20 | self?.webView.reload() 21 | }.autoChangeTransparency(true) 22 | .link(to: webView.scrollView) 23 | 24 | webView.scrollView.mj_header?.beginRefreshing() 25 | } 26 | } 27 | 28 | // MARK: 🌈 无关例子的样式构建方法 29 | extension MJWKWebViewController { 30 | override func viewDidLoad() { 31 | super.viewDidLoad() 32 | 33 | constructViews() 34 | } 35 | override func viewWillAppear(_ animated: Bool) { 36 | super.viewWillAppear(animated) 37 | 38 | navigationController?.setNavigationBarHidden(true, animated: true) 39 | setNeedsStatusBarAppearanceUpdate() 40 | } 41 | override func viewWillDisappear(_ animated: Bool) { 42 | super.viewWillDisappear(animated) 43 | 44 | navigationController?.setNavigationBarHidden(false, animated: true) 45 | } 46 | 47 | override var prefersStatusBarHidden: Bool { 48 | true 49 | } 50 | 51 | private func constructViews() { 52 | webView = WKWebView(frame: view.frame) 53 | webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 54 | view.addSubview(webView) 55 | webView.navigationDelegate = self 56 | 57 | let size = view.frame.size 58 | let warningLabel = UILabel(frame: CGRect(x: size.width - 210, y: size.height - 160, width: 200, height: 50)) 59 | warningLabel.text = "注意,这不是原生界面,是个网页:http://weibo.com/excepptions" 60 | warningLabel.adjustsFontSizeToFitWidth = true 61 | warningLabel.textColor = .black 62 | warningLabel.backgroundColor = UIColor.lightGray.withAlphaComponent(0.3) 63 | warningLabel.numberOfLines = 0 64 | let mask: UIView.AutoresizingMask = [.flexibleRightMargin, .flexibleBottomMargin] 65 | warningLabel.autoresizingMask = mask 66 | webView.addSubview(warningLabel) 67 | 68 | let backButton = UIButton(frame: CGRect(x: size.width - 210, y: size.height - 100, width: 200, height: 50)) 69 | backButton.setTitle("回到上一页", for: .normal) 70 | backButton.backgroundColor = .red 71 | backButton.autoresizingMask = mask 72 | backButton.addTarget(self, action: #selector(back), for: .touchUpInside) 73 | webView.addSubview(backButton) 74 | 75 | webView.load(URLRequest(url: URL(string: "http://weibo.com/exceptions")!)) 76 | example41() 77 | } 78 | 79 | @objc 80 | func back() { 81 | navigationController?.popViewController(animated: true) 82 | } 83 | } 84 | 85 | 86 | extension MJWKWebViewController: WKNavigationDelegate { 87 | func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 88 | webView.scrollView.mj_header?.endRefreshing() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/ko.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/ko.lproj/Localizable.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/ru.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/ru.lproj/Localizable.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/uk.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/uk.lproj/Localizable.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/CustomLanguages.bundle/zh-Hant.lproj/Localizable.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/I18NExampleViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // I18NExampleViewController.swift 3 | // MJRefreshExample 4 | // 5 | // Created by Frank on 2021/7/5. 6 | // Copyright © 2021 小码哥. All rights reserved. 7 | // 8 | import UIKit 9 | 10 | class I18NExampleViewController: UITableViewController { 11 | var languages = [ 12 | "zh-Hans", "zh-Hant", "en", "ru", "ko", "uk" 13 | ] 14 | var customBundles = [ 15 | "zh-Hans", "zh-Hant", "en", "ru", "ko", "uk" 16 | ] 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") 22 | 23 | MJRefreshNormalHeader { 24 | DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in 25 | guard let self = self else { return } 26 | self.tableView.mj_header?.endRefreshing() 27 | } 28 | }.autoChangeTransparency(true).link(to: tableView) 29 | 30 | MJRefreshAutoNormalFooter { 31 | DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in 32 | guard let self = self else { return } 33 | self.tableView.mj_footer?.endRefreshing() 34 | } 35 | }.link(to: tableView) 36 | } 37 | 38 | override func numberOfSections(in tableView: UITableView) -> Int { 39 | return 3 40 | } 41 | 42 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 43 | return languages.count 44 | } 45 | 46 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 47 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! 48 | 49 | cell.textLabel?.text = languages[indexPath.row] 50 | return cell 51 | } 52 | 53 | override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 54 | switch section { 55 | case 0: 56 | return "MJRefresh 系统包或 MainBundle 中默认语言包" 57 | case 1: 58 | return "🍬自定义语言包文件(MJRefresh_i18n.strings)" 59 | case 2: 60 | return "♿️自定义语言包 bundle(CustomLanguages.bundle)" 61 | default: 62 | return nil 63 | } 64 | } 65 | 66 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 67 | switch indexPath.section { 68 | case 1: 69 | MJRefreshConfig.default.i18nFilename = "MJRefresh_i18n" 70 | MJRefreshConfig.default.languageCode = nil 71 | MJRefreshConfig.default.i18nBundle = nil 72 | case 2: 73 | MJRefreshConfig.default.i18nFilename = nil 74 | MJRefreshConfig.default.languageCode = nil 75 | MJRefreshConfig.default.i18nBundle = Bundle(path: Bundle.main.path(forResource: "CustomLanguages", ofType: "bundle")!) 76 | default: 77 | MJRefreshConfig.default.i18nFilename = nil 78 | MJRefreshConfig.default.languageCode = nil 79 | MJRefreshConfig.default.i18nBundle = nil 80 | } 81 | 82 | MJRefreshConfig.default.languageCode = languages[indexPath.row] 83 | 84 | let alertC = UIAlertController(title: "⚠️", message: "language changed to '\(languages[indexPath.row])'", preferredStyle: .alert) 85 | 86 | alertC.addAction(UIAlertAction(title: "🎉", style: .destructive)) 87 | 88 | present(alertC, animated: true) 89 | } 90 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/ar.lproj/MJRefresh_i18n.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/ar.lproj/MJRefresh_i18n.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/en.lproj/MJRefresh_i18n.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/en.lproj/MJRefresh_i18n.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/ko.lproj/MJRefresh_i18n.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/ko.lproj/MJRefresh_i18n.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/ru.lproj/MJRefresh_i18n.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/ru.lproj/MJRefresh_i18n.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/uk.lproj/MJRefresh_i18n.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/uk.lproj/MJRefresh_i18n.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/zh-Hans.lproj/MJRefresh_i18n.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/zh-Hans.lproj/MJRefresh_i18n.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/zh-Hant.lproj/MJRefresh_i18n.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Classes/i18n/zh-Hant.lproj/MJRefresh_i18n.strings -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "ipad-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "iphone-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "ipad-29x29.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "ipad-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "iphone-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "ipad-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "iphone-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "iphone-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "iphone-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "ipad-20x20.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "iphone-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "ipad-29x29-1.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "iphone-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "ipad-40x40.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "iphone-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "ipad-76x76.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "ipad-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "ipad-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "ios-marketing-1024x1024.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ios-marketing-1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ios-marketing-1024x1024.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-20x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-20x20.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-20x20@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-29x29-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-29x29-1.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-29x29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-29x29.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-29x29@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-40x40.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-40x40@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-76x76.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-76x76@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/ipad-83.5x83.5@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-20x20@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-20x20@3x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-29x29@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-29x29@3x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-40x40@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-40x40@3x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-60x60@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/AppIcon.appiconset/iphone-60x60@3x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0001@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/dropdown_anim__0001@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/dropdown_anim__0001@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00010@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/dropdown_anim__00010@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/dropdown_anim__00010@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00011@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/dropdown_anim__00011@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/dropdown_anim__00011@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00012@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/dropdown_anim__00012@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/dropdown_anim__00012@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00013@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/dropdown_anim__00013@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/dropdown_anim__00013@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00014@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/dropdown_anim__00014@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/dropdown_anim__00014@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00015@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/dropdown_anim__00015@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/dropdown_anim__00015@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00016@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/dropdown_anim__00016@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/dropdown_anim__00016@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00017@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/dropdown_anim__00017@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/dropdown_anim__00017@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00018@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/dropdown_anim__00018@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/dropdown_anim__00018@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00019@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/dropdown_anim__00019@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/dropdown_anim__00019@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0002@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/dropdown_anim__0002@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/dropdown_anim__0002@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00020@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/dropdown_anim__00020@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/dropdown_anim__00020@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00021@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/dropdown_anim__00021@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/dropdown_anim__00021@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00022@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/dropdown_anim__00022@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/dropdown_anim__00022@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00023@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/dropdown_anim__00023@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/dropdown_anim__00023@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00024@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/dropdown_anim__00024@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/dropdown_anim__00024@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00025@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/dropdown_anim__00025@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/dropdown_anim__00025@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00026@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/dropdown_anim__00026@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/dropdown_anim__00026@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00027@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/dropdown_anim__00027@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/dropdown_anim__00027@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00028@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/dropdown_anim__00028@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/dropdown_anim__00028@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00029@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/dropdown_anim__00029@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/dropdown_anim__00029@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0003@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/dropdown_anim__0003@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/dropdown_anim__0003@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00030@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/dropdown_anim__00030@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/dropdown_anim__00030@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00031@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/dropdown_anim__00031@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/dropdown_anim__00031@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00032@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/dropdown_anim__00032@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/dropdown_anim__00032@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00033@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/dropdown_anim__00033@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/dropdown_anim__00033@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00034@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/dropdown_anim__00034@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/dropdown_anim__00034@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00035@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/dropdown_anim__00035@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/dropdown_anim__00035@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00036@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/dropdown_anim__00036@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/dropdown_anim__00036@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00037@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/dropdown_anim__00037@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/dropdown_anim__00037@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00038@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/dropdown_anim__00038@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/dropdown_anim__00038@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00039@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/dropdown_anim__00039@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/dropdown_anim__00039@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0004@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/dropdown_anim__0004@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/dropdown_anim__0004@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00040@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/dropdown_anim__00040@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/dropdown_anim__00040@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00041@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/dropdown_anim__00041@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/dropdown_anim__00041@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00042@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/dropdown_anim__00042@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/dropdown_anim__00042@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00043@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/dropdown_anim__00043@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/dropdown_anim__00043@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00044@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/dropdown_anim__00044@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/dropdown_anim__00044@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00045@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/dropdown_anim__00045@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/dropdown_anim__00045@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00046@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/dropdown_anim__00046@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/dropdown_anim__00046@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00047@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/dropdown_anim__00047@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/dropdown_anim__00047@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00048@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/dropdown_anim__00048@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/dropdown_anim__00048@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00049@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/dropdown_anim__00049@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/dropdown_anim__00049@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0005@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/dropdown_anim__0005@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/dropdown_anim__0005@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00050@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/dropdown_anim__00050@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/dropdown_anim__00050@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00051@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/dropdown_anim__00051@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/dropdown_anim__00051@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00052@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/dropdown_anim__00052@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/dropdown_anim__00052@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00053@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/dropdown_anim__00053@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/dropdown_anim__00053@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00054@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/dropdown_anim__00054@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/dropdown_anim__00054@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00055@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/dropdown_anim__00055@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/dropdown_anim__00055@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00056@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/dropdown_anim__00056@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/dropdown_anim__00056@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00057@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/dropdown_anim__00057@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/dropdown_anim__00057@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00058@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/dropdown_anim__00058@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/dropdown_anim__00058@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00059@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/dropdown_anim__00059@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/dropdown_anim__00059@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0006@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/dropdown_anim__0006@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/dropdown_anim__0006@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__00060@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/dropdown_anim__00060@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/dropdown_anim__00060@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0007@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/dropdown_anim__0007@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/dropdown_anim__0007@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0008@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/dropdown_anim__0008@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/dropdown_anim__0008@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_anim__0009@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/dropdown_anim__0009@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/dropdown_anim__0009@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_loading_01@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/dropdown_loading_01@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/dropdown_loading_01@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_loading_02@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/dropdown_loading_02@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/dropdown_loading_02@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "dropdown_loading_03@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/dropdown_loading_03@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/dropdown_loading_03@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/MJRefresh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "MJRefresh.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/MJRefresh.imageset/MJRefresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/MJRefresh.imageset/MJRefresh.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/NavBar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "NavBar@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/NavBar.imageset/NavBar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/NavBar.imageset/NavBar@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/NavBar64.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "NavBar64@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/NavBar64.imageset/NavBar64@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/NavBar64.imageset/NavBar64@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "logo.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "logo@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/logo.imageset/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/logo.imageset/logo.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/logo.imageset/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Examples/MJRefreshExample/MJRefreshExample/Images.xcassets/logo.imageset/logo@2x.png -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | MJRefresh 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIMainStoryboardFile 33 | Main 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UISupportedInterfaceOrientations~ipad 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationPortraitUpsideDown 48 | UIInterfaceOrientationLandscapeLeft 49 | UIInterfaceOrientationLandscapeRight 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/MJRefreshExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "MJChiBaoZiHeader.h" 6 | #import "MJCollectionViewController.h" 7 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/9/22. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | #import "MJTempViewController.h" 12 | #endif /* PrefixHeader_pch */ 13 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Examples/MJRefreshExample/MJRefreshExampleTests/MJRefreshExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshExampleTests.m 3 | // MJRefreshExampleTests 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface MJRefreshExampleTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation MJRefreshExampleTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SPMTestExample 4 | // 5 | // Created by Frank on 2021/11/19. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/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 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // SPMTestExample 4 | // 5 | // Created by Frank on 2021/11/19. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | guard let _ = (scene as? UIWindowScene) else { return } 20 | } 21 | 22 | func sceneDidDisconnect(_ scene: UIScene) { 23 | // Called as the scene is being released by the system. 24 | // This occurs shortly after the scene enters the background, or when its session is discarded. 25 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | // Called when the scene has moved from an inactive state to an active state. 31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 32 | } 33 | 34 | func sceneWillResignActive(_ scene: UIScene) { 35 | // Called when the scene will move from an active state to an inactive state. 36 | // This may occur due to temporary interruptions (ex. an incoming phone call). 37 | } 38 | 39 | func sceneWillEnterForeground(_ scene: UIScene) { 40 | // Called as the scene transitions from the background to the foreground. 41 | // Use this method to undo the changes made on entering the background. 42 | } 43 | 44 | func sceneDidEnterBackground(_ scene: UIScene) { 45 | // Called as the scene transitions from the foreground to the background. 46 | // Use this method to save data, release shared resources, and store enough scene-specific state information 47 | // to restore the scene back to its current state. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Examples/SPMTestExample/SPMTestExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SPMTestExample 4 | // 5 | // Created by Frank on 2021/11/19. 6 | // 7 | 8 | import UIKit 9 | import MJRefresh 10 | 11 | class ViewController: UITableViewController { 12 | 13 | var itemsCount = 5 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | MJRefreshNormalHeader { 19 | DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { [weak self] in 20 | guard let self = self else { return } 21 | 22 | self.itemsCount += Int.random(in: 1...5) 23 | self.tableView.reloadData() 24 | 25 | self.tableView.mj_header?.endRefreshing() 26 | } 27 | }.autoChangeTransparency(true).link(to: self.tableView) 28 | } 29 | 30 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 31 | return itemsCount 32 | } 33 | 34 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 35 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! 36 | 37 | cell.textLabel?.text = "\(indexPath.row)" 38 | return cell 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Gif/trailer_refresh.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/Gif/trailer_refresh.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /MJRefresh.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'MJRefresh' 3 | s.version = '3.7.9' 4 | s.summary = 'An easy way to use pull-to-refresh' 5 | s.homepage = 'https://github.com/CoderMJLee/MJRefresh' 6 | s.license = 'MIT' 7 | s.authors = {'MJ Lee' => 'richermj123go@vip.qq.com'} 8 | s.platform = :ios, '12.0' 9 | s.source = {:git => 'https://github.com/CoderMJLee/MJRefresh.git', :tag => s.version} 10 | s.source_files = 'MJRefresh/**/*.{h,m}' 11 | s.exclude_files = 'MJRefresh/include/**' 12 | s.resource = 'MJRefresh/MJRefresh.bundle' 13 | s.resource_bundles = { 'MJRefresh.Privacy' => 'MJRefresh/PrivacyInfo.xcprivacy' } 14 | s.requires_arc = true 15 | end 16 | -------------------------------------------------------------------------------- /MJRefresh.xcodeproj/xcshareddata/xcschemes/MJRefresh.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /MJRefresh/Base/MJRefreshAutoFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshAutoFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshAutoFooter : MJRefreshFooter 18 | /** 是否自动刷新(默认为YES) */ 19 | @property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; 20 | 21 | /** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ 22 | @property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; 23 | 24 | /** 自动触发次数, 默认为 1, 仅在拖拽 ScrollView 时才生效, 25 | 26 | 如果为 -1, 则为无限触发 27 | */ 28 | @property (nonatomic) NSInteger autoTriggerTimes; 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /MJRefresh/Base/MJRefreshBackFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshBackFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshBackFooter : MJRefreshFooter 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /MJRefresh/Base/MJRefreshFooter.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJRefreshFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/3/5. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 上拉刷新控件 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshComponent.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshFooter : MJRefreshComponent 18 | /** 创建footer */ 19 | + (instancetype)footerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; 20 | /** 创建footer */ 21 | + (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; 22 | 23 | /** 提示没有更多的数据 */ 24 | - (void)endRefreshingWithNoMoreData; 25 | - (void)noticeNoMoreData MJRefreshDeprecated("使用endRefreshingWithNoMoreData"); 26 | 27 | /** 重置没有更多的数据(消除没有更多数据的状态) */ 28 | - (void)resetNoMoreData; 29 | 30 | /** 忽略多少scrollView的contentInset的bottom */ 31 | @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; 32 | 33 | /** 自动根据有无数据来显示和隐藏(有数据就显示,没有数据隐藏。默认是NO) */ 34 | @property (assign, nonatomic, getter=isAutomaticallyHidden) BOOL automaticallyHidden MJRefreshDeprecated("已废弃此属性,开发者请自行控制footer的显示和隐藏"); 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /MJRefresh/Base/MJRefreshFooter.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJRefreshFooter.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/3/5. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshFooter.h" 10 | #import "UIScrollView+MJRefresh.h" 11 | #import "UIView+MJExtension.h" 12 | 13 | @interface MJRefreshFooter() 14 | 15 | @end 16 | 17 | @implementation MJRefreshFooter 18 | #pragma mark - 构造方法 19 | + (instancetype)footerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock 20 | { 21 | MJRefreshFooter *cmp = [[self alloc] init]; 22 | cmp.refreshingBlock = refreshingBlock; 23 | return cmp; 24 | } 25 | + (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action 26 | { 27 | MJRefreshFooter *cmp = [[self alloc] init]; 28 | [cmp setRefreshingTarget:target refreshingAction:action]; 29 | return cmp; 30 | } 31 | 32 | #pragma mark - 重写父类的方法 33 | - (void)prepare 34 | { 35 | [super prepare]; 36 | 37 | // 设置自己的高度 38 | self.mj_h = MJRefreshFooterHeight; 39 | 40 | // 默认不会自动隐藏 41 | // self.automaticallyHidden = NO; 42 | } 43 | 44 | #pragma mark . 链式语法部分 . 45 | 46 | - (instancetype)linkTo:(UIScrollView *)scrollView { 47 | scrollView.mj_footer = self; 48 | return self; 49 | } 50 | 51 | #pragma mark - 公共方法 52 | - (void)endRefreshingWithNoMoreData 53 | { 54 | MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateNoMoreData;) 55 | } 56 | 57 | - (void)noticeNoMoreData 58 | { 59 | [self endRefreshingWithNoMoreData]; 60 | } 61 | 62 | - (void)resetNoMoreData 63 | { 64 | MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;) 65 | } 66 | 67 | - (void)setAutomaticallyHidden:(BOOL)automaticallyHidden 68 | { 69 | _automaticallyHidden = automaticallyHidden; 70 | } 71 | @end 72 | -------------------------------------------------------------------------------- /MJRefresh/Base/MJRefreshHeader.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // MJRefreshHeader.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 下拉刷新控件:负责监控用户下拉的状态 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshComponent.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshHeader : MJRefreshComponent 18 | /** 创建header */ 19 | + (instancetype)headerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; 20 | /** 创建header */ 21 | + (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; 22 | 23 | /** 这个key用来存储上一次下拉刷新成功的时间 */ 24 | @property (copy, nonatomic) NSString *lastUpdatedTimeKey; 25 | /** 上一次下拉刷新成功的时间 */ 26 | @property (strong, nonatomic, readonly, nullable) NSDate *lastUpdatedTime; 27 | 28 | /** 忽略多少scrollView的contentInset的top */ 29 | @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; 30 | 31 | /** 默认是关闭状态, 如果遇到 CollectionView 的动画异常问题可以尝试打开 */ 32 | @property (nonatomic) BOOL isCollectionViewAnimationBug; 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /MJRefresh/Base/MJRefreshTrailer.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshTrailer.h 3 | // MJRefresh 4 | // 5 | // Created by kinarobin on 2020/5/3. 6 | // Copyright © 2020 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshComponent.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshTrailer : MJRefreshComponent 18 | 19 | /** 创建trailer*/ 20 | + (instancetype)trailerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; 21 | /** 创建trailer */ 22 | + (instancetype)trailerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; 23 | 24 | /** 忽略多少scrollView的contentInset的right */ 25 | @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetRight; 26 | 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshAutoGifFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshAutoStateFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshAutoGifFooter : MJRefreshAutoStateFooter 18 | @property (weak, nonatomic, readonly) UIImageView *gifView; 19 | 20 | /** 设置state状态下的动画图片images 动画持续时间duration*/ 21 | - (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; 22 | - (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state; 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshAutoGifFooter.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshAutoGifFooter.h" 10 | #import "NSBundle+MJRefresh.h" 11 | #import "UIView+MJExtension.h" 12 | #import "UIScrollView+MJExtension.h" 13 | #import "UIScrollView+MJRefresh.h" 14 | 15 | @interface MJRefreshAutoGifFooter() 16 | { 17 | __unsafe_unretained UIImageView *_gifView; 18 | } 19 | /** 所有状态对应的动画图片 */ 20 | @property (strong, nonatomic) NSMutableDictionary *stateImages; 21 | /** 所有状态对应的动画时间 */ 22 | @property (strong, nonatomic) NSMutableDictionary *stateDurations; 23 | @end 24 | 25 | @implementation MJRefreshAutoGifFooter 26 | #pragma mark - 懒加载 27 | - (UIImageView *)gifView 28 | { 29 | if (!_gifView) { 30 | UIImageView *gifView = [[UIImageView alloc] init]; 31 | [self addSubview:_gifView = gifView]; 32 | } 33 | return _gifView; 34 | } 35 | 36 | - (NSMutableDictionary *)stateImages 37 | { 38 | if (!_stateImages) { 39 | self.stateImages = [NSMutableDictionary dictionary]; 40 | } 41 | return _stateImages; 42 | } 43 | 44 | - (NSMutableDictionary *)stateDurations 45 | { 46 | if (!_stateDurations) { 47 | self.stateDurations = [NSMutableDictionary dictionary]; 48 | } 49 | return _stateDurations; 50 | } 51 | 52 | #pragma mark - 公共方法 53 | - (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state 54 | { 55 | if (images == nil) return self; 56 | 57 | self.stateImages[@(state)] = images; 58 | self.stateDurations[@(state)] = @(duration); 59 | 60 | /* 根据图片设置控件的高度 */ 61 | UIImage *image = [images firstObject]; 62 | if (image.size.height > self.mj_h) { 63 | self.mj_h = image.size.height; 64 | } 65 | return self; 66 | } 67 | 68 | - (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state 69 | { 70 | return [self setImages:images duration:images.count * 0.1 forState:state]; 71 | } 72 | 73 | #pragma mark - 实现父类的方法 74 | - (void)prepare 75 | { 76 | [super prepare]; 77 | 78 | // 初始化间距 79 | self.labelLeftInset = 20; 80 | } 81 | 82 | - (void)placeSubviews 83 | { 84 | [super placeSubviews]; 85 | 86 | if (self.gifView.constraints.count) return; 87 | 88 | self.gifView.frame = self.bounds; 89 | if (self.isRefreshingTitleHidden) { 90 | self.gifView.contentMode = UIViewContentModeCenter; 91 | } else { 92 | self.gifView.contentMode = UIViewContentModeRight; 93 | self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWidth * 0.5; 94 | } 95 | } 96 | 97 | - (void)setState:(MJRefreshState)state 98 | { 99 | MJRefreshCheckState 100 | 101 | // 根据状态做事情 102 | if (state == MJRefreshStateRefreshing) { 103 | NSArray *images = self.stateImages[@(state)]; 104 | if (images.count == 0) return; 105 | [self.gifView stopAnimating]; 106 | 107 | self.gifView.hidden = NO; 108 | if (images.count == 1) { // 单张图片 109 | self.gifView.image = [images lastObject]; 110 | } else { // 多张图片 111 | self.gifView.animationImages = images; 112 | self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; 113 | [self.gifView startAnimating]; 114 | } 115 | } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { 116 | [self.gifView stopAnimating]; 117 | self.gifView.hidden = YES; 118 | } 119 | } 120 | 121 | - (NSArray *)flipsHorizontallyInOppositeLayoutDirectionViews { 122 | return [super.flipsHorizontallyInOppositeLayoutDirectionViews arrayByAddingObjectsFromArray:@[ 123 | self.gifView 124 | ]]; 125 | } 126 | 127 | @end 128 | 129 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshAutoNormalFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshAutoStateFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshAutoNormalFooter : MJRefreshAutoStateFooter 18 | @property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; 19 | 20 | /** 菊花的样式 */ 21 | @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); 22 | @end 23 | 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshAutoNormalFooter.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshAutoNormalFooter.h" 10 | #import "NSBundle+MJRefresh.h" 11 | #import "UIView+MJExtension.h" 12 | #import "UIScrollView+MJExtension.h" 13 | #import "UIScrollView+MJRefresh.h" 14 | 15 | @interface MJRefreshAutoNormalFooter() 16 | @property (weak, nonatomic) UIActivityIndicatorView *loadingView; 17 | @end 18 | 19 | @implementation MJRefreshAutoNormalFooter 20 | #pragma mark - 懒加载子控件 21 | - (UIActivityIndicatorView *)loadingView 22 | { 23 | if (!_loadingView) { 24 | UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; 25 | loadingView.hidesWhenStopped = YES; 26 | [self addSubview:_loadingView = loadingView]; 27 | } 28 | return _loadingView; 29 | } 30 | 31 | - (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle 32 | { 33 | _activityIndicatorViewStyle = activityIndicatorViewStyle; 34 | 35 | [self.loadingView removeFromSuperview]; 36 | self.loadingView = nil; 37 | [self setNeedsLayout]; 38 | } 39 | #pragma mark - 重写父类的方法 40 | - (void)prepare 41 | { 42 | [super prepare]; 43 | 44 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 45 | if (@available(iOS 13.0, *)) { 46 | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; 47 | return; 48 | } 49 | #endif 50 | 51 | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; 52 | } 53 | 54 | - (void)placeSubviews 55 | { 56 | [super placeSubviews]; 57 | 58 | if (self.loadingView.constraints.count) return; 59 | 60 | // 圈圈 61 | CGFloat loadingCenterX = self.mj_w * 0.5; 62 | if (!self.isRefreshingTitleHidden) { 63 | loadingCenterX -= self.stateLabel.mj_textWidth * 0.5 + self.labelLeftInset; 64 | } 65 | CGFloat loadingCenterY = self.mj_h * 0.5; 66 | self.loadingView.center = CGPointMake(loadingCenterX, loadingCenterY); 67 | } 68 | 69 | - (void)setState:(MJRefreshState)state 70 | { 71 | MJRefreshCheckState 72 | 73 | // 根据状态做事情 74 | if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { 75 | [self.loadingView stopAnimating]; 76 | } else if (state == MJRefreshStateRefreshing) { 77 | [self.loadingView startAnimating]; 78 | } 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshAutoStateFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshAutoFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshAutoStateFooter : MJRefreshAutoFooter 18 | /** 文字距离圈圈、箭头的距离 */ 19 | @property (assign, nonatomic) CGFloat labelLeftInset; 20 | /** 显示刷新状态的label */ 21 | @property (weak, nonatomic, readonly) UILabel *stateLabel; 22 | 23 | /** 设置state状态下的文字 */ 24 | - (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; 25 | 26 | /** 隐藏刷新状态的文字 */ 27 | @property (assign, nonatomic, getter=isRefreshingTitleHidden) BOOL refreshingTitleHidden; 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshAutoStateFooter.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshAutoStateFooter.h" 10 | #import "NSBundle+MJRefresh.h" 11 | 12 | @interface MJRefreshAutoFooter (TapTriggerFix) 13 | 14 | - (void)beginRefreshingWithoutValidation; 15 | @end 16 | 17 | 18 | @implementation MJRefreshAutoFooter (TapTriggerFix) 19 | 20 | - (void)beginRefreshingWithoutValidation { 21 | [super beginRefreshing]; 22 | } 23 | 24 | @end 25 | 26 | @interface MJRefreshAutoStateFooter() 27 | { 28 | /** 显示刷新状态的label */ 29 | __unsafe_unretained UILabel *_stateLabel; 30 | } 31 | /** 所有状态对应的文字 */ 32 | @property (strong, nonatomic) NSMutableDictionary *stateTitles; 33 | @end 34 | 35 | @implementation MJRefreshAutoStateFooter 36 | #pragma mark - 懒加载 37 | - (NSMutableDictionary *)stateTitles 38 | { 39 | if (!_stateTitles) { 40 | self.stateTitles = [NSMutableDictionary dictionary]; 41 | } 42 | return _stateTitles; 43 | } 44 | 45 | - (UILabel *)stateLabel 46 | { 47 | if (!_stateLabel) { 48 | [self addSubview:_stateLabel = [UILabel mj_label]]; 49 | } 50 | return _stateLabel; 51 | } 52 | 53 | #pragma mark - 公共方法 54 | - (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state 55 | { 56 | if (title == nil) return self; 57 | self.stateTitles[@(state)] = title; 58 | self.stateLabel.text = self.stateTitles[@(self.state)]; 59 | return self; 60 | } 61 | 62 | #pragma mark - 私有方法 63 | - (void)stateLabelClick 64 | { 65 | if (self.state == MJRefreshStateIdle) { 66 | [super beginRefreshingWithoutValidation]; 67 | } 68 | } 69 | 70 | - (void)textConfiguration { 71 | // 初始化文字 72 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterIdleText] forState:MJRefreshStateIdle]; 73 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterRefreshingText] forState:MJRefreshStateRefreshing]; 74 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; 75 | } 76 | 77 | #pragma mark - 重写父类的方法 78 | - (void)prepare 79 | { 80 | [super prepare]; 81 | 82 | // 初始化间距 83 | self.labelLeftInset = MJRefreshLabelLeftInset; 84 | 85 | [self textConfiguration]; 86 | 87 | // 监听label 88 | self.stateLabel.userInteractionEnabled = YES; 89 | [self.stateLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stateLabelClick)]]; 90 | } 91 | 92 | - (void)i18nDidChange { 93 | [self textConfiguration]; 94 | 95 | [super i18nDidChange]; 96 | } 97 | 98 | 99 | - (void)placeSubviews 100 | { 101 | [super placeSubviews]; 102 | 103 | if (self.stateLabel.constraints.count) return; 104 | 105 | // 状态标签 106 | self.stateLabel.frame = self.bounds; 107 | } 108 | 109 | - (void)setState:(MJRefreshState)state 110 | { 111 | MJRefreshCheckState 112 | 113 | if (self.isRefreshingTitleHidden && state == MJRefreshStateRefreshing) { 114 | self.stateLabel.text = nil; 115 | } else { 116 | self.stateLabel.text = self.stateTitles[@(state)]; 117 | } 118 | } 119 | 120 | - (NSArray *)flipsHorizontallyInOppositeLayoutDirectionViews { 121 | return @[ 122 | self.stateLabel 123 | ]; 124 | } 125 | @end 126 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshBackGifFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshBackStateFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshBackGifFooter : MJRefreshBackStateFooter 18 | @property (weak, nonatomic, readonly) UIImageView *gifView; 19 | 20 | /** 设置state状态下的动画图片images 动画持续时间duration*/ 21 | - (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; 22 | - (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state; 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshBackNormalFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshBackStateFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshBackNormalFooter : MJRefreshBackStateFooter 18 | @property (weak, nonatomic, readonly) UIImageView *arrowView; 19 | @property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; 20 | 21 | /** 菊花的样式 */ 22 | @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshBackStateFooter.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshBackFooter.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshBackStateFooter : MJRefreshBackFooter 18 | /** 文字距离圈圈、箭头的距离 */ 19 | @property (assign, nonatomic) CGFloat labelLeftInset; 20 | /** 显示刷新状态的label */ 21 | @property (weak, nonatomic, readonly) UILabel *stateLabel; 22 | /** 设置state状态下的文字 */ 23 | - (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; 24 | 25 | /** 获取state状态下的title */ 26 | - (NSString *)titleForState:(MJRefreshState)state; 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshBackStateFooter.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/6/13. 6 | // Copyright © 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshBackStateFooter.h" 10 | #import "NSBundle+MJRefresh.h" 11 | 12 | @interface MJRefreshBackStateFooter() 13 | { 14 | /** 显示刷新状态的label */ 15 | __unsafe_unretained UILabel *_stateLabel; 16 | } 17 | /** 所有状态对应的文字 */ 18 | @property (strong, nonatomic) NSMutableDictionary *stateTitles; 19 | @end 20 | 21 | @implementation MJRefreshBackStateFooter 22 | #pragma mark - 懒加载 23 | - (NSMutableDictionary *)stateTitles 24 | { 25 | if (!_stateTitles) { 26 | self.stateTitles = [NSMutableDictionary dictionary]; 27 | } 28 | return _stateTitles; 29 | } 30 | 31 | - (UILabel *)stateLabel 32 | { 33 | if (!_stateLabel) { 34 | [self addSubview:_stateLabel = [UILabel mj_label]]; 35 | } 36 | return _stateLabel; 37 | } 38 | 39 | #pragma mark - 公共方法 40 | - (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state 41 | { 42 | if (title == nil) return self; 43 | self.stateTitles[@(state)] = title; 44 | self.stateLabel.text = self.stateTitles[@(self.state)]; 45 | return self; 46 | } 47 | 48 | - (NSString *)titleForState:(MJRefreshState)state { 49 | return self.stateTitles[@(state)]; 50 | } 51 | 52 | - (void)textConfiguration { 53 | // 初始化文字 54 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterIdleText] forState:MJRefreshStateIdle]; 55 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterPullingText] forState:MJRefreshStatePulling]; 56 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterRefreshingText] forState:MJRefreshStateRefreshing]; 57 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; 58 | } 59 | 60 | #pragma mark - 重写父类的方法 61 | - (void)prepare 62 | { 63 | [super prepare]; 64 | 65 | // 初始化间距 66 | self.labelLeftInset = MJRefreshLabelLeftInset; 67 | [self textConfiguration]; 68 | } 69 | 70 | - (void)i18nDidChange { 71 | [self textConfiguration]; 72 | 73 | [super i18nDidChange]; 74 | } 75 | 76 | - (void)placeSubviews 77 | { 78 | [super placeSubviews]; 79 | 80 | if (self.stateLabel.constraints.count) return; 81 | 82 | // 状态标签 83 | self.stateLabel.frame = self.bounds; 84 | } 85 | 86 | - (void)setState:(MJRefreshState)state 87 | { 88 | MJRefreshCheckState 89 | 90 | // 设置状态文字 91 | self.stateLabel.text = self.stateTitles[@(state)]; 92 | } 93 | 94 | - (NSArray *)flipsHorizontallyInOppositeLayoutDirectionViews { 95 | return @[ 96 | self.stateLabel 97 | ]; 98 | } 99 | @end 100 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Header/MJRefreshGifHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshGifHeader.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshStateHeader.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshGifHeader : MJRefreshStateHeader 18 | @property (weak, nonatomic, readonly) UIImageView *gifView; 19 | 20 | /** 设置state状态下的动画图片images 动画持续时间duration*/ 21 | - (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; 22 | - (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state; 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Header/MJRefreshNormalHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshNormalHeader.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshStateHeader.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshNormalHeader : MJRefreshStateHeader 18 | @property (weak, nonatomic, readonly) UIImageView *arrowView; 19 | @property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; 20 | 21 | 22 | /** 菊花的样式 */ 23 | @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Header/MJRefreshStateHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshStateHeader.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/4/24. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshHeader.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshStateHeader : MJRefreshHeader 18 | #pragma mark - 刷新时间相关 19 | /** 利用这个block来决定显示的更新时间文字 */ 20 | @property (copy, nonatomic, nullable) NSString *(^lastUpdatedTimeText)(NSDate * _Nullable lastUpdatedTime); 21 | /** 显示上一次刷新时间的label */ 22 | @property (weak, nonatomic, readonly) UILabel *lastUpdatedTimeLabel; 23 | 24 | #pragma mark - 状态相关 25 | /** 文字距离圈圈、箭头的距离 */ 26 | @property (assign, nonatomic) CGFloat labelLeftInset; 27 | /** 显示刷新状态的label */ 28 | @property (weak, nonatomic, readonly) UILabel *stateLabel; 29 | /** 设置state状态下的文字 */ 30 | - (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; 31 | @end 32 | 33 | @interface MJRefreshStateHeader (ChainingGrammar) 34 | 35 | - (instancetype)modifyLastUpdatedTimeText:(NSString * (^)(NSDate * _Nullable lastUpdatedTime))handler; 36 | 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshNormalTrailer.h 3 | // MJRefresh 4 | // 5 | // Created by kinarobin on 2020/5/3. 6 | // Copyright © 2020 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshStateTrailer.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface MJRefreshNormalTrailer : MJRefreshStateTrailer 18 | 19 | @property (weak, nonatomic, readonly) UIImageView *arrowView; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshNormalTrailer.m 3 | // MJRefresh 4 | // 5 | // Created by kinarobin on 2020/5/3. 6 | // Copyright © 2020 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshNormalTrailer.h" 10 | #import "NSBundle+MJRefresh.h" 11 | #import "UIView+MJExtension.h" 12 | 13 | @interface MJRefreshNormalTrailer() { 14 | __unsafe_unretained UIImageView *_arrowView; 15 | } 16 | @end 17 | 18 | @implementation MJRefreshNormalTrailer 19 | #pragma mark - 懒加载子控件 20 | - (UIImageView *)arrowView { 21 | if (!_arrowView) { 22 | UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_trailArrowImage]]; 23 | [self addSubview:_arrowView = arrowView]; 24 | } 25 | return _arrowView; 26 | } 27 | 28 | - (void)placeSubviews { 29 | [super placeSubviews]; 30 | 31 | CGSize arrowSize = self.arrowView.image.size; 32 | // 箭头的中心点 33 | CGPoint selfCenter = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5); 34 | CGPoint arrowCenter = CGPointMake(arrowSize.width * 0.5 + 5, self.mj_h * 0.5); 35 | BOOL stateHidden = self.stateLabel.isHidden; 36 | 37 | if (self.arrowView.constraints.count == 0) { 38 | self.arrowView.mj_size = self.arrowView.image.size; 39 | self.arrowView.center = stateHidden ? selfCenter : arrowCenter ; 40 | } 41 | self.arrowView.tintColor = self.stateLabel.textColor; 42 | 43 | if (stateHidden) return; 44 | 45 | BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; 46 | CGFloat stateLabelW = ceil(self.stateLabel.font.pointSize); 47 | // 状态 48 | if (noConstrainsOnStatusLabel) { 49 | BOOL arrowHidden = self.arrowView.isHidden; 50 | CGFloat stateCenterX = (self.mj_w + arrowSize.width) * 0.5; 51 | self.stateLabel.center = arrowHidden ? selfCenter : CGPointMake(stateCenterX, self.mj_h * 0.5); 52 | self.stateLabel.mj_size = CGSizeMake(stateLabelW, self.mj_h) ; 53 | } 54 | } 55 | 56 | - (void)setState:(MJRefreshState)state { 57 | MJRefreshCheckState 58 | // 根据状态做事情 59 | if (state == MJRefreshStateIdle) { 60 | if (oldState == MJRefreshStateRefreshing) { 61 | [UIView animateWithDuration:self.fastAnimationDuration animations:^{ 62 | self.arrowView.transform = CGAffineTransformMakeRotation(M_PI); 63 | } completion:^(BOOL finished) { 64 | self.arrowView.transform = CGAffineTransformIdentity; 65 | }]; 66 | } else { 67 | [UIView animateWithDuration:self.fastAnimationDuration animations:^{ 68 | self.arrowView.transform = CGAffineTransformIdentity; 69 | }]; 70 | } 71 | } else if (state == MJRefreshStatePulling) { 72 | [UIView animateWithDuration:self.fastAnimationDuration animations:^{ 73 | self.arrowView.transform = CGAffineTransformMakeRotation(M_PI); 74 | }]; 75 | } 76 | } 77 | 78 | - (NSArray *)flipsHorizontallyInOppositeLayoutDirectionViews { 79 | return [super.flipsHorizontallyInOppositeLayoutDirectionViews arrayByAddingObjectsFromArray:@[ 80 | self.arrowView 81 | ]]; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Trailer/MJRefreshStateTrailer.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshStateTrailer.h 3 | // MJRefresh 4 | // 5 | // Created by kinarobin on 2020/5/3. 6 | // Copyright © 2020 小码哥. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import 11 | #else 12 | #import "MJRefreshTrailer.h" 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | 18 | @interface MJRefreshStateTrailer : MJRefreshTrailer 19 | 20 | #pragma mark - 状态相关 21 | /** 显示刷新状态的label */ 22 | @property (weak, nonatomic, readonly) UILabel *stateLabel; 23 | /** 设置state状态下的文字 */ 24 | - (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /MJRefresh/Custom/Trailer/MJRefreshStateTrailer.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshStateTrailer.m 3 | // MJRefresh 4 | // 5 | // Created by kinarobin on 2020/5/3. 6 | // Copyright © 2020 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshStateTrailer.h" 10 | #import "NSBundle+MJRefresh.h" 11 | #import "UIView+MJExtension.h" 12 | 13 | @interface MJRefreshStateTrailer() { 14 | /** 显示刷新状态的label */ 15 | __unsafe_unretained UILabel *_stateLabel; 16 | } 17 | /** 所有状态对应的文字 */ 18 | @property (strong, nonatomic) NSMutableDictionary *stateTitles; 19 | @end 20 | 21 | @implementation MJRefreshStateTrailer 22 | #pragma mark - 懒加载 23 | - (NSMutableDictionary *)stateTitles { 24 | if (!_stateTitles) { 25 | self.stateTitles = [NSMutableDictionary dictionary]; 26 | } 27 | return _stateTitles; 28 | } 29 | 30 | - (UILabel *)stateLabel { 31 | if (!_stateLabel) { 32 | UILabel *stateLabel = [UILabel mj_label]; 33 | stateLabel.numberOfLines = 0; 34 | [self addSubview:_stateLabel = stateLabel]; 35 | } 36 | return _stateLabel; 37 | } 38 | 39 | #pragma mark - 公共方法 40 | - (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state { 41 | if (title == nil) return self; 42 | self.stateTitles[@(state)] = title; 43 | self.stateLabel.text = self.stateTitles[@(self.state)]; 44 | return self; 45 | } 46 | 47 | - (void)textConfiguration { 48 | // 初始化文字 49 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerIdleText] forState:MJRefreshStateIdle]; 50 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerPullingText] forState:MJRefreshStatePulling]; 51 | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerPullingText] forState:MJRefreshStateRefreshing]; 52 | } 53 | 54 | #pragma mark - 覆盖父类的方法 55 | - (void)prepare { 56 | [super prepare]; 57 | 58 | [self textConfiguration]; 59 | } 60 | 61 | - (void)i18nDidChange { 62 | [self textConfiguration]; 63 | 64 | [super i18nDidChange]; 65 | } 66 | 67 | - (void)setState:(MJRefreshState)state { 68 | MJRefreshCheckState 69 | // 设置状态文字 70 | self.stateLabel.text = self.stateTitles[@(state)]; 71 | } 72 | 73 | - (void)placeSubviews { 74 | [super placeSubviews]; 75 | 76 | if (self.stateLabel.hidden) return; 77 | 78 | BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; 79 | CGFloat stateLabelW = ceil(self.stateLabel.font.pointSize); 80 | // 状态 81 | if (noConstrainsOnStatusLabel) { 82 | self.stateLabel.center = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5); 83 | self.stateLabel.mj_size = CGSizeMake(stateLabelW, self.mj_h) ; 84 | } 85 | } 86 | 87 | - (NSArray *)flipsHorizontallyInOppositeLayoutDirectionViews { 88 | return @[ 89 | self.stateLabel 90 | ]; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /MJRefresh/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/MJRefresh/MJRefresh.bundle/arrow@2x.png -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/ko.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | "MJRefreshHeaderIdleText" = "아래로 당겨 새로고침"; 2 | "MJRefreshHeaderPullingText" = "놓으면 새로고침"; 3 | "MJRefreshHeaderRefreshingText" = "로딩중..."; 4 | 5 | "MJRefreshAutoFooterIdleText" = "탭 또는 위로 당겨 로드함"; 6 | "MJRefreshAutoFooterRefreshingText" = "로딩중..."; 7 | "MJRefreshAutoFooterNoMoreDataText" = "더이상 데이터 없음"; 8 | 9 | "MJRefreshBackFooterIdleText" = "위로 당겨 더 로드 가능"; 10 | "MJRefreshBackFooterPullingText" = "놓으면 더 로드됨."; 11 | "MJRefreshBackFooterRefreshingText" = "로딩중..."; 12 | "MJRefreshBackFooterNoMoreDataText" = "더이상 데이터 없음"; 13 | 14 | "MJRefreshHeaderLastTimeText" = "마지막 업데이트: "; 15 | "MJRefreshHeaderDateTodayText" = "오늘"; 16 | "MJRefreshHeaderNoneLastDateText" = "기록 없음"; 17 | -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/ru.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/MJRefresh/MJRefresh.bundle/ru.lproj/Localizable.strings -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/trail_arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/MJRefresh/MJRefresh.bundle/trail_arrow@2x.png -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/uk.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/MJRefresh/MJRefresh.bundle/uk.lproj/Localizable.strings -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderMJLee/MJRefresh/5647d82cd7e0de8c59980c6cb2afff173978f481/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | "MJRefreshHeaderIdleText" = "下拉可以刷新"; 2 | "MJRefreshHeaderPullingText" = "鬆開立即刷新"; 3 | "MJRefreshHeaderRefreshingText" = "正在刷新數據中..."; 4 | 5 | "MJRefreshTrailerIdleText" = "滑動查看圖文詳情"; 6 | "MJRefreshTrailerPullingText" = "釋放查看圖文詳情"; 7 | 8 | "MJRefreshAutoFooterIdleText" = "點擊或上拉加載更多"; 9 | "MJRefreshAutoFooterRefreshingText" = "正在加載更多的數據..."; 10 | "MJRefreshAutoFooterNoMoreDataText" = "已經全部加載完畢"; 11 | 12 | "MJRefreshBackFooterIdleText" = "上拉可以加載更多"; 13 | "MJRefreshBackFooterPullingText" = "鬆開立即加載更多"; 14 | "MJRefreshBackFooterRefreshingText" = "正在加載更多的數據..."; 15 | "MJRefreshBackFooterNoMoreDataText" = "已經全部加載完畢"; 16 | 17 | "MJRefreshHeaderLastTimeText" = "最後更新:"; 18 | "MJRefreshHeaderDateTodayText" = "今天"; 19 | "MJRefreshHeaderNoneLastDateText" = "無記錄"; 20 | -------------------------------------------------------------------------------- /MJRefresh/MJRefresh.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | 3 | #import 4 | 5 | #if __has_include() 6 | FOUNDATION_EXPORT double MJRefreshVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char MJRefreshVersionString[]; 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | 16 | #import 17 | #import 18 | #import 19 | #import 20 | 21 | #import 22 | #import 23 | #import 24 | #import 25 | #else 26 | #import "UIScrollView+MJRefresh.h" 27 | #import "UIScrollView+MJExtension.h" 28 | #import "UIView+MJExtension.h" 29 | 30 | #import "MJRefreshNormalHeader.h" 31 | #import "MJRefreshGifHeader.h" 32 | 33 | #import "MJRefreshBackNormalFooter.h" 34 | #import "MJRefreshBackGifFooter.h" 35 | #import "MJRefreshAutoNormalFooter.h" 36 | #import "MJRefreshAutoGifFooter.h" 37 | 38 | #import "MJRefreshNormalTrailer.h" 39 | #import "MJRefreshConfig.h" 40 | #import "NSBundle+MJRefresh.h" 41 | #import "MJRefreshConst.h" 42 | #endif 43 | -------------------------------------------------------------------------------- /MJRefresh/MJRefreshConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshConfig.h 3 | // 4 | // Created by Frank on 2018/11/27. 5 | // Copyright © 2018 小码哥. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface MJRefreshConfig : NSObject 13 | 14 | /** 默认使用的语言版本, 默认为 nil. 将随系统的语言自动改变 */ 15 | @property (copy, nonatomic, nullable) NSString *languageCode; 16 | 17 | /** 默认使用的语言资源文件名, 默认为 nil, 即默认的 Localizable.strings. 18 | 19 | - Attention: 文件名不包含后缀.strings 20 | */ 21 | @property (copy, nonatomic, nullable) NSString *i18nFilename; 22 | /** i18n 多语言资源加载自定义 Bundle. 23 | 24 | - Attention: 默认为 nil 采用内置逻辑. 这里设置后将忽略内置逻辑的多语言模式, 采用自定义的多语言 bundle 25 | */ 26 | @property (nonatomic, nullable) NSBundle *i18nBundle; 27 | 28 | /** Singleton Config instance */ 29 | @property (class, nonatomic, readonly) MJRefreshConfig *defaultConfig; 30 | 31 | - (instancetype)init NS_UNAVAILABLE; 32 | + (instancetype)new NS_UNAVAILABLE; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /MJRefresh/MJRefreshConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshConfig.m 3 | // 4 | // Created by Frank on 2018/11/27. 5 | // Copyright © 2018 小码哥. All rights reserved. 6 | // 7 | 8 | #import "MJRefreshConfig.h" 9 | #import "MJRefreshConst.h" 10 | #import "NSBundle+MJRefresh.h" 11 | 12 | @interface MJRefreshConfig (Bundle) 13 | 14 | + (void)resetLanguageResourceCache; 15 | 16 | @end 17 | 18 | @implementation MJRefreshConfig 19 | 20 | static MJRefreshConfig *mj_RefreshConfig = nil; 21 | 22 | + (instancetype)defaultConfig { 23 | static dispatch_once_t onceToken; 24 | dispatch_once(&onceToken, ^{ 25 | mj_RefreshConfig = [[self alloc] init]; 26 | }); 27 | return mj_RefreshConfig; 28 | } 29 | 30 | - (void)setLanguageCode:(NSString *)languageCode { 31 | if ([languageCode isEqualToString:_languageCode]) { 32 | return; 33 | } 34 | 35 | _languageCode = languageCode; 36 | // 重置语言资源 37 | [MJRefreshConfig resetLanguageResourceCache]; 38 | [NSNotificationCenter.defaultCenter 39 | postNotificationName:MJRefreshDidChangeLanguageNotification object:self]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /MJRefresh/MJRefreshConst.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | #import 3 | 4 | const CGFloat MJRefreshLabelLeftInset = 25; 5 | const CGFloat MJRefreshHeaderHeight = 54.0; 6 | const CGFloat MJRefreshFooterHeight = 44.0; 7 | const CGFloat MJRefreshTrailWidth = 60.0; 8 | const CGFloat MJRefreshFastAnimationDuration = 0.25; 9 | const CGFloat MJRefreshSlowAnimationDuration = 0.4; 10 | 11 | 12 | NSString *const MJRefreshKeyPathContentOffset = @"contentOffset"; 13 | NSString *const MJRefreshKeyPathContentInset = @"contentInset"; 14 | NSString *const MJRefreshKeyPathContentSize = @"contentSize"; 15 | NSString *const MJRefreshKeyPathPanState = @"state"; 16 | 17 | NSString *const MJRefreshHeaderLastUpdatedTimeKey = @"MJRefreshHeaderLastUpdatedTimeKey"; 18 | 19 | NSString *const MJRefreshHeaderIdleText = @"MJRefreshHeaderIdleText"; 20 | NSString *const MJRefreshHeaderPullingText = @"MJRefreshHeaderPullingText"; 21 | NSString *const MJRefreshHeaderRefreshingText = @"MJRefreshHeaderRefreshingText"; 22 | 23 | NSString *const MJRefreshTrailerIdleText = @"MJRefreshTrailerIdleText"; 24 | NSString *const MJRefreshTrailerPullingText = @"MJRefreshTrailerPullingText"; 25 | 26 | NSString *const MJRefreshAutoFooterIdleText = @"MJRefreshAutoFooterIdleText"; 27 | NSString *const MJRefreshAutoFooterRefreshingText = @"MJRefreshAutoFooterRefreshingText"; 28 | NSString *const MJRefreshAutoFooterNoMoreDataText = @"MJRefreshAutoFooterNoMoreDataText"; 29 | 30 | NSString *const MJRefreshBackFooterIdleText = @"MJRefreshBackFooterIdleText"; 31 | NSString *const MJRefreshBackFooterPullingText = @"MJRefreshBackFooterPullingText"; 32 | NSString *const MJRefreshBackFooterRefreshingText = @"MJRefreshBackFooterRefreshingText"; 33 | NSString *const MJRefreshBackFooterNoMoreDataText = @"MJRefreshBackFooterNoMoreDataText"; 34 | 35 | NSString *const MJRefreshHeaderLastTimeText = @"MJRefreshHeaderLastTimeText"; 36 | NSString *const MJRefreshHeaderDateTodayText = @"MJRefreshHeaderDateTodayText"; 37 | NSString *const MJRefreshHeaderNoneLastDateText = @"MJRefreshHeaderNoneLastDateText"; 38 | 39 | NSString *const MJRefreshDidChangeLanguageNotification = @"MJRefreshDidChangeLanguageNotification"; 40 | -------------------------------------------------------------------------------- /MJRefresh/NSBundle+MJRefresh.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+MJRefresh.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 16/6/13. 6 | // Copyright © 2016年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSBundle (MJRefresh) 14 | + (instancetype)mj_refreshBundle; 15 | + (UIImage *)mj_arrowImage; 16 | + (UIImage *)mj_trailArrowImage; 17 | + (NSString *)mj_localizedStringForKey:(NSString *)key value:(nullable NSString *)value; 18 | + (NSString *)mj_localizedStringForKey:(NSString *)key; 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /MJRefresh/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyTracking 6 | 7 | NSPrivacyTrackingDomains 8 | 9 | NSPrivacyAccessedAPITypes 10 | 11 | 12 | NSPrivacyAccessedAPIType 13 | NSPrivacyAccessedAPICategoryUserDefaults 14 | NSPrivacyAccessedAPITypeReasons 15 | 16 | CA92.1 17 | 18 | 19 | 20 | NSPrivacyCollectedDataTypes 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /MJRefresh/UICollectionViewLayout+MJRefresh.h: -------------------------------------------------------------------------------- 1 | // 2 | // UICollectionViewLayout+MJRefresh.h 3 | // 4 | // 该类是用来解决 Footer 在底端加载完成后, 仍停留在原处的 bug. 5 | // 此问题出现在 iOS 14 及以下系统上. 6 | // Reference: https://github.com/CoderMJLee/MJRefresh/issues/1552 7 | // 8 | // Created by jiasong on 2021/11/15. 9 | // Copyright © 2021 小码哥. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface UICollectionViewLayout (MJRefresh) 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /MJRefresh/UICollectionViewLayout+MJRefresh.m: -------------------------------------------------------------------------------- 1 | // 2 | // UICollectionViewLayout+MJRefresh.m 3 | // 4 | // 该类是用来解决 Footer 在底端加载完成后, 仍停留在原处的 bug. 5 | // 此问题出现在 iOS 14 及以下系统上. 6 | // Reference: https://github.com/CoderMJLee/MJRefresh/issues/1552 7 | // 8 | // Created by jiasong on 2021/11/15. 9 | // Copyright © 2021 小码哥. All rights reserved. 10 | // 11 | 12 | #import "UICollectionViewLayout+MJRefresh.h" 13 | #import "MJRefreshConst.h" 14 | #import "MJRefreshFooter.h" 15 | #import "UIScrollView+MJRefresh.h" 16 | 17 | @implementation UICollectionViewLayout (MJRefresh) 18 | 19 | + (void)load { 20 | static dispatch_once_t onceToken; 21 | dispatch_once(&onceToken, ^{ 22 | MJRefreshExchangeImplementations(self.class, @selector(finalizeCollectionViewUpdates), 23 | self.class, @selector(mj_finalizeCollectionViewUpdates)); 24 | }); 25 | } 26 | 27 | - (void)mj_finalizeCollectionViewUpdates { 28 | [self mj_finalizeCollectionViewUpdates]; 29 | 30 | __kindof MJRefreshFooter *footer = self.collectionView.mj_footer; 31 | CGSize newSize = self.collectionViewContentSize; 32 | CGSize oldSize = self.collectionView.contentSize; 33 | if (footer != nil && !CGSizeEqualToSize(newSize, oldSize)) { 34 | NSDictionary *changed = @{ 35 | NSKeyValueChangeNewKey: [NSValue valueWithCGSize:newSize], 36 | NSKeyValueChangeOldKey: [NSValue valueWithCGSize:oldSize], 37 | }; 38 | [CATransaction begin]; 39 | [CATransaction setDisableActions:YES]; 40 | [footer scrollViewContentSizeDidChange:changed]; 41 | [CATransaction commit]; 42 | } 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /MJRefresh/UIScrollView+MJExtension.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // UIScrollView+Extension.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIScrollView (MJExtension) 14 | @property (readonly, nonatomic) UIEdgeInsets mj_inset; 15 | 16 | @property (assign, nonatomic) CGFloat mj_insetT; 17 | @property (assign, nonatomic) CGFloat mj_insetB; 18 | @property (assign, nonatomic) CGFloat mj_insetL; 19 | @property (assign, nonatomic) CGFloat mj_insetR; 20 | 21 | @property (assign, nonatomic) CGFloat mj_offsetX; 22 | @property (assign, nonatomic) CGFloat mj_offsetY; 23 | 24 | @property (assign, nonatomic) CGFloat mj_contentW; 25 | @property (assign, nonatomic) CGFloat mj_contentH; 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /MJRefresh/UIScrollView+MJExtension.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // UIScrollView+Extension.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+MJExtension.h" 10 | #import 11 | 12 | #pragma clang diagnostic push 13 | #pragma clang diagnostic ignored "-Wunguarded-availability-new" 14 | 15 | @implementation UIScrollView (MJExtension) 16 | 17 | static BOOL respondsToAdjustedContentInset_; 18 | 19 | + (void)load 20 | { 21 | static dispatch_once_t onceToken; 22 | dispatch_once(&onceToken, ^{ 23 | respondsToAdjustedContentInset_ = [self instancesRespondToSelector:@selector(adjustedContentInset)]; 24 | }); 25 | } 26 | 27 | - (UIEdgeInsets)mj_inset 28 | { 29 | #ifdef __IPHONE_11_0 30 | if (respondsToAdjustedContentInset_) { 31 | return self.adjustedContentInset; 32 | } 33 | #endif 34 | return self.contentInset; 35 | } 36 | 37 | - (void)setMj_insetT:(CGFloat)mj_insetT 38 | { 39 | UIEdgeInsets inset = self.contentInset; 40 | inset.top = mj_insetT; 41 | #ifdef __IPHONE_11_0 42 | if (respondsToAdjustedContentInset_) { 43 | inset.top -= (self.adjustedContentInset.top - self.contentInset.top); 44 | } 45 | #endif 46 | self.contentInset = inset; 47 | } 48 | 49 | - (CGFloat)mj_insetT 50 | { 51 | return self.mj_inset.top; 52 | } 53 | 54 | - (void)setMj_insetB:(CGFloat)mj_insetB 55 | { 56 | UIEdgeInsets inset = self.contentInset; 57 | inset.bottom = mj_insetB; 58 | #ifdef __IPHONE_11_0 59 | if (respondsToAdjustedContentInset_) { 60 | inset.bottom -= (self.adjustedContentInset.bottom - self.contentInset.bottom); 61 | } 62 | #endif 63 | self.contentInset = inset; 64 | } 65 | 66 | - (CGFloat)mj_insetB 67 | { 68 | return self.mj_inset.bottom; 69 | } 70 | 71 | - (void)setMj_insetL:(CGFloat)mj_insetL 72 | { 73 | UIEdgeInsets inset = self.contentInset; 74 | inset.left = mj_insetL; 75 | #ifdef __IPHONE_11_0 76 | if (respondsToAdjustedContentInset_) { 77 | inset.left -= (self.adjustedContentInset.left - self.contentInset.left); 78 | } 79 | #endif 80 | self.contentInset = inset; 81 | } 82 | 83 | - (CGFloat)mj_insetL 84 | { 85 | return self.mj_inset.left; 86 | } 87 | 88 | - (void)setMj_insetR:(CGFloat)mj_insetR 89 | { 90 | UIEdgeInsets inset = self.contentInset; 91 | inset.right = mj_insetR; 92 | #ifdef __IPHONE_11_0 93 | if (respondsToAdjustedContentInset_) { 94 | inset.right -= (self.adjustedContentInset.right - self.contentInset.right); 95 | } 96 | #endif 97 | self.contentInset = inset; 98 | } 99 | 100 | - (CGFloat)mj_insetR 101 | { 102 | return self.mj_inset.right; 103 | } 104 | 105 | - (void)setMj_offsetX:(CGFloat)mj_offsetX 106 | { 107 | CGPoint offset = self.contentOffset; 108 | offset.x = mj_offsetX; 109 | self.contentOffset = offset; 110 | } 111 | 112 | - (CGFloat)mj_offsetX 113 | { 114 | return self.contentOffset.x; 115 | } 116 | 117 | - (void)setMj_offsetY:(CGFloat)mj_offsetY 118 | { 119 | CGPoint offset = self.contentOffset; 120 | offset.y = mj_offsetY; 121 | self.contentOffset = offset; 122 | } 123 | 124 | - (CGFloat)mj_offsetY 125 | { 126 | return self.contentOffset.y; 127 | } 128 | 129 | - (void)setMj_contentW:(CGFloat)mj_contentW 130 | { 131 | CGSize size = self.contentSize; 132 | size.width = mj_contentW; 133 | self.contentSize = size; 134 | } 135 | 136 | - (CGFloat)mj_contentW 137 | { 138 | return self.contentSize.width; 139 | } 140 | 141 | - (void)setMj_contentH:(CGFloat)mj_contentH 142 | { 143 | CGSize size = self.contentSize; 144 | size.height = mj_contentH; 145 | self.contentSize = size; 146 | } 147 | 148 | - (CGFloat)mj_contentH 149 | { 150 | return self.contentSize.height; 151 | } 152 | @end 153 | #pragma clang diagnostic pop 154 | -------------------------------------------------------------------------------- /MJRefresh/UIScrollView+MJRefresh.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // UIScrollView+MJRefresh.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 给ScrollView增加下拉刷新、上拉刷新、 左滑刷新的功能 8 | 9 | #import 10 | #if __has_include() 11 | #import 12 | #else 13 | #import "MJRefreshConst.h" 14 | #endif 15 | 16 | @class MJRefreshHeader, MJRefreshFooter, MJRefreshTrailer; 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UIScrollView (MJRefresh) 21 | /** 下拉刷新控件 */ 22 | @property (strong, nonatomic, nullable) MJRefreshHeader *mj_header; 23 | @property (strong, nonatomic, nullable) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header"); 24 | /** 上拉刷新控件 */ 25 | @property (strong, nonatomic, nullable) MJRefreshFooter *mj_footer; 26 | @property (strong, nonatomic, nullable) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer"); 27 | 28 | /** 左滑刷新控件 */ 29 | @property (strong, nonatomic, nullable) MJRefreshTrailer *mj_trailer; 30 | 31 | #pragma mark - other 32 | - (NSInteger)mj_totalDataCount; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /MJRefresh/UIScrollView+MJRefresh.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // UIScrollView+MJRefresh.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 15/3/4. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+MJRefresh.h" 10 | #import "MJRefreshHeader.h" 11 | #import "MJRefreshFooter.h" 12 | #import "MJRefreshTrailer.h" 13 | #import 14 | 15 | @implementation UIScrollView (MJRefresh) 16 | 17 | #pragma mark - header 18 | static const char MJRefreshHeaderKey = '\0'; 19 | - (void)setMj_header:(MJRefreshHeader *)mj_header 20 | { 21 | if (mj_header != self.mj_header) { 22 | // 删除旧的,添加新的 23 | [self.mj_header removeFromSuperview]; 24 | 25 | if (mj_header) { 26 | [self insertSubview:mj_header atIndex:0]; 27 | } 28 | // 存储新的 29 | objc_setAssociatedObject(self, &MJRefreshHeaderKey, 30 | mj_header, OBJC_ASSOCIATION_RETAIN); 31 | } 32 | } 33 | 34 | - (MJRefreshHeader *)mj_header 35 | { 36 | return objc_getAssociatedObject(self, &MJRefreshHeaderKey); 37 | } 38 | 39 | #pragma mark - footer 40 | static const char MJRefreshFooterKey = '\0'; 41 | - (void)setMj_footer:(MJRefreshFooter *)mj_footer 42 | { 43 | if (mj_footer != self.mj_footer) { 44 | // 删除旧的,添加新的 45 | [self.mj_footer removeFromSuperview]; 46 | if (mj_footer) { 47 | [self insertSubview:mj_footer atIndex:0]; 48 | } 49 | // 存储新的 50 | objc_setAssociatedObject(self, &MJRefreshFooterKey, 51 | mj_footer, OBJC_ASSOCIATION_RETAIN); 52 | } 53 | } 54 | 55 | - (MJRefreshFooter *)mj_footer 56 | { 57 | return objc_getAssociatedObject(self, &MJRefreshFooterKey); 58 | } 59 | 60 | #pragma mark - footer 61 | static const char MJRefreshTrailerKey = '\0'; 62 | - (void)setMj_trailer:(MJRefreshTrailer *)mj_trailer { 63 | if (mj_trailer != self.mj_trailer) { 64 | // 删除旧的,添加新的 65 | [self.mj_trailer removeFromSuperview]; 66 | if (mj_trailer) { 67 | [self insertSubview:mj_trailer atIndex:0]; 68 | } 69 | // 存储新的 70 | objc_setAssociatedObject(self, &MJRefreshTrailerKey, 71 | mj_trailer, OBJC_ASSOCIATION_RETAIN); 72 | } 73 | } 74 | 75 | - (MJRefreshTrailer *)mj_trailer { 76 | return objc_getAssociatedObject(self, &MJRefreshTrailerKey); 77 | } 78 | 79 | #pragma mark - 过期 80 | - (void)setFooter:(MJRefreshFooter *)footer 81 | { 82 | self.mj_footer = footer; 83 | } 84 | 85 | - (MJRefreshFooter *)footer 86 | { 87 | return self.mj_footer; 88 | } 89 | 90 | - (void)setHeader:(MJRefreshHeader *)header 91 | { 92 | self.mj_header = header; 93 | } 94 | 95 | - (MJRefreshHeader *)header 96 | { 97 | return self.mj_header; 98 | } 99 | 100 | #pragma mark - other 101 | - (NSInteger)mj_totalDataCount 102 | { 103 | NSInteger totalCount = 0; 104 | if ([self isKindOfClass:[UITableView class]]) { 105 | UITableView *tableView = (UITableView *)self; 106 | 107 | for (NSInteger section = 0; section < tableView.numberOfSections; section++) { 108 | totalCount += [tableView numberOfRowsInSection:section]; 109 | } 110 | } else if ([self isKindOfClass:[UICollectionView class]]) { 111 | UICollectionView *collectionView = (UICollectionView *)self; 112 | 113 | for (NSInteger section = 0; section < collectionView.numberOfSections; section++) { 114 | totalCount += [collectionView numberOfItemsInSection:section]; 115 | } 116 | } 117 | return totalCount; 118 | } 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /MJRefresh/UIView+MJExtension.h: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // UIView+Extension.h 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIView (MJExtension) 14 | @property (assign, nonatomic) CGFloat mj_x; 15 | @property (assign, nonatomic) CGFloat mj_y; 16 | @property (assign, nonatomic) CGFloat mj_w; 17 | @property (assign, nonatomic) CGFloat mj_h; 18 | @property (assign, nonatomic) CGSize mj_size; 19 | @property (assign, nonatomic) CGPoint mj_origin; 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /MJRefresh/UIView+MJExtension.m: -------------------------------------------------------------------------------- 1 | // 代码地址: https://github.com/CoderMJLee/MJRefresh 2 | // UIView+Extension.m 3 | // MJRefresh 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "UIView+MJExtension.h" 10 | 11 | @implementation UIView (MJExtension) 12 | - (void)setMj_x:(CGFloat)mj_x 13 | { 14 | CGRect frame = self.frame; 15 | frame.origin.x = mj_x; 16 | self.frame = frame; 17 | } 18 | 19 | - (CGFloat)mj_x 20 | { 21 | return self.frame.origin.x; 22 | } 23 | 24 | - (void)setMj_y:(CGFloat)mj_y 25 | { 26 | CGRect frame = self.frame; 27 | frame.origin.y = mj_y; 28 | self.frame = frame; 29 | } 30 | 31 | - (CGFloat)mj_y 32 | { 33 | return self.frame.origin.y; 34 | } 35 | 36 | - (void)setMj_w:(CGFloat)mj_w 37 | { 38 | CGRect frame = self.frame; 39 | frame.size.width = mj_w; 40 | self.frame = frame; 41 | } 42 | 43 | - (CGFloat)mj_w 44 | { 45 | return self.frame.size.width; 46 | } 47 | 48 | - (void)setMj_h:(CGFloat)mj_h 49 | { 50 | CGRect frame = self.frame; 51 | frame.size.height = mj_h; 52 | self.frame = frame; 53 | } 54 | 55 | - (CGFloat)mj_h 56 | { 57 | return self.frame.size.height; 58 | } 59 | 60 | - (void)setMj_size:(CGSize)mj_size 61 | { 62 | CGRect frame = self.frame; 63 | frame.size = mj_size; 64 | self.frame = frame; 65 | } 66 | 67 | - (CGSize)mj_size 68 | { 69 | return self.frame.size; 70 | } 71 | 72 | - (void)setMj_origin:(CGPoint)mj_origin 73 | { 74 | CGRect frame = self.frame; 75 | frame.origin = mj_origin; 76 | self.frame = frame; 77 | } 78 | 79 | - (CGPoint)mj_origin 80 | { 81 | return self.frame.origin; 82 | } 83 | @end 84 | -------------------------------------------------------------------------------- /MJRefresh/include/MJRefresh.h: -------------------------------------------------------------------------------- 1 | ../MJRefresh.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshAutoFooter.h: -------------------------------------------------------------------------------- 1 | ../Base/MJRefreshAutoFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshAutoGifFooter.h: -------------------------------------------------------------------------------- 1 | ../Custom/Footer/Auto/MJRefreshAutoGifFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshAutoNormalFooter.h: -------------------------------------------------------------------------------- 1 | ../Custom/Footer/Auto/MJRefreshAutoNormalFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshAutoStateFooter.h: -------------------------------------------------------------------------------- 1 | ../Custom/Footer/Auto/MJRefreshAutoStateFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshBackFooter.h: -------------------------------------------------------------------------------- 1 | ../Base/MJRefreshBackFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshBackGifFooter.h: -------------------------------------------------------------------------------- 1 | ../Custom/Footer/Back/MJRefreshBackGifFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshBackNormalFooter.h: -------------------------------------------------------------------------------- 1 | ../Custom/Footer/Back/MJRefreshBackNormalFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshBackStateFooter.h: -------------------------------------------------------------------------------- 1 | ../Custom/Footer/Back/MJRefreshBackStateFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshComponent.h: -------------------------------------------------------------------------------- 1 | ../Base/MJRefreshComponent.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshConfig.h: -------------------------------------------------------------------------------- 1 | ../MJRefreshConfig.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshConst.h: -------------------------------------------------------------------------------- 1 | ../MJRefreshConst.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshFooter.h: -------------------------------------------------------------------------------- 1 | ../Base/MJRefreshFooter.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshGifHeader.h: -------------------------------------------------------------------------------- 1 | ../Custom/Header/MJRefreshGifHeader.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshHeader.h: -------------------------------------------------------------------------------- 1 | ../Base/MJRefreshHeader.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshNormalHeader.h: -------------------------------------------------------------------------------- 1 | ../Custom/Header/MJRefreshNormalHeader.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshNormalTrailer.h: -------------------------------------------------------------------------------- 1 | ../Custom/Trailer/MJRefreshNormalTrailer.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshStateHeader.h: -------------------------------------------------------------------------------- 1 | ../Custom/Header/MJRefreshStateHeader.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshStateTrailer.h: -------------------------------------------------------------------------------- 1 | ../Custom/Trailer/MJRefreshStateTrailer.h -------------------------------------------------------------------------------- /MJRefresh/include/MJRefreshTrailer.h: -------------------------------------------------------------------------------- 1 | ../Base/MJRefreshTrailer.h -------------------------------------------------------------------------------- /MJRefresh/include/NSBundle+MJRefresh.h: -------------------------------------------------------------------------------- 1 | ../NSBundle+MJRefresh.h -------------------------------------------------------------------------------- /MJRefresh/include/UIScrollView+MJExtension.h: -------------------------------------------------------------------------------- 1 | ../UIScrollView+MJExtension.h -------------------------------------------------------------------------------- /MJRefresh/include/UIScrollView+MJRefresh.h: -------------------------------------------------------------------------------- 1 | ../UIScrollView+MJRefresh.h -------------------------------------------------------------------------------- /MJRefresh/include/UIView+MJExtension.h: -------------------------------------------------------------------------------- 1 | ../UIView+MJExtension.h -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "MJRefresh", 8 | products: [ 9 | .library(name: "MJRefresh", targets: ["MJRefresh"]), 10 | ], 11 | dependencies: [], 12 | targets: [ 13 | .target( 14 | name: "MJRefresh", 15 | dependencies: [], 16 | path: "MJRefresh", 17 | exclude: ["Info.plist"], 18 | resources: [.process("MJRefresh.bundle"), .copy("PrivacyInfo.xcprivacy")], 19 | publicHeadersPath: "include", 20 | cSettings: [ 21 | //Config header path 22 | .headerSearchPath("."), 23 | ] 24 | ), 25 | ] 26 | ) 27 | --------------------------------------------------------------------------------