Commit df99eb1074ff4dbb7fb97b65704bcc59508f9502
1 parent
983c1bc5
添加MJrefresh
Showing
76 changed files
with
3659 additions
and
62 deletions
CNLiveRefeshHeader.podspec
| 1 | -# | |
| 2 | -# Be sure to run `pod lib lint CNLiveRefeshHeader.podspec' to ensure this is a | |
| 3 | -# valid spec before submitting. | |
| 4 | -# | |
| 5 | -# Any lines starting with a # are optional, but their use is encouraged | |
| 6 | -# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html | |
| 7 | -# | |
| 8 | 1 | |
| 9 | 2 | Pod::Spec.new do |s| |
| 10 | 3 | s.name = 'CNLiveRefeshHeader' |
| 11 | - s.version = '0.1.0' | |
| 12 | - s.summary = 'A short description of CNLiveRefeshHeader.' | |
| 13 | - | |
| 14 | -# This description is used to generate tags and improve search results. | |
| 15 | -# * Think: What does it do? Why did you write it? What is the focus? | |
| 16 | -# * Try to keep it short, snappy and to the point. | |
| 17 | -# * Write the description between the DESC delimiters below. | |
| 18 | -# * Finally, don't worry about the indent, CocoaPods strips it! | |
| 4 | + s.version = '0.0.1' | |
| 5 | + s.summary = 'MJRefresh封装.' | |
| 19 | 6 | |
| 20 | 7 | s.description = <<-DESC |
| 21 | 8 | TODO: Add long description of the pod here. |
| 22 | 9 | DESC |
| 23 | 10 | |
| 24 | - s.homepage = 'https://github.com/殷巧娟/CNLiveRefeshHeader' | |
| 11 | + s.homepage = 'http://bj.gitlab.cnlive.com/ios-team/CNLiveRefreshHeader' | |
| 25 | 12 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' |
| 26 | 13 | s.license = { :type => 'MIT', :file => 'LICENSE' } |
| 27 | 14 | s.author = { '殷巧娟' => '1427945373@qq.com' } |
| 28 | - s.source = { :git => 'https://github.com/殷巧娟/CNLiveRefeshHeader.git', :tag => s.version.to_s } | |
| 15 | + s.source = { :git => 'http://bj.gitlab.cnlive.com/ios-team/CNLiveRefreshHeader.git', :tag => s.version.to_s } | |
| 29 | 16 | # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' |
| 30 | 17 | |
| 31 | - s.ios.deployment_target = '8.0' | |
| 18 | + s.ios.deployment_target = '9.0' | |
| 32 | 19 | |
| 33 | - s.source_files = 'CNLiveRefeshHeader/Classes/**/*' | |
| 20 | + s.source_files = 'CNLiveRefeshHeader/Classes/**/*.{h,m}' | |
| 34 | 21 | |
| 35 | 22 | # s.resource_bundles = { |
| 36 | 23 | # 'CNLiveRefeshHeader' => ['CNLiveRefeshHeader/Assets/*.png'] |
| 37 | 24 | # } |
| 38 | 25 | |
| 39 | 26 | # s.public_header_files = 'Pod/Classes/**/*.h' |
| 40 | - # s.frameworks = 'UIKit', 'MapKit' | |
| 41 | - # s.dependency 'AFNetworking', '~> 2.3' | |
| 27 | + s.frameworks = 'UIKit', 'Foundation' | |
| 28 | + s.dependency 'MJRefresh' | |
| 42 | 29 | end | ... | ... |
CNLiveRefeshHeader/Assets/.gitkeep deleted
100644 → 0
CNLiveRefeshHeader/Classes/.gitkeep deleted
100644 → 0
CNLiveRefeshHeader/Classes/ReplaceMe.m deleted
100644 → 0
CNLiveRefeshHeader/Classes/Test.h
0 → 100644
CNLiveRefeshHeader/Classes/Test.m
0 → 100644
Example/CNLiveRefeshHeader.xcodeproj/project.pbxproj
| ... | ... | @@ -39,7 +39,7 @@ |
| 39 | 39 | /* Begin PBXFileReference section */ |
| 40 | 40 | 206C49FAD2FBC65472F0B245 /* Pods-CNLiveRefeshHeader_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveRefeshHeader_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example.release.xcconfig"; sourceTree = "<group>"; }; |
| 41 | 41 | 2EC258FB34840795986BB394 /* Pods-CNLiveRefeshHeader_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveRefeshHeader_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example.debug.xcconfig"; sourceTree = "<group>"; }; |
| 42 | - 38AD5FC6B5653A55CFF6AF37 /* CNLiveRefeshHeader.podspec */ = {isa = PBXFileReference; includeInIndex = 1; name = CNLiveRefeshHeader.podspec; path = ../CNLiveRefeshHeader.podspec; sourceTree = "<group>"; }; | |
| 42 | + 38AD5FC6B5653A55CFF6AF37 /* CNLiveRefeshHeader.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLiveRefeshHeader.podspec; path = ../CNLiveRefeshHeader.podspec; sourceTree = "<group>"; }; | |
| 43 | 43 | 6003F58A195388D20070C39A /* CNLiveRefeshHeader_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveRefeshHeader_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 44 | 44 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; |
| 45 | 45 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; |
| ... | ... | @@ -64,8 +64,8 @@ |
| 64 | 64 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; |
| 65 | 65 | 9FEDF435609EC6ABA3ED68BF /* Pods-CNLiveRefeshHeader_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveRefeshHeader_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests.release.xcconfig"; sourceTree = "<group>"; }; |
| 66 | 66 | A038442E309DD2C1B32E2DD4 /* Pods_CNLiveRefeshHeader_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveRefeshHeader_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 67 | - B625FDE487441B5FBA4401E8 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = ../README.md; sourceTree = "<group>"; }; | |
| 68 | - EB60BE8F605BB573066259CC /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; }; | |
| 67 | + B625FDE487441B5FBA4401E8 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; }; | |
| 68 | + EB60BE8F605BB573066259CC /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; }; | |
| 69 | 69 | EE2F66B8F2F8AC6C6F1CC916 /* Pods_CNLiveRefeshHeader_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveRefeshHeader_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 70 | 70 | /* End PBXFileReference section */ |
| 71 | 71 | |
| ... | ... | @@ -226,6 +226,7 @@ |
| 226 | 226 | 6003F5AA195388D20070C39A /* Sources */, |
| 227 | 227 | 6003F5AB195388D20070C39A /* Frameworks */, |
| 228 | 228 | 6003F5AC195388D20070C39A /* Resources */, |
| 229 | + 826EDDFDF9BC4785184B1D06 /* [CP] Embed Pods Frameworks */, | |
| 229 | 230 | ); |
| 230 | 231 | buildRules = ( |
| 231 | 232 | ); |
| ... | ... | @@ -247,6 +248,9 @@ |
| 247 | 248 | LastUpgradeCheck = 0720; |
| 248 | 249 | ORGANIZATIONNAME = "殷巧娟"; |
| 249 | 250 | TargetAttributes = { |
| 251 | + 6003F589195388D20070C39A = { | |
| 252 | + DevelopmentTeam = 94X49GG3ZW; | |
| 253 | + }; | |
| 250 | 254 | 6003F5AD195388D20070C39A = { |
| 251 | 255 | TestTargetID = 6003F589195388D20070C39A; |
| 252 | 256 | }; |
| ... | ... | @@ -316,6 +320,28 @@ |
| 316 | 320 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; |
| 317 | 321 | showEnvVarsInLog = 0; |
| 318 | 322 | }; |
| 323 | + 826EDDFDF9BC4785184B1D06 /* [CP] Embed Pods Frameworks */ = { | |
| 324 | + isa = PBXShellScriptBuildPhase; | |
| 325 | + buildActionMask = 2147483647; | |
| 326 | + files = ( | |
| 327 | + ); | |
| 328 | + inputFileListPaths = ( | |
| 329 | + ); | |
| 330 | + inputPaths = ( | |
| 331 | + "${SRCROOT}/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests-frameworks.sh", | |
| 332 | + "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework", | |
| 333 | + ); | |
| 334 | + name = "[CP] Embed Pods Frameworks"; | |
| 335 | + outputFileListPaths = ( | |
| 336 | + ); | |
| 337 | + outputPaths = ( | |
| 338 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework", | |
| 339 | + ); | |
| 340 | + runOnlyForDeploymentPostprocessing = 0; | |
| 341 | + shellPath = /bin/sh; | |
| 342 | + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests-frameworks.sh\"\n"; | |
| 343 | + showEnvVarsInLog = 0; | |
| 344 | + }; | |
| 319 | 345 | 9E14C1C76626ACA2CA39777E /* [CP] Check Pods Manifest.lock */ = { |
| 320 | 346 | isa = PBXShellScriptBuildPhase; |
| 321 | 347 | buildActionMask = 2147483647; |
| ... | ... | @@ -348,12 +374,14 @@ |
| 348 | 374 | inputPaths = ( |
| 349 | 375 | "${SRCROOT}/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example-frameworks.sh", |
| 350 | 376 | "${BUILT_PRODUCTS_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework", |
| 377 | + "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework", | |
| 351 | 378 | ); |
| 352 | 379 | name = "[CP] Embed Pods Frameworks"; |
| 353 | 380 | outputFileListPaths = ( |
| 354 | 381 | ); |
| 355 | 382 | outputPaths = ( |
| 356 | 383 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveRefeshHeader.framework", |
| 384 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework", | |
| 357 | 385 | ); |
| 358 | 386 | runOnlyForDeploymentPostprocessing = 0; |
| 359 | 387 | shellPath = /bin/sh; |
| ... | ... | @@ -497,6 +525,7 @@ |
| 497 | 525 | baseConfigurationReference = 2EC258FB34840795986BB394 /* Pods-CNLiveRefeshHeader_Example.debug.xcconfig */; |
| 498 | 526 | buildSettings = { |
| 499 | 527 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
| 528 | + DEVELOPMENT_TEAM = 94X49GG3ZW; | |
| 500 | 529 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
| 501 | 530 | GCC_PREFIX_HEADER = "CNLiveRefeshHeader/CNLiveRefeshHeader-Prefix.pch"; |
| 502 | 531 | INFOPLIST_FILE = "CNLiveRefeshHeader/CNLiveRefeshHeader-Info.plist"; |
| ... | ... | @@ -512,6 +541,7 @@ |
| 512 | 541 | baseConfigurationReference = 206C49FAD2FBC65472F0B245 /* Pods-CNLiveRefeshHeader_Example.release.xcconfig */; |
| 513 | 542 | buildSettings = { |
| 514 | 543 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
| 544 | + DEVELOPMENT_TEAM = 94X49GG3ZW; | |
| 515 | 545 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
| 516 | 546 | GCC_PREFIX_HEADER = "CNLiveRefeshHeader/CNLiveRefeshHeader-Prefix.pch"; |
| 517 | 547 | INFOPLIST_FILE = "CNLiveRefeshHeader/CNLiveRefeshHeader-Info.plist"; | ... | ... |
Example/Podfile
| 1 | 1 | use_frameworks! |
| 2 | 2 | |
| 3 | -platform :ios, '8.0' | |
| 3 | +platform :ios, '9.0' | |
| 4 | 4 | |
| 5 | 5 | target 'CNLiveRefeshHeader_Example' do |
| 6 | 6 | pod 'CNLiveRefeshHeader', :path => '../' |
| 7 | + pod 'MJRefresh' | |
| 7 | 8 | |
| 8 | 9 | target 'CNLiveRefeshHeader_Tests' do |
| 9 | 10 | inherit! :search_paths |
| 11 | + pod 'MJRefresh' | |
| 10 | 12 | |
| 11 | 13 | |
| 12 | 14 | end | ... | ... |
Example/Podfile.lock
| 1 | 1 | PODS: |
| 2 | - - CNLiveRefeshHeader (0.1.0) | |
| 2 | + - CNLiveRefeshHeader (0.0.1): | |
| 3 | + - MJRefresh | |
| 4 | + - MJRefresh (3.1.15.7) | |
| 3 | 5 | |
| 4 | 6 | DEPENDENCIES: |
| 5 | 7 | - CNLiveRefeshHeader (from `../`) |
| 8 | + - MJRefresh | |
| 9 | + | |
| 10 | +SPEC REPOS: | |
| 11 | + https://github.com/cocoapods/specs.git: | |
| 12 | + - MJRefresh | |
| 6 | 13 | |
| 7 | 14 | EXTERNAL SOURCES: |
| 8 | 15 | CNLiveRefeshHeader: |
| 9 | 16 | :path: "../" |
| 10 | 17 | |
| 11 | 18 | SPEC CHECKSUMS: |
| 12 | - CNLiveRefeshHeader: d965f2b85e9e7780987a403011aa2bc1ef39699a | |
| 19 | + CNLiveRefeshHeader: 02f3d68e758397c04a98dcf8be0141ff1a8f2874 | |
| 20 | + MJRefresh: 697f8ec75ebdbe9207767bb682cf0f51b0d8a41f | |
| 13 | 21 | |
| 14 | -PODFILE CHECKSUM: 23844f68fff15c2b9e865816ca034e39a4d9cd02 | |
| 22 | +PODFILE CHECKSUM: 813baa37d96ee543acda9928f20b522a49de2526 | |
| 15 | 23 | |
| 16 | 24 | COCOAPODS: 1.5.3 | ... | ... |
Example/Pods/Local Podspecs/CNLiveRefeshHeader.podspec.json
| 1 | 1 | { |
| 2 | 2 | "name": "CNLiveRefeshHeader", |
| 3 | - "version": "0.1.0", | |
| 4 | - "summary": "A short description of CNLiveRefeshHeader.", | |
| 3 | + "version": "0.0.1", | |
| 4 | + "summary": "MJRefresh封装.", | |
| 5 | 5 | "description": "TODO: Add long description of the pod here.", |
| 6 | - "homepage": "https://github.com/殷巧娟/CNLiveRefeshHeader", | |
| 6 | + "homepage": "http://bj.gitlab.cnlive.com/ios-team/CNLiveRefreshHeader", | |
| 7 | 7 | "license": { |
| 8 | 8 | "type": "MIT", |
| 9 | 9 | "file": "LICENSE" |
| ... | ... | @@ -12,11 +12,20 @@ |
| 12 | 12 | "殷巧娟": "1427945373@qq.com" |
| 13 | 13 | }, |
| 14 | 14 | "source": { |
| 15 | - "git": "https://github.com/殷巧娟/CNLiveRefeshHeader.git", | |
| 16 | - "tag": "0.1.0" | |
| 15 | + "git": "http://bj.gitlab.cnlive.com/ios-team/CNLiveRefreshHeader.git", | |
| 16 | + "tag": "0.0.1" | |
| 17 | 17 | }, |
| 18 | 18 | "platforms": { |
| 19 | - "ios": "8.0" | |
| 19 | + "ios": "9.0" | |
| 20 | 20 | }, |
| 21 | - "source_files": "CNLiveRefeshHeader/Classes/**/*" | |
| 21 | + "source_files": "CNLiveRefeshHeader/Classes/**/*.{h,m}", | |
| 22 | + "frameworks": [ | |
| 23 | + "UIKit", | |
| 24 | + "Foundation" | |
| 25 | + ], | |
| 26 | + "dependencies": { | |
| 27 | + "MJRefresh": [ | |
| 28 | + | |
| 29 | + ] | |
| 30 | + } | |
| 22 | 31 | } | ... | ... |
Example/Pods/MJRefresh/LICENSE
0 → 100644
| 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. | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoFooter.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoFooter : MJRefreshFooter | |
| 12 | +/** 是否自动刷新(默认为YES) */ | |
| 13 | +@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; | |
| 14 | + | |
| 15 | +/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ | |
| 16 | +@property (assign, nonatomic) CGFloat appearencePercentTriggerAutoRefresh MJRefreshDeprecated("请使用triggerAutomaticallyRefreshPercent属性"); | |
| 17 | + | |
| 18 | +/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ | |
| 19 | +@property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; | |
| 20 | + | |
| 21 | +/** 是否每一次拖拽只发一次请求 */ | |
| 22 | +@property (assign, nonatomic, getter=isOnlyRefreshPerDrag) BOOL onlyRefreshPerDrag; | |
| 23 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshAutoFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoFooter() | |
| 12 | +/** 一个新的拖拽 */ | |
| 13 | +@property (assign, nonatomic, getter=isOneNewPan) BOOL oneNewPan; | |
| 14 | +@end | |
| 15 | + | |
| 16 | +@implementation MJRefreshAutoFooter | |
| 17 | + | |
| 18 | +#pragma mark - 初始化 | |
| 19 | +- (void)willMoveToSuperview:(UIView *)newSuperview | |
| 20 | +{ | |
| 21 | + [super willMoveToSuperview:newSuperview]; | |
| 22 | + | |
| 23 | + if (newSuperview) { // 新的父控件 | |
| 24 | + if (self.hidden == NO) { | |
| 25 | + self.scrollView.mj_insetB += self.mj_h; | |
| 26 | + } | |
| 27 | + | |
| 28 | + // 设置位置 | |
| 29 | + self.mj_y = _scrollView.mj_contentH; | |
| 30 | + } else { // 被移除了 | |
| 31 | + if (self.hidden == NO) { | |
| 32 | + self.scrollView.mj_insetB -= self.mj_h; | |
| 33 | + } | |
| 34 | + } | |
| 35 | +} | |
| 36 | + | |
| 37 | +#pragma mark - 过期方法 | |
| 38 | +- (void)setAppearencePercentTriggerAutoRefresh:(CGFloat)appearencePercentTriggerAutoRefresh | |
| 39 | +{ | |
| 40 | + self.triggerAutomaticallyRefreshPercent = appearencePercentTriggerAutoRefresh; | |
| 41 | +} | |
| 42 | + | |
| 43 | +- (CGFloat)appearencePercentTriggerAutoRefresh | |
| 44 | +{ | |
| 45 | + return self.triggerAutomaticallyRefreshPercent; | |
| 46 | +} | |
| 47 | + | |
| 48 | +#pragma mark - 实现父类的方法 | |
| 49 | +- (void)prepare | |
| 50 | +{ | |
| 51 | + [super prepare]; | |
| 52 | + | |
| 53 | + // 默认底部控件100%出现时才会自动刷新 | |
| 54 | + self.triggerAutomaticallyRefreshPercent = 1.0; | |
| 55 | + | |
| 56 | + // 设置为默认状态 | |
| 57 | + self.automaticallyRefresh = YES; | |
| 58 | + | |
| 59 | + // 默认是当offset达到条件就发送请求(可连续) | |
| 60 | + self.onlyRefreshPerDrag = NO; | |
| 61 | +} | |
| 62 | + | |
| 63 | +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change | |
| 64 | +{ | |
| 65 | + [super scrollViewContentSizeDidChange:change]; | |
| 66 | + | |
| 67 | + // 设置位置 | |
| 68 | + self.mj_y = self.scrollView.mj_contentH; | |
| 69 | +} | |
| 70 | + | |
| 71 | +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change | |
| 72 | +{ | |
| 73 | + [super scrollViewContentOffsetDidChange:change]; | |
| 74 | + | |
| 75 | + if (self.state != MJRefreshStateIdle || !self.automaticallyRefresh || self.mj_y == 0) return; | |
| 76 | + | |
| 77 | + if (_scrollView.mj_insetT + _scrollView.mj_contentH > _scrollView.mj_h) { // 内容超过一个屏幕 | |
| 78 | + // 这里的_scrollView.mj_contentH替换掉self.mj_y更为合理 | |
| 79 | + if (_scrollView.mj_offsetY >= _scrollView.mj_contentH - _scrollView.mj_h + self.mj_h * self.triggerAutomaticallyRefreshPercent + _scrollView.mj_insetB - self.mj_h) { | |
| 80 | + // 防止手松开时连续调用 | |
| 81 | + CGPoint old = [change[@"old"] CGPointValue]; | |
| 82 | + CGPoint new = [change[@"new"] CGPointValue]; | |
| 83 | + if (new.y <= old.y) return; | |
| 84 | + | |
| 85 | + // 当底部刷新控件完全出现时,才刷新 | |
| 86 | + [self beginRefreshing]; | |
| 87 | + } | |
| 88 | + } | |
| 89 | +} | |
| 90 | + | |
| 91 | +- (void)scrollViewPanStateDidChange:(NSDictionary *)change | |
| 92 | +{ | |
| 93 | + [super scrollViewPanStateDidChange:change]; | |
| 94 | + | |
| 95 | + if (self.state != MJRefreshStateIdle) return; | |
| 96 | + | |
| 97 | + UIGestureRecognizerState panState = _scrollView.panGestureRecognizer.state; | |
| 98 | + if (panState == UIGestureRecognizerStateEnded) {// 手松开 | |
| 99 | + if (_scrollView.mj_insetT + _scrollView.mj_contentH <= _scrollView.mj_h) { // 不够一个屏幕 | |
| 100 | + if (_scrollView.mj_offsetY >= - _scrollView.mj_insetT) { // 向上拽 | |
| 101 | + [self beginRefreshing]; | |
| 102 | + } | |
| 103 | + } else { // 超出一个屏幕 | |
| 104 | + if (_scrollView.mj_offsetY >= _scrollView.mj_contentH + _scrollView.mj_insetB - _scrollView.mj_h) { | |
| 105 | + [self beginRefreshing]; | |
| 106 | + } | |
| 107 | + } | |
| 108 | + } else if (panState == UIGestureRecognizerStateBegan) { | |
| 109 | + self.oneNewPan = YES; | |
| 110 | + } | |
| 111 | +} | |
| 112 | + | |
| 113 | +- (void)beginRefreshing | |
| 114 | +{ | |
| 115 | + if (!self.isOneNewPan && self.isOnlyRefreshPerDrag) return; | |
| 116 | + | |
| 117 | + [super beginRefreshing]; | |
| 118 | + | |
| 119 | + self.oneNewPan = NO; | |
| 120 | +} | |
| 121 | + | |
| 122 | +- (void)setState:(MJRefreshState)state | |
| 123 | +{ | |
| 124 | + MJRefreshCheckState | |
| 125 | + | |
| 126 | + if (state == MJRefreshStateRefreshing) { | |
| 127 | + [self executeRefreshingCallback]; | |
| 128 | + } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { | |
| 129 | + if (MJRefreshStateRefreshing == oldState) { | |
| 130 | + if (self.endRefreshingCompletionBlock) { | |
| 131 | + self.endRefreshingCompletionBlock(); | |
| 132 | + } | |
| 133 | + } | |
| 134 | + } | |
| 135 | +} | |
| 136 | + | |
| 137 | +- (void)setHidden:(BOOL)hidden | |
| 138 | +{ | |
| 139 | + BOOL lastHidden = self.isHidden; | |
| 140 | + | |
| 141 | + [super setHidden:hidden]; | |
| 142 | + | |
| 143 | + if (!lastHidden && hidden) { | |
| 144 | + self.state = MJRefreshStateIdle; | |
| 145 | + | |
| 146 | + self.scrollView.mj_insetB -= self.mj_h; | |
| 147 | + } else if (lastHidden && !hidden) { | |
| 148 | + self.scrollView.mj_insetB += self.mj_h; | |
| 149 | + | |
| 150 | + // 设置位置 | |
| 151 | + self.mj_y = _scrollView.mj_contentH; | |
| 152 | + } | |
| 153 | +} | |
| 154 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h
0 → 100644
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshBackFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshBackFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshBackFooter() | |
| 12 | +@property (assign, nonatomic) NSInteger lastRefreshCount; | |
| 13 | +@property (assign, nonatomic) CGFloat lastBottomDelta; | |
| 14 | +@end | |
| 15 | + | |
| 16 | +@implementation MJRefreshBackFooter | |
| 17 | + | |
| 18 | +#pragma mark - 初始化 | |
| 19 | +- (void)willMoveToSuperview:(UIView *)newSuperview | |
| 20 | +{ | |
| 21 | + [super willMoveToSuperview:newSuperview]; | |
| 22 | + | |
| 23 | + [self scrollViewContentSizeDidChange:nil]; | |
| 24 | +} | |
| 25 | + | |
| 26 | +#pragma mark - 实现父类的方法 | |
| 27 | +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change | |
| 28 | +{ | |
| 29 | + [super scrollViewContentOffsetDidChange:change]; | |
| 30 | + | |
| 31 | + // 如果正在刷新,直接返回 | |
| 32 | + if (self.state == MJRefreshStateRefreshing) return; | |
| 33 | + | |
| 34 | + _scrollViewOriginalInset = self.scrollView.mj_inset; | |
| 35 | + | |
| 36 | + // 当前的contentOffset | |
| 37 | + CGFloat currentOffsetY = self.scrollView.mj_offsetY; | |
| 38 | + // 尾部控件刚好出现的offsetY | |
| 39 | + CGFloat happenOffsetY = [self happenOffsetY]; | |
| 40 | + // 如果是向下滚动到看不见尾部控件,直接返回 | |
| 41 | + if (currentOffsetY <= happenOffsetY) return; | |
| 42 | + | |
| 43 | + CGFloat pullingPercent = (currentOffsetY - happenOffsetY) / self.mj_h; | |
| 44 | + | |
| 45 | + // 如果已全部加载,仅设置pullingPercent,然后返回 | |
| 46 | + if (self.state == MJRefreshStateNoMoreData) { | |
| 47 | + self.pullingPercent = pullingPercent; | |
| 48 | + return; | |
| 49 | + } | |
| 50 | + | |
| 51 | + if (self.scrollView.isDragging) { | |
| 52 | + self.pullingPercent = pullingPercent; | |
| 53 | + // 普通 和 即将刷新 的临界点 | |
| 54 | + CGFloat normal2pullingOffsetY = happenOffsetY + self.mj_h; | |
| 55 | + | |
| 56 | + if (self.state == MJRefreshStateIdle && currentOffsetY > normal2pullingOffsetY) { | |
| 57 | + // 转为即将刷新状态 | |
| 58 | + self.state = MJRefreshStatePulling; | |
| 59 | + } else if (self.state == MJRefreshStatePulling && currentOffsetY <= normal2pullingOffsetY) { | |
| 60 | + // 转为普通状态 | |
| 61 | + self.state = MJRefreshStateIdle; | |
| 62 | + } | |
| 63 | + } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 | |
| 64 | + // 开始刷新 | |
| 65 | + [self beginRefreshing]; | |
| 66 | + } else if (pullingPercent < 1) { | |
| 67 | + self.pullingPercent = pullingPercent; | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 71 | +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change | |
| 72 | +{ | |
| 73 | + [super scrollViewContentSizeDidChange:change]; | |
| 74 | + | |
| 75 | + // 内容的高度 | |
| 76 | + CGFloat contentHeight = self.scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom; | |
| 77 | + // 表格的高度 | |
| 78 | + CGFloat scrollHeight = self.scrollView.mj_h - self.scrollViewOriginalInset.top - self.scrollViewOriginalInset.bottom + self.ignoredScrollViewContentInsetBottom; | |
| 79 | + // 设置位置和尺寸 | |
| 80 | + self.mj_y = MAX(contentHeight, scrollHeight); | |
| 81 | +} | |
| 82 | + | |
| 83 | +- (void)setState:(MJRefreshState)state | |
| 84 | +{ | |
| 85 | + MJRefreshCheckState | |
| 86 | + | |
| 87 | + // 根据状态来设置属性 | |
| 88 | + if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { | |
| 89 | + // 刷新完毕 | |
| 90 | + if (MJRefreshStateRefreshing == oldState) { | |
| 91 | + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ | |
| 92 | + self.scrollView.mj_insetB -= self.lastBottomDelta; | |
| 93 | + | |
| 94 | + // 自动调整透明度 | |
| 95 | + if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; | |
| 96 | + } completion:^(BOOL finished) { | |
| 97 | + self.pullingPercent = 0.0; | |
| 98 | + | |
| 99 | + if (self.endRefreshingCompletionBlock) { | |
| 100 | + self.endRefreshingCompletionBlock(); | |
| 101 | + } | |
| 102 | + }]; | |
| 103 | + } | |
| 104 | + | |
| 105 | + CGFloat deltaH = [self heightForContentBreakView]; | |
| 106 | + // 刚刷新完毕 | |
| 107 | + if (MJRefreshStateRefreshing == oldState && deltaH > 0 && self.scrollView.mj_totalDataCount != self.lastRefreshCount) { | |
| 108 | + self.scrollView.mj_offsetY = self.scrollView.mj_offsetY; | |
| 109 | + } | |
| 110 | + } else if (state == MJRefreshStateRefreshing) { | |
| 111 | + // 记录刷新前的数量 | |
| 112 | + self.lastRefreshCount = self.scrollView.mj_totalDataCount; | |
| 113 | + | |
| 114 | + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ | |
| 115 | + CGFloat bottom = self.mj_h + self.scrollViewOriginalInset.bottom; | |
| 116 | + CGFloat deltaH = [self heightForContentBreakView]; | |
| 117 | + if (deltaH < 0) { // 如果内容高度小于view的高度 | |
| 118 | + bottom -= deltaH; | |
| 119 | + } | |
| 120 | + self.lastBottomDelta = bottom - self.scrollView.mj_insetB; | |
| 121 | + self.scrollView.mj_insetB = bottom; | |
| 122 | + self.scrollView.mj_offsetY = [self happenOffsetY] + self.mj_h; | |
| 123 | + } completion:^(BOOL finished) { | |
| 124 | + [self executeRefreshingCallback]; | |
| 125 | + }]; | |
| 126 | + } | |
| 127 | +} | |
| 128 | +#pragma mark - 私有方法 | |
| 129 | +#pragma mark 获得scrollView的内容 超出 view 的高度 | |
| 130 | +- (CGFloat)heightForContentBreakView | |
| 131 | +{ | |
| 132 | + CGFloat h = self.scrollView.frame.size.height - self.scrollViewOriginalInset.bottom - self.scrollViewOriginalInset.top; | |
| 133 | + return self.scrollView.contentSize.height - h; | |
| 134 | +} | |
| 135 | + | |
| 136 | +#pragma mark 刚好看到上拉刷新控件时的contentOffset.y | |
| 137 | +- (CGFloat)happenOffsetY | |
| 138 | +{ | |
| 139 | + CGFloat deltaH = [self heightForContentBreakView]; | |
| 140 | + if (deltaH > 0) { | |
| 141 | + return deltaH - self.scrollViewOriginalInset.top; | |
| 142 | + } else { | |
| 143 | + return - self.scrollViewOriginalInset.top; | |
| 144 | + } | |
| 145 | +} | |
| 146 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// MJRefreshComponent.h | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/4. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// 刷新控件的基类 | |
| 9 | + | |
| 10 | +#import <UIKit/UIKit.h> | |
| 11 | +#import "MJRefreshConst.h" | |
| 12 | +#import "UIView+MJExtension.h" | |
| 13 | +#import "UIScrollView+MJExtension.h" | |
| 14 | +#import "UIScrollView+MJRefresh.h" | |
| 15 | +#import "NSBundle+MJRefresh.h" | |
| 16 | + | |
| 17 | +/** 刷新控件的状态 */ | |
| 18 | +typedef NS_ENUM(NSInteger, MJRefreshState) { | |
| 19 | + /** 普通闲置状态 */ | |
| 20 | + MJRefreshStateIdle = 1, | |
| 21 | + /** 松开就可以进行刷新的状态 */ | |
| 22 | + MJRefreshStatePulling, | |
| 23 | + /** 正在刷新中的状态 */ | |
| 24 | + MJRefreshStateRefreshing, | |
| 25 | + /** 即将刷新的状态 */ | |
| 26 | + MJRefreshStateWillRefresh, | |
| 27 | + /** 所有数据加载完毕,没有更多的数据了 */ | |
| 28 | + MJRefreshStateNoMoreData | |
| 29 | +}; | |
| 30 | + | |
| 31 | +/** 进入刷新状态的回调 */ | |
| 32 | +typedef void (^MJRefreshComponentRefreshingBlock)(void); | |
| 33 | +/** 开始刷新后的回调(进入刷新状态后的回调) */ | |
| 34 | +typedef void (^MJRefreshComponentbeginRefreshingCompletionBlock)(void); | |
| 35 | +/** 结束刷新后的回调 */ | |
| 36 | +typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void); | |
| 37 | + | |
| 38 | +/** 刷新控件的基类 */ | |
| 39 | +@interface MJRefreshComponent : UIView | |
| 40 | +{ | |
| 41 | + /** 记录scrollView刚开始的inset */ | |
| 42 | + UIEdgeInsets _scrollViewOriginalInset; | |
| 43 | + /** 父控件 */ | |
| 44 | + __weak UIScrollView *_scrollView; | |
| 45 | +} | |
| 46 | +#pragma mark - 刷新回调 | |
| 47 | +/** 正在刷新的回调 */ | |
| 48 | +@property (copy, nonatomic) MJRefreshComponentRefreshingBlock refreshingBlock; | |
| 49 | +/** 设置回调对象和回调方法 */ | |
| 50 | +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action; | |
| 51 | + | |
| 52 | +/** 回调对象 */ | |
| 53 | +@property (weak, nonatomic) id refreshingTarget; | |
| 54 | +/** 回调方法 */ | |
| 55 | +@property (assign, nonatomic) SEL refreshingAction; | |
| 56 | +/** 触发回调(交给子类去调用) */ | |
| 57 | +- (void)executeRefreshingCallback; | |
| 58 | + | |
| 59 | +#pragma mark - 刷新状态控制 | |
| 60 | +/** 进入刷新状态 */ | |
| 61 | +- (void)beginRefreshing; | |
| 62 | +- (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock; | |
| 63 | +/** 开始刷新后的回调(进入刷新状态后的回调) */ | |
| 64 | +@property (copy, nonatomic) MJRefreshComponentbeginRefreshingCompletionBlock beginRefreshingCompletionBlock; | |
| 65 | +/** 结束刷新的回调 */ | |
| 66 | +@property (copy, nonatomic) MJRefreshComponentEndRefreshingCompletionBlock endRefreshingCompletionBlock; | |
| 67 | +/** 结束刷新状态 */ | |
| 68 | +- (void)endRefreshing; | |
| 69 | +- (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock; | |
| 70 | +/** 是否正在刷新 */ | |
| 71 | +@property (assign, nonatomic, readonly, getter=isRefreshing) BOOL refreshing; | |
| 72 | +//- (BOOL)isRefreshing; | |
| 73 | +/** 刷新状态 一般交给子类内部实现 */ | |
| 74 | +@property (assign, nonatomic) MJRefreshState state; | |
| 75 | + | |
| 76 | +#pragma mark - 交给子类去访问 | |
| 77 | +/** 记录scrollView刚开始的inset */ | |
| 78 | +@property (assign, nonatomic, readonly) UIEdgeInsets scrollViewOriginalInset; | |
| 79 | +/** 父控件 */ | |
| 80 | +@property (weak, nonatomic, readonly) UIScrollView *scrollView; | |
| 81 | + | |
| 82 | +#pragma mark - 交给子类们去实现 | |
| 83 | +/** 初始化 */ | |
| 84 | +- (void)prepare NS_REQUIRES_SUPER; | |
| 85 | +/** 摆放子控件frame */ | |
| 86 | +- (void)placeSubviews NS_REQUIRES_SUPER; | |
| 87 | +/** 当scrollView的contentOffset发生改变的时候调用 */ | |
| 88 | +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; | |
| 89 | +/** 当scrollView的contentSize发生改变的时候调用 */ | |
| 90 | +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; | |
| 91 | +/** 当scrollView的拖拽状态发生改变的时候调用 */ | |
| 92 | +- (void)scrollViewPanStateDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; | |
| 93 | + | |
| 94 | + | |
| 95 | +#pragma mark - 其他 | |
| 96 | +/** 拉拽的百分比(交给子类重写) */ | |
| 97 | +@property (assign, nonatomic) CGFloat pullingPercent; | |
| 98 | +/** 根据拖拽比例自动切换透明度 */ | |
| 99 | +@property (assign, nonatomic, getter=isAutoChangeAlpha) BOOL autoChangeAlpha MJRefreshDeprecated("请使用automaticallyChangeAlpha属性"); | |
| 100 | +/** 根据拖拽比例自动切换透明度 */ | |
| 101 | +@property (assign, nonatomic, getter=isAutomaticallyChangeAlpha) BOOL automaticallyChangeAlpha; | |
| 102 | +@end | |
| 103 | + | |
| 104 | +@interface UILabel(MJRefresh) | |
| 105 | ++ (instancetype)mj_label; | |
| 106 | +- (CGFloat)mj_textWith; | |
| 107 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.m
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// MJRefreshComponent.m | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/4. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import "MJRefreshComponent.h" | |
| 11 | +#import "MJRefreshConst.h" | |
| 12 | + | |
| 13 | +@interface MJRefreshComponent() | |
| 14 | +@property (strong, nonatomic) UIPanGestureRecognizer *pan; | |
| 15 | +@end | |
| 16 | + | |
| 17 | +@implementation MJRefreshComponent | |
| 18 | +#pragma mark - 初始化 | |
| 19 | +- (instancetype)initWithFrame:(CGRect)frame | |
| 20 | +{ | |
| 21 | + if (self = [super initWithFrame:frame]) { | |
| 22 | + // 准备工作 | |
| 23 | + [self prepare]; | |
| 24 | + | |
| 25 | + // 默认是普通状态 | |
| 26 | + self.state = MJRefreshStateIdle; | |
| 27 | + } | |
| 28 | + return self; | |
| 29 | +} | |
| 30 | + | |
| 31 | +- (void)prepare | |
| 32 | +{ | |
| 33 | + // 基本属性 | |
| 34 | + self.autoresizingMask = UIViewAutoresizingFlexibleWidth; | |
| 35 | + self.backgroundColor = [UIColor clearColor]; | |
| 36 | +} | |
| 37 | + | |
| 38 | +- (void)layoutSubviews | |
| 39 | +{ | |
| 40 | + [self placeSubviews]; | |
| 41 | + | |
| 42 | + [super layoutSubviews]; | |
| 43 | +} | |
| 44 | + | |
| 45 | +- (void)placeSubviews{} | |
| 46 | + | |
| 47 | +- (void)willMoveToSuperview:(UIView *)newSuperview | |
| 48 | +{ | |
| 49 | + [super willMoveToSuperview:newSuperview]; | |
| 50 | + | |
| 51 | + // 如果不是UIScrollView,不做任何事情 | |
| 52 | + if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return; | |
| 53 | + | |
| 54 | + // 旧的父控件移除监听 | |
| 55 | + [self removeObservers]; | |
| 56 | + | |
| 57 | + if (newSuperview) { // 新的父控件 | |
| 58 | + // 设置宽度 | |
| 59 | + self.mj_w = newSuperview.mj_w; | |
| 60 | + // 设置位置 | |
| 61 | + self.mj_x = -_scrollView.mj_insetL; | |
| 62 | + | |
| 63 | + // 记录UIScrollView | |
| 64 | + _scrollView = (UIScrollView *)newSuperview; | |
| 65 | + // 设置永远支持垂直弹簧效果 | |
| 66 | + _scrollView.alwaysBounceVertical = YES; | |
| 67 | + // 记录UIScrollView最开始的contentInset | |
| 68 | + _scrollViewOriginalInset = _scrollView.mj_inset; | |
| 69 | + | |
| 70 | + // 添加监听 | |
| 71 | + [self addObservers]; | |
| 72 | + } | |
| 73 | +} | |
| 74 | + | |
| 75 | +- (void)drawRect:(CGRect)rect | |
| 76 | +{ | |
| 77 | + [super drawRect:rect]; | |
| 78 | + | |
| 79 | + if (self.state == MJRefreshStateWillRefresh) { | |
| 80 | + // 预防view还没显示出来就调用了beginRefreshing | |
| 81 | + self.state = MJRefreshStateRefreshing; | |
| 82 | + } | |
| 83 | +} | |
| 84 | + | |
| 85 | +#pragma mark - KVO监听 | |
| 86 | +- (void)addObservers | |
| 87 | +{ | |
| 88 | + NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld; | |
| 89 | + [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil]; | |
| 90 | + [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil]; | |
| 91 | + self.pan = self.scrollView.panGestureRecognizer; | |
| 92 | + [self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil]; | |
| 93 | +} | |
| 94 | + | |
| 95 | +- (void)removeObservers | |
| 96 | +{ | |
| 97 | + [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset]; | |
| 98 | + [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize]; | |
| 99 | + [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState]; | |
| 100 | + self.pan = nil; | |
| 101 | +} | |
| 102 | + | |
| 103 | +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context | |
| 104 | +{ | |
| 105 | + // 遇到这些情况就直接返回 | |
| 106 | + if (!self.userInteractionEnabled) return; | |
| 107 | + | |
| 108 | + // 这个就算看不见也需要处理 | |
| 109 | + if ([keyPath isEqualToString:MJRefreshKeyPathContentSize]) { | |
| 110 | + [self scrollViewContentSizeDidChange:change]; | |
| 111 | + } | |
| 112 | + | |
| 113 | + // 看不见 | |
| 114 | + if (self.hidden) return; | |
| 115 | + if ([keyPath isEqualToString:MJRefreshKeyPathContentOffset]) { | |
| 116 | + [self scrollViewContentOffsetDidChange:change]; | |
| 117 | + } else if ([keyPath isEqualToString:MJRefreshKeyPathPanState]) { | |
| 118 | + [self scrollViewPanStateDidChange:change]; | |
| 119 | + } | |
| 120 | +} | |
| 121 | + | |
| 122 | +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{} | |
| 123 | +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change{} | |
| 124 | +- (void)scrollViewPanStateDidChange:(NSDictionary *)change{} | |
| 125 | + | |
| 126 | +#pragma mark - 公共方法 | |
| 127 | +#pragma mark 设置回调对象和回调方法 | |
| 128 | +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action | |
| 129 | +{ | |
| 130 | + self.refreshingTarget = target; | |
| 131 | + self.refreshingAction = action; | |
| 132 | +} | |
| 133 | + | |
| 134 | +- (void)setState:(MJRefreshState)state | |
| 135 | +{ | |
| 136 | + _state = state; | |
| 137 | + | |
| 138 | + // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件 | |
| 139 | + MJRefreshDispatchAsyncOnMainQueue([self setNeedsLayout];) | |
| 140 | +} | |
| 141 | + | |
| 142 | +#pragma mark 进入刷新状态 | |
| 143 | +- (void)beginRefreshing | |
| 144 | +{ | |
| 145 | + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ | |
| 146 | + self.alpha = 1.0; | |
| 147 | + }]; | |
| 148 | + self.pullingPercent = 1.0; | |
| 149 | + // 只要正在刷新,就完全显示 | |
| 150 | + if (self.window) { | |
| 151 | + self.state = MJRefreshStateRefreshing; | |
| 152 | + } else { | |
| 153 | + // 预防正在刷新中时,调用本方法使得header inset回置失败 | |
| 154 | + if (self.state != MJRefreshStateRefreshing) { | |
| 155 | + self.state = MJRefreshStateWillRefresh; | |
| 156 | + // 刷新(预防从另一个控制器回到这个控制器的情况,回来要重新刷新一下) | |
| 157 | + [self setNeedsDisplay]; | |
| 158 | + } | |
| 159 | + } | |
| 160 | +} | |
| 161 | + | |
| 162 | +- (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock | |
| 163 | +{ | |
| 164 | + self.beginRefreshingCompletionBlock = completionBlock; | |
| 165 | + | |
| 166 | + [self beginRefreshing]; | |
| 167 | +} | |
| 168 | + | |
| 169 | +#pragma mark 结束刷新状态 | |
| 170 | +- (void)endRefreshing | |
| 171 | +{ | |
| 172 | + MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;) | |
| 173 | +} | |
| 174 | + | |
| 175 | +- (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock | |
| 176 | +{ | |
| 177 | + self.endRefreshingCompletionBlock = completionBlock; | |
| 178 | + | |
| 179 | + [self endRefreshing]; | |
| 180 | +} | |
| 181 | + | |
| 182 | +#pragma mark 是否正在刷新 | |
| 183 | +- (BOOL)isRefreshing | |
| 184 | +{ | |
| 185 | + return self.state == MJRefreshStateRefreshing || self.state == MJRefreshStateWillRefresh; | |
| 186 | +} | |
| 187 | + | |
| 188 | +#pragma mark 自动切换透明度 | |
| 189 | +- (void)setAutoChangeAlpha:(BOOL)autoChangeAlpha | |
| 190 | +{ | |
| 191 | + self.automaticallyChangeAlpha = autoChangeAlpha; | |
| 192 | +} | |
| 193 | + | |
| 194 | +- (BOOL)isAutoChangeAlpha | |
| 195 | +{ | |
| 196 | + return self.isAutomaticallyChangeAlpha; | |
| 197 | +} | |
| 198 | + | |
| 199 | +- (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha | |
| 200 | +{ | |
| 201 | + _automaticallyChangeAlpha = automaticallyChangeAlpha; | |
| 202 | + | |
| 203 | + if (self.isRefreshing) return; | |
| 204 | + | |
| 205 | + if (automaticallyChangeAlpha) { | |
| 206 | + self.alpha = self.pullingPercent; | |
| 207 | + } else { | |
| 208 | + self.alpha = 1.0; | |
| 209 | + } | |
| 210 | +} | |
| 211 | + | |
| 212 | +#pragma mark 根据拖拽进度设置透明度 | |
| 213 | +- (void)setPullingPercent:(CGFloat)pullingPercent | |
| 214 | +{ | |
| 215 | + _pullingPercent = pullingPercent; | |
| 216 | + | |
| 217 | + if (self.isRefreshing) return; | |
| 218 | + | |
| 219 | + if (self.isAutomaticallyChangeAlpha) { | |
| 220 | + self.alpha = pullingPercent; | |
| 221 | + } | |
| 222 | +} | |
| 223 | + | |
| 224 | +#pragma mark - 内部方法 | |
| 225 | +- (void)executeRefreshingCallback | |
| 226 | +{ | |
| 227 | + MJRefreshDispatchAsyncOnMainQueue({ | |
| 228 | + if (self.refreshingBlock) { | |
| 229 | + self.refreshingBlock(); | |
| 230 | + } | |
| 231 | + if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) { | |
| 232 | + MJRefreshMsgSend(MJRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self); | |
| 233 | + } | |
| 234 | + if (self.beginRefreshingCompletionBlock) { | |
| 235 | + self.beginRefreshingCompletionBlock(); | |
| 236 | + } | |
| 237 | + }) | |
| 238 | +} | |
| 239 | +@end | |
| 240 | + | |
| 241 | +@implementation UILabel(MJRefresh) | |
| 242 | ++ (instancetype)mj_label | |
| 243 | +{ | |
| 244 | + UILabel *label = [[self alloc] init]; | |
| 245 | + label.font = MJRefreshLabelFont; | |
| 246 | + label.textColor = MJRefreshLabelTextColor; | |
| 247 | + label.autoresizingMask = UIViewAutoresizingFlexibleWidth; | |
| 248 | + label.textAlignment = NSTextAlignmentCenter; | |
| 249 | + label.backgroundColor = [UIColor clearColor]; | |
| 250 | + return label; | |
| 251 | +} | |
| 252 | + | |
| 253 | +- (CGFloat)mj_textWith { | |
| 254 | + CGFloat stringWidth = 0; | |
| 255 | + CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT); | |
| 256 | + if (self.text.length > 0) { | |
| 257 | +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 | |
| 258 | + stringWidth =[self.text | |
| 259 | + boundingRectWithSize:size | |
| 260 | + options:NSStringDrawingUsesLineFragmentOrigin | |
| 261 | + attributes:@{NSFontAttributeName:self.font} | |
| 262 | + context:nil].size.width; | |
| 263 | +#else | |
| 264 | + | |
| 265 | + stringWidth = [self.text sizeWithFont:self.font | |
| 266 | + constrainedToSize:size | |
| 267 | + lineBreakMode:NSLineBreakByCharWrapping].width; | |
| 268 | +#endif | |
| 269 | + } | |
| 270 | + return stringWidth; | |
| 271 | +} | |
| 272 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// MJRefreshFooter.h | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/5. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// 上拉刷新控件 | |
| 9 | + | |
| 10 | +#import "MJRefreshComponent.h" | |
| 11 | + | |
| 12 | +@interface MJRefreshFooter : MJRefreshComponent | |
| 13 | +/** 创建footer */ | |
| 14 | ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; | |
| 15 | +/** 创建footer */ | |
| 16 | ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; | |
| 17 | + | |
| 18 | +/** 提示没有更多的数据 */ | |
| 19 | +- (void)endRefreshingWithNoMoreData; | |
| 20 | +- (void)noticeNoMoreData MJRefreshDeprecated("使用endRefreshingWithNoMoreData"); | |
| 21 | + | |
| 22 | +/** 重置没有更多的数据(消除没有更多数据的状态) */ | |
| 23 | +- (void)resetNoMoreData; | |
| 24 | + | |
| 25 | +/** 忽略多少scrollView的contentInset的bottom */ | |
| 26 | +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; | |
| 27 | + | |
| 28 | +/** 自动根据有无数据来显示和隐藏(有数据就显示,没有数据隐藏。默认是NO) */ | |
| 29 | +@property (assign, nonatomic, getter=isAutomaticallyHidden) BOOL automaticallyHidden MJRefreshDeprecated("不建议使用此属性,开发者请自行控制footer的显示和隐藏。基于安全考虑,在未来的某些版本此属性可能作废"); | |
| 30 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.m
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// MJRefreshFooter.m | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/5. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import "MJRefreshFooter.h" | |
| 11 | +#include "UIScrollView+MJRefresh.h" | |
| 12 | + | |
| 13 | +@interface MJRefreshFooter() | |
| 14 | + | |
| 15 | +@end | |
| 16 | + | |
| 17 | +@implementation MJRefreshFooter | |
| 18 | +#pragma mark - 构造方法 | |
| 19 | ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)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 | +- (void)willMoveToSuperview:(UIView *)newSuperview | |
| 45 | +{ | |
| 46 | + [super willMoveToSuperview:newSuperview]; | |
| 47 | + | |
| 48 | + if (newSuperview) { | |
| 49 | + // 监听scrollView数据的变化 | |
| 50 | + if ([self.scrollView isKindOfClass:[UITableView class]] || [self.scrollView isKindOfClass:[UICollectionView class]]) { | |
| 51 | + [self.scrollView setMj_reloadDataBlock:^(NSInteger totalDataCount) { | |
| 52 | + if (self.isAutomaticallyHidden) { | |
| 53 | + self.hidden = (totalDataCount == 0); | |
| 54 | + } | |
| 55 | + }]; | |
| 56 | + } | |
| 57 | + } | |
| 58 | +} | |
| 59 | + | |
| 60 | +#pragma mark - 公共方法 | |
| 61 | +- (void)endRefreshingWithNoMoreData | |
| 62 | +{ | |
| 63 | + MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateNoMoreData;) | |
| 64 | +} | |
| 65 | + | |
| 66 | +- (void)noticeNoMoreData | |
| 67 | +{ | |
| 68 | + [self endRefreshingWithNoMoreData]; | |
| 69 | +} | |
| 70 | + | |
| 71 | +- (void)resetNoMoreData | |
| 72 | +{ | |
| 73 | + MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;) | |
| 74 | +} | |
| 75 | + | |
| 76 | +- (void)setAutomaticallyHidden:(BOOL)automaticallyHidden | |
| 77 | +{ | |
| 78 | + _automaticallyHidden = automaticallyHidden; | |
| 79 | +} | |
| 80 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// MJRefreshHeader.h | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/4. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// 下拉刷新控件:负责监控用户下拉的状态 | |
| 9 | + | |
| 10 | +#import "MJRefreshComponent.h" | |
| 11 | + | |
| 12 | +@interface MJRefreshHeader : MJRefreshComponent | |
| 13 | +/** 创建header */ | |
| 14 | ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; | |
| 15 | +/** 创建header */ | |
| 16 | ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; | |
| 17 | + | |
| 18 | +/** 这个key用来存储上一次下拉刷新成功的时间 */ | |
| 19 | +@property (copy, nonatomic) NSString *lastUpdatedTimeKey; | |
| 20 | +/** 上一次下拉刷新成功的时间 */ | |
| 21 | +@property (strong, nonatomic, readonly) NSDate *lastUpdatedTime; | |
| 22 | + | |
| 23 | +/** 忽略多少scrollView的contentInset的top */ | |
| 24 | +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; | |
| 25 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.m
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// MJRefreshHeader.m | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/4. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import "MJRefreshHeader.h" | |
| 11 | + | |
| 12 | +@interface MJRefreshHeader() | |
| 13 | +@property (assign, nonatomic) CGFloat insetTDelta; | |
| 14 | +@end | |
| 15 | + | |
| 16 | +@implementation MJRefreshHeader | |
| 17 | +#pragma mark - 构造方法 | |
| 18 | ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock | |
| 19 | +{ | |
| 20 | + MJRefreshHeader *cmp = [[self alloc] init]; | |
| 21 | + cmp.refreshingBlock = refreshingBlock; | |
| 22 | + return cmp; | |
| 23 | +} | |
| 24 | ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action | |
| 25 | +{ | |
| 26 | + MJRefreshHeader *cmp = [[self alloc] init]; | |
| 27 | + [cmp setRefreshingTarget:target refreshingAction:action]; | |
| 28 | + return cmp; | |
| 29 | +} | |
| 30 | + | |
| 31 | +#pragma mark - 覆盖父类的方法 | |
| 32 | +- (void)prepare | |
| 33 | +{ | |
| 34 | + [super prepare]; | |
| 35 | + | |
| 36 | + // 设置key | |
| 37 | + self.lastUpdatedTimeKey = MJRefreshHeaderLastUpdatedTimeKey; | |
| 38 | + | |
| 39 | + // 设置高度 | |
| 40 | + self.mj_h = MJRefreshHeaderHeight; | |
| 41 | +} | |
| 42 | + | |
| 43 | +- (void)placeSubviews | |
| 44 | +{ | |
| 45 | + [super placeSubviews]; | |
| 46 | + | |
| 47 | + // 设置y值(当自己的高度发生改变了,肯定要重新调整Y值,所以放到placeSubviews方法中设置y值) | |
| 48 | + self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop; | |
| 49 | +} | |
| 50 | + | |
| 51 | +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change | |
| 52 | +{ | |
| 53 | + [super scrollViewContentOffsetDidChange:change]; | |
| 54 | + | |
| 55 | + // 在刷新的refreshing状态 | |
| 56 | + if (self.state == MJRefreshStateRefreshing) { | |
| 57 | + // 暂时保留 | |
| 58 | + if (self.window == nil) return; | |
| 59 | + | |
| 60 | + // sectionheader停留解决 | |
| 61 | + CGFloat insetT = - self.scrollView.mj_offsetY > _scrollViewOriginalInset.top ? - self.scrollView.mj_offsetY : _scrollViewOriginalInset.top; | |
| 62 | + insetT = insetT > self.mj_h + _scrollViewOriginalInset.top ? self.mj_h + _scrollViewOriginalInset.top : insetT; | |
| 63 | + self.scrollView.mj_insetT = insetT; | |
| 64 | + | |
| 65 | + self.insetTDelta = _scrollViewOriginalInset.top - insetT; | |
| 66 | + return; | |
| 67 | + } | |
| 68 | + | |
| 69 | + // 跳转到下一个控制器时,contentInset可能会变 | |
| 70 | + _scrollViewOriginalInset = self.scrollView.mj_inset; | |
| 71 | + | |
| 72 | + // 当前的contentOffset | |
| 73 | + CGFloat offsetY = self.scrollView.mj_offsetY; | |
| 74 | + // 头部控件刚好出现的offsetY | |
| 75 | + CGFloat happenOffsetY = - self.scrollViewOriginalInset.top; | |
| 76 | + | |
| 77 | + // 如果是向上滚动到看不见头部控件,直接返回 | |
| 78 | + // >= -> > | |
| 79 | + if (offsetY > happenOffsetY) return; | |
| 80 | + | |
| 81 | + // 普通 和 即将刷新 的临界点 | |
| 82 | + CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h; | |
| 83 | + CGFloat pullingPercent = (happenOffsetY - offsetY) / self.mj_h; | |
| 84 | + | |
| 85 | + if (self.scrollView.isDragging) { // 如果正在拖拽 | |
| 86 | + self.pullingPercent = pullingPercent; | |
| 87 | + if (self.state == MJRefreshStateIdle && offsetY < normal2pullingOffsetY) { | |
| 88 | + // 转为即将刷新状态 | |
| 89 | + self.state = MJRefreshStatePulling; | |
| 90 | + } else if (self.state == MJRefreshStatePulling && offsetY >= normal2pullingOffsetY) { | |
| 91 | + // 转为普通状态 | |
| 92 | + self.state = MJRefreshStateIdle; | |
| 93 | + } | |
| 94 | + } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 | |
| 95 | + // 开始刷新 | |
| 96 | + [self beginRefreshing]; | |
| 97 | + } else if (pullingPercent < 1) { | |
| 98 | + self.pullingPercent = pullingPercent; | |
| 99 | + } | |
| 100 | +} | |
| 101 | + | |
| 102 | +- (void)setState:(MJRefreshState)state | |
| 103 | +{ | |
| 104 | + MJRefreshCheckState | |
| 105 | + | |
| 106 | + // 根据状态做事情 | |
| 107 | + if (state == MJRefreshStateIdle) { | |
| 108 | + if (oldState != MJRefreshStateRefreshing) return; | |
| 109 | + | |
| 110 | + // 保存刷新时间 | |
| 111 | + [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:self.lastUpdatedTimeKey]; | |
| 112 | + [[NSUserDefaults standardUserDefaults] synchronize]; | |
| 113 | + | |
| 114 | + // 恢复inset和offset | |
| 115 | + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ | |
| 116 | + self.scrollView.mj_insetT += self.insetTDelta; | |
| 117 | + | |
| 118 | + // 自动调整透明度 | |
| 119 | + if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; | |
| 120 | + } completion:^(BOOL finished) { | |
| 121 | + self.pullingPercent = 0.0; | |
| 122 | + | |
| 123 | + if (self.endRefreshingCompletionBlock) { | |
| 124 | + self.endRefreshingCompletionBlock(); | |
| 125 | + } | |
| 126 | + }]; | |
| 127 | + } else if (state == MJRefreshStateRefreshing) { | |
| 128 | + MJRefreshDispatchAsyncOnMainQueue({ | |
| 129 | + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ | |
| 130 | + if (self.scrollView.panGestureRecognizer.state != UIGestureRecognizerStateCancelled) { | |
| 131 | + CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; | |
| 132 | + // 增加滚动区域top | |
| 133 | + self.scrollView.mj_insetT = top; | |
| 134 | + // 设置滚动位置 | |
| 135 | + CGPoint offset = self.scrollView.contentOffset; | |
| 136 | + offset.y = -top; | |
| 137 | + [self.scrollView setContentOffset:offset animated:NO]; | |
| 138 | + } | |
| 139 | + } completion:^(BOOL finished) { | |
| 140 | + [self executeRefreshingCallback]; | |
| 141 | + }]; | |
| 142 | + }) | |
| 143 | + } | |
| 144 | +} | |
| 145 | + | |
| 146 | +#pragma mark - 公共方法 | |
| 147 | +- (NSDate *)lastUpdatedTime | |
| 148 | +{ | |
| 149 | + return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey]; | |
| 150 | +} | |
| 151 | + | |
| 152 | +- (void)setIgnoredScrollViewContentInsetTop:(CGFloat)ignoredScrollViewContentInsetTop { | |
| 153 | + _ignoredScrollViewContentInsetTop = ignoredScrollViewContentInsetTop; | |
| 154 | + | |
| 155 | + self.mj_y = - self.mj_h - _ignoredScrollViewContentInsetTop; | |
| 156 | +} | |
| 157 | + | |
| 158 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoGifFooter.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshAutoStateFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoGifFooter : MJRefreshAutoStateFooter | |
| 12 | +@property (weak, nonatomic, readonly) UIImageView *gifView; | |
| 13 | + | |
| 14 | +/** 设置state状态下的动画图片images 动画持续时间duration*/ | |
| 15 | +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; | |
| 16 | +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; | |
| 17 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoGifFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshAutoGifFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoGifFooter() | |
| 12 | +{ | |
| 13 | + __unsafe_unretained UIImageView *_gifView; | |
| 14 | +} | |
| 15 | +/** 所有状态对应的动画图片 */ | |
| 16 | +@property (strong, nonatomic) NSMutableDictionary *stateImages; | |
| 17 | +/** 所有状态对应的动画时间 */ | |
| 18 | +@property (strong, nonatomic) NSMutableDictionary *stateDurations; | |
| 19 | +@end | |
| 20 | + | |
| 21 | +@implementation MJRefreshAutoGifFooter | |
| 22 | +#pragma mark - 懒加载 | |
| 23 | +- (UIImageView *)gifView | |
| 24 | +{ | |
| 25 | + if (!_gifView) { | |
| 26 | + UIImageView *gifView = [[UIImageView alloc] init]; | |
| 27 | + [self addSubview:_gifView = gifView]; | |
| 28 | + } | |
| 29 | + return _gifView; | |
| 30 | +} | |
| 31 | + | |
| 32 | +- (NSMutableDictionary *)stateImages | |
| 33 | +{ | |
| 34 | + if (!_stateImages) { | |
| 35 | + self.stateImages = [NSMutableDictionary dictionary]; | |
| 36 | + } | |
| 37 | + return _stateImages; | |
| 38 | +} | |
| 39 | + | |
| 40 | +- (NSMutableDictionary *)stateDurations | |
| 41 | +{ | |
| 42 | + if (!_stateDurations) { | |
| 43 | + self.stateDurations = [NSMutableDictionary dictionary]; | |
| 44 | + } | |
| 45 | + return _stateDurations; | |
| 46 | +} | |
| 47 | + | |
| 48 | +#pragma mark - 公共方法 | |
| 49 | +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state | |
| 50 | +{ | |
| 51 | + if (images == nil) return; | |
| 52 | + | |
| 53 | + self.stateImages[@(state)] = images; | |
| 54 | + self.stateDurations[@(state)] = @(duration); | |
| 55 | + | |
| 56 | + /* 根据图片设置控件的高度 */ | |
| 57 | + UIImage *image = [images firstObject]; | |
| 58 | + if (image.size.height > self.mj_h) { | |
| 59 | + self.mj_h = image.size.height; | |
| 60 | + } | |
| 61 | +} | |
| 62 | + | |
| 63 | +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state | |
| 64 | +{ | |
| 65 | + [self setImages:images duration:images.count * 0.1 forState:state]; | |
| 66 | +} | |
| 67 | + | |
| 68 | +#pragma mark - 实现父类的方法 | |
| 69 | +- (void)prepare | |
| 70 | +{ | |
| 71 | + [super prepare]; | |
| 72 | + | |
| 73 | + // 初始化间距 | |
| 74 | + self.labelLeftInset = 20; | |
| 75 | +} | |
| 76 | + | |
| 77 | +- (void)placeSubviews | |
| 78 | +{ | |
| 79 | + [super placeSubviews]; | |
| 80 | + | |
| 81 | + if (self.gifView.constraints.count) return; | |
| 82 | + | |
| 83 | + self.gifView.frame = self.bounds; | |
| 84 | + if (self.isRefreshingTitleHidden) { | |
| 85 | + self.gifView.contentMode = UIViewContentModeCenter; | |
| 86 | + } else { | |
| 87 | + self.gifView.contentMode = UIViewContentModeRight; | |
| 88 | + self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWith * 0.5; | |
| 89 | + } | |
| 90 | +} | |
| 91 | + | |
| 92 | +- (void)setState:(MJRefreshState)state | |
| 93 | +{ | |
| 94 | + MJRefreshCheckState | |
| 95 | + | |
| 96 | + // 根据状态做事情 | |
| 97 | + if (state == MJRefreshStateRefreshing) { | |
| 98 | + NSArray *images = self.stateImages[@(state)]; | |
| 99 | + if (images.count == 0) return; | |
| 100 | + [self.gifView stopAnimating]; | |
| 101 | + | |
| 102 | + self.gifView.hidden = NO; | |
| 103 | + if (images.count == 1) { // 单张图片 | |
| 104 | + self.gifView.image = [images lastObject]; | |
| 105 | + } else { // 多张图片 | |
| 106 | + self.gifView.animationImages = images; | |
| 107 | + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; | |
| 108 | + [self.gifView startAnimating]; | |
| 109 | + } | |
| 110 | + } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { | |
| 111 | + [self.gifView stopAnimating]; | |
| 112 | + self.gifView.hidden = YES; | |
| 113 | + } | |
| 114 | +} | |
| 115 | +@end | |
| 116 | + | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoNormalFooter.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshAutoStateFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoNormalFooter : MJRefreshAutoStateFooter | |
| 12 | +/** 菊花的样式 */ | |
| 13 | +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; | |
| 14 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoNormalFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshAutoNormalFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoNormalFooter() | |
| 12 | +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; | |
| 13 | +@end | |
| 14 | + | |
| 15 | +@implementation MJRefreshAutoNormalFooter | |
| 16 | +#pragma mark - 懒加载子控件 | |
| 17 | +- (UIActivityIndicatorView *)loadingView | |
| 18 | +{ | |
| 19 | + if (!_loadingView) { | |
| 20 | + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; | |
| 21 | + loadingView.hidesWhenStopped = YES; | |
| 22 | + [self addSubview:_loadingView = loadingView]; | |
| 23 | + } | |
| 24 | + return _loadingView; | |
| 25 | +} | |
| 26 | + | |
| 27 | +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle | |
| 28 | +{ | |
| 29 | + _activityIndicatorViewStyle = activityIndicatorViewStyle; | |
| 30 | + | |
| 31 | + self.loadingView = nil; | |
| 32 | + [self setNeedsLayout]; | |
| 33 | +} | |
| 34 | +#pragma mark - 重写父类的方法 | |
| 35 | +- (void)prepare | |
| 36 | +{ | |
| 37 | + [super prepare]; | |
| 38 | + | |
| 39 | + self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; | |
| 40 | +} | |
| 41 | + | |
| 42 | +- (void)placeSubviews | |
| 43 | +{ | |
| 44 | + [super placeSubviews]; | |
| 45 | + | |
| 46 | + if (self.loadingView.constraints.count) return; | |
| 47 | + | |
| 48 | + // 圈圈 | |
| 49 | + CGFloat loadingCenterX = self.mj_w * 0.5; | |
| 50 | + if (!self.isRefreshingTitleHidden) { | |
| 51 | + loadingCenterX -= self.stateLabel.mj_textWith * 0.5 + self.labelLeftInset; | |
| 52 | + } | |
| 53 | + CGFloat loadingCenterY = self.mj_h * 0.5; | |
| 54 | + self.loadingView.center = CGPointMake(loadingCenterX, loadingCenterY); | |
| 55 | +} | |
| 56 | + | |
| 57 | +- (void)setState:(MJRefreshState)state | |
| 58 | +{ | |
| 59 | + MJRefreshCheckState | |
| 60 | + | |
| 61 | + // 根据状态做事情 | |
| 62 | + if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { | |
| 63 | + [self.loadingView stopAnimating]; | |
| 64 | + } else if (state == MJRefreshStateRefreshing) { | |
| 65 | + [self.loadingView startAnimating]; | |
| 66 | + } | |
| 67 | +} | |
| 68 | + | |
| 69 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoStateFooter.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/6/13. | |
| 6 | +// Copyright © 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshAutoFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoStateFooter : MJRefreshAutoFooter | |
| 12 | +/** 文字距离圈圈、箭头的距离 */ | |
| 13 | +@property (assign, nonatomic) CGFloat labelLeftInset; | |
| 14 | +/** 显示刷新状态的label */ | |
| 15 | +@property (weak, nonatomic, readonly) UILabel *stateLabel; | |
| 16 | + | |
| 17 | +/** 设置state状态下的文字 */ | |
| 18 | +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state; | |
| 19 | + | |
| 20 | +/** 隐藏刷新状态的文字 */ | |
| 21 | +@property (assign, nonatomic, getter=isRefreshingTitleHidden) BOOL refreshingTitleHidden; | |
| 22 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshAutoStateFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/6/13. | |
| 6 | +// Copyright © 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshAutoStateFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshAutoStateFooter() | |
| 12 | +{ | |
| 13 | + /** 显示刷新状态的label */ | |
| 14 | + __unsafe_unretained UILabel *_stateLabel; | |
| 15 | +} | |
| 16 | +/** 所有状态对应的文字 */ | |
| 17 | +@property (strong, nonatomic) NSMutableDictionary *stateTitles; | |
| 18 | +@end | |
| 19 | + | |
| 20 | +@implementation MJRefreshAutoStateFooter | |
| 21 | +#pragma mark - 懒加载 | |
| 22 | +- (NSMutableDictionary *)stateTitles | |
| 23 | +{ | |
| 24 | + if (!_stateTitles) { | |
| 25 | + self.stateTitles = [NSMutableDictionary dictionary]; | |
| 26 | + } | |
| 27 | + return _stateTitles; | |
| 28 | +} | |
| 29 | + | |
| 30 | +- (UILabel *)stateLabel | |
| 31 | +{ | |
| 32 | + if (!_stateLabel) { | |
| 33 | + [self addSubview:_stateLabel = [UILabel mj_label]]; | |
| 34 | + } | |
| 35 | + return _stateLabel; | |
| 36 | +} | |
| 37 | + | |
| 38 | +#pragma mark - 公共方法 | |
| 39 | +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state | |
| 40 | +{ | |
| 41 | + if (title == nil) return; | |
| 42 | + self.stateTitles[@(state)] = title; | |
| 43 | + self.stateLabel.text = self.stateTitles[@(self.state)]; | |
| 44 | +} | |
| 45 | + | |
| 46 | +#pragma mark - 私有方法 | |
| 47 | +- (void)stateLabelClick | |
| 48 | +{ | |
| 49 | + if (self.state == MJRefreshStateIdle) { | |
| 50 | + [self beginRefreshing]; | |
| 51 | + } | |
| 52 | +} | |
| 53 | + | |
| 54 | +#pragma mark - 重写父类的方法 | |
| 55 | +- (void)prepare | |
| 56 | +{ | |
| 57 | + [super prepare]; | |
| 58 | + | |
| 59 | + // 初始化间距 | |
| 60 | + self.labelLeftInset = MJRefreshLabelLeftInset; | |
| 61 | + | |
| 62 | + // 初始化文字 | |
| 63 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterIdleText] forState:MJRefreshStateIdle]; | |
| 64 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterRefreshingText] forState:MJRefreshStateRefreshing]; | |
| 65 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; | |
| 66 | + | |
| 67 | + // 监听label | |
| 68 | + self.stateLabel.userInteractionEnabled = YES; | |
| 69 | + [self.stateLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stateLabelClick)]]; | |
| 70 | +} | |
| 71 | + | |
| 72 | +- (void)placeSubviews | |
| 73 | +{ | |
| 74 | + [super placeSubviews]; | |
| 75 | + | |
| 76 | + if (self.stateLabel.constraints.count) return; | |
| 77 | + | |
| 78 | + // 状态标签 | |
| 79 | + self.stateLabel.frame = self.bounds; | |
| 80 | +} | |
| 81 | + | |
| 82 | +- (void)setState:(MJRefreshState)state | |
| 83 | +{ | |
| 84 | + MJRefreshCheckState | |
| 85 | + | |
| 86 | + if (self.isRefreshingTitleHidden && state == MJRefreshStateRefreshing) { | |
| 87 | + self.stateLabel.text = nil; | |
| 88 | + } else { | |
| 89 | + self.stateLabel.text = self.stateTitles[@(state)]; | |
| 90 | + } | |
| 91 | +} | |
| 92 | +@end | |
| 0 | 93 | \ No newline at end of file | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshBackGifFooter.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshBackStateFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshBackGifFooter : MJRefreshBackStateFooter | |
| 12 | +@property (weak, nonatomic, readonly) UIImageView *gifView; | |
| 13 | + | |
| 14 | +/** 设置state状态下的动画图片images 动画持续时间duration*/ | |
| 15 | +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; | |
| 16 | +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; | |
| 17 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshBackGifFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshBackGifFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshBackGifFooter() | |
| 12 | +{ | |
| 13 | + __unsafe_unretained UIImageView *_gifView; | |
| 14 | +} | |
| 15 | +/** 所有状态对应的动画图片 */ | |
| 16 | +@property (strong, nonatomic) NSMutableDictionary *stateImages; | |
| 17 | +/** 所有状态对应的动画时间 */ | |
| 18 | +@property (strong, nonatomic) NSMutableDictionary *stateDurations; | |
| 19 | +@end | |
| 20 | + | |
| 21 | +@implementation MJRefreshBackGifFooter | |
| 22 | +#pragma mark - 懒加载 | |
| 23 | +- (UIImageView *)gifView | |
| 24 | +{ | |
| 25 | + if (!_gifView) { | |
| 26 | + UIImageView *gifView = [[UIImageView alloc] init]; | |
| 27 | + [self addSubview:_gifView = gifView]; | |
| 28 | + } | |
| 29 | + return _gifView; | |
| 30 | +} | |
| 31 | + | |
| 32 | +- (NSMutableDictionary *)stateImages | |
| 33 | +{ | |
| 34 | + if (!_stateImages) { | |
| 35 | + self.stateImages = [NSMutableDictionary dictionary]; | |
| 36 | + } | |
| 37 | + return _stateImages; | |
| 38 | +} | |
| 39 | + | |
| 40 | +- (NSMutableDictionary *)stateDurations | |
| 41 | +{ | |
| 42 | + if (!_stateDurations) { | |
| 43 | + self.stateDurations = [NSMutableDictionary dictionary]; | |
| 44 | + } | |
| 45 | + return _stateDurations; | |
| 46 | +} | |
| 47 | + | |
| 48 | +#pragma mark - 公共方法 | |
| 49 | +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state | |
| 50 | +{ | |
| 51 | + if (images == nil) return; | |
| 52 | + | |
| 53 | + self.stateImages[@(state)] = images; | |
| 54 | + self.stateDurations[@(state)] = @(duration); | |
| 55 | + | |
| 56 | + /* 根据图片设置控件的高度 */ | |
| 57 | + UIImage *image = [images firstObject]; | |
| 58 | + if (image.size.height > self.mj_h) { | |
| 59 | + self.mj_h = image.size.height; | |
| 60 | + } | |
| 61 | +} | |
| 62 | + | |
| 63 | +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state | |
| 64 | +{ | |
| 65 | + [self setImages:images duration:images.count * 0.1 forState:state]; | |
| 66 | +} | |
| 67 | + | |
| 68 | +#pragma mark - 实现父类的方法 | |
| 69 | +- (void)prepare | |
| 70 | +{ | |
| 71 | + [super prepare]; | |
| 72 | + | |
| 73 | + // 初始化间距 | |
| 74 | + self.labelLeftInset = 20; | |
| 75 | +} | |
| 76 | + | |
| 77 | +- (void)setPullingPercent:(CGFloat)pullingPercent | |
| 78 | +{ | |
| 79 | + [super setPullingPercent:pullingPercent]; | |
| 80 | + NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; | |
| 81 | + if (self.state != MJRefreshStateIdle || images.count == 0) return; | |
| 82 | + [self.gifView stopAnimating]; | |
| 83 | + NSUInteger index = images.count * pullingPercent; | |
| 84 | + if (index >= images.count) index = images.count - 1; | |
| 85 | + self.gifView.image = images[index]; | |
| 86 | +} | |
| 87 | + | |
| 88 | +- (void)placeSubviews | |
| 89 | +{ | |
| 90 | + [super placeSubviews]; | |
| 91 | + | |
| 92 | + if (self.gifView.constraints.count) return; | |
| 93 | + | |
| 94 | + self.gifView.frame = self.bounds; | |
| 95 | + if (self.stateLabel.hidden) { | |
| 96 | + self.gifView.contentMode = UIViewContentModeCenter; | |
| 97 | + } else { | |
| 98 | + self.gifView.contentMode = UIViewContentModeRight; | |
| 99 | + self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWith * 0.5; | |
| 100 | + } | |
| 101 | +} | |
| 102 | + | |
| 103 | +- (void)setState:(MJRefreshState)state | |
| 104 | +{ | |
| 105 | + MJRefreshCheckState | |
| 106 | + | |
| 107 | + // 根据状态做事情 | |
| 108 | + if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { | |
| 109 | + NSArray *images = self.stateImages[@(state)]; | |
| 110 | + if (images.count == 0) return; | |
| 111 | + | |
| 112 | + self.gifView.hidden = NO; | |
| 113 | + [self.gifView stopAnimating]; | |
| 114 | + if (images.count == 1) { // 单张图片 | |
| 115 | + self.gifView.image = [images lastObject]; | |
| 116 | + } else { // 多张图片 | |
| 117 | + self.gifView.animationImages = images; | |
| 118 | + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; | |
| 119 | + [self.gifView startAnimating]; | |
| 120 | + } | |
| 121 | + } else if (state == MJRefreshStateIdle) { | |
| 122 | + self.gifView.hidden = NO; | |
| 123 | + } else if (state == MJRefreshStateNoMoreData) { | |
| 124 | + self.gifView.hidden = YES; | |
| 125 | + } | |
| 126 | +} | |
| 127 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshBackNormalFooter.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshBackStateFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshBackNormalFooter : MJRefreshBackStateFooter | |
| 12 | +@property (weak, nonatomic, readonly) UIImageView *arrowView; | |
| 13 | +/** 菊花的样式 */ | |
| 14 | +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; | |
| 15 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshBackNormalFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshBackNormalFooter.h" | |
| 10 | +#import "NSBundle+MJRefresh.h" | |
| 11 | + | |
| 12 | +@interface MJRefreshBackNormalFooter() | |
| 13 | +{ | |
| 14 | + __unsafe_unretained UIImageView *_arrowView; | |
| 15 | +} | |
| 16 | +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; | |
| 17 | +@end | |
| 18 | + | |
| 19 | +@implementation MJRefreshBackNormalFooter | |
| 20 | +#pragma mark - 懒加载子控件 | |
| 21 | +- (UIImageView *)arrowView | |
| 22 | +{ | |
| 23 | + if (!_arrowView) { | |
| 24 | + UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; | |
| 25 | + [self addSubview:_arrowView = arrowView]; | |
| 26 | + } | |
| 27 | + return _arrowView; | |
| 28 | +} | |
| 29 | + | |
| 30 | + | |
| 31 | +- (UIActivityIndicatorView *)loadingView | |
| 32 | +{ | |
| 33 | + if (!_loadingView) { | |
| 34 | + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; | |
| 35 | + loadingView.hidesWhenStopped = YES; | |
| 36 | + [self addSubview:_loadingView = loadingView]; | |
| 37 | + } | |
| 38 | + return _loadingView; | |
| 39 | +} | |
| 40 | + | |
| 41 | +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle | |
| 42 | +{ | |
| 43 | + _activityIndicatorViewStyle = activityIndicatorViewStyle; | |
| 44 | + | |
| 45 | + self.loadingView = nil; | |
| 46 | + [self setNeedsLayout]; | |
| 47 | +} | |
| 48 | +#pragma mark - 重写父类的方法 | |
| 49 | +- (void)prepare | |
| 50 | +{ | |
| 51 | + [super prepare]; | |
| 52 | + | |
| 53 | + self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; | |
| 54 | +} | |
| 55 | + | |
| 56 | +- (void)placeSubviews | |
| 57 | +{ | |
| 58 | + [super placeSubviews]; | |
| 59 | + | |
| 60 | + // 箭头的中心点 | |
| 61 | + CGFloat arrowCenterX = self.mj_w * 0.5; | |
| 62 | + if (!self.stateLabel.hidden) { | |
| 63 | + arrowCenterX -= self.labelLeftInset + self.stateLabel.mj_textWith * 0.5; | |
| 64 | + } | |
| 65 | + CGFloat arrowCenterY = self.mj_h * 0.5; | |
| 66 | + CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); | |
| 67 | + | |
| 68 | + // 箭头 | |
| 69 | + if (self.arrowView.constraints.count == 0) { | |
| 70 | + self.arrowView.mj_size = self.arrowView.image.size; | |
| 71 | + self.arrowView.center = arrowCenter; | |
| 72 | + } | |
| 73 | + | |
| 74 | + // 圈圈 | |
| 75 | + if (self.loadingView.constraints.count == 0) { | |
| 76 | + self.loadingView.center = arrowCenter; | |
| 77 | + } | |
| 78 | + | |
| 79 | + self.arrowView.tintColor = self.stateLabel.textColor; | |
| 80 | +} | |
| 81 | + | |
| 82 | +- (void)setState:(MJRefreshState)state | |
| 83 | +{ | |
| 84 | + MJRefreshCheckState | |
| 85 | + | |
| 86 | + // 根据状态做事情 | |
| 87 | + if (state == MJRefreshStateIdle) { | |
| 88 | + if (oldState == MJRefreshStateRefreshing) { | |
| 89 | + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); | |
| 90 | + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ | |
| 91 | + self.loadingView.alpha = 0.0; | |
| 92 | + } completion:^(BOOL finished) { | |
| 93 | + // 防止动画结束后,状态已经不是MJRefreshStateIdle | |
| 94 | + if (state != MJRefreshStateIdle) return; | |
| 95 | + | |
| 96 | + self.loadingView.alpha = 1.0; | |
| 97 | + [self.loadingView stopAnimating]; | |
| 98 | + | |
| 99 | + self.arrowView.hidden = NO; | |
| 100 | + }]; | |
| 101 | + } else { | |
| 102 | + self.arrowView.hidden = NO; | |
| 103 | + [self.loadingView stopAnimating]; | |
| 104 | + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ | |
| 105 | + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); | |
| 106 | + }]; | |
| 107 | + } | |
| 108 | + } else if (state == MJRefreshStatePulling) { | |
| 109 | + self.arrowView.hidden = NO; | |
| 110 | + [self.loadingView stopAnimating]; | |
| 111 | + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ | |
| 112 | + self.arrowView.transform = CGAffineTransformIdentity; | |
| 113 | + }]; | |
| 114 | + } else if (state == MJRefreshStateRefreshing) { | |
| 115 | + self.arrowView.hidden = YES; | |
| 116 | + [self.loadingView startAnimating]; | |
| 117 | + } else if (state == MJRefreshStateNoMoreData) { | |
| 118 | + self.arrowView.hidden = YES; | |
| 119 | + [self.loadingView stopAnimating]; | |
| 120 | + } | |
| 121 | +} | |
| 122 | + | |
| 123 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshBackStateFooter.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/6/13. | |
| 6 | +// Copyright © 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshBackFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshBackStateFooter : MJRefreshBackFooter | |
| 12 | +/** 文字距离圈圈、箭头的距离 */ | |
| 13 | +@property (assign, nonatomic) CGFloat labelLeftInset; | |
| 14 | +/** 显示刷新状态的label */ | |
| 15 | +@property (weak, nonatomic, readonly) UILabel *stateLabel; | |
| 16 | +/** 设置state状态下的文字 */ | |
| 17 | +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state; | |
| 18 | + | |
| 19 | +/** 获取state状态下的title */ | |
| 20 | +- (NSString *)titleForState:(MJRefreshState)state; | |
| 21 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshBackStateFooter.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/6/13. | |
| 6 | +// Copyright © 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshBackStateFooter.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshBackStateFooter() | |
| 12 | +{ | |
| 13 | + /** 显示刷新状态的label */ | |
| 14 | + __unsafe_unretained UILabel *_stateLabel; | |
| 15 | +} | |
| 16 | +/** 所有状态对应的文字 */ | |
| 17 | +@property (strong, nonatomic) NSMutableDictionary *stateTitles; | |
| 18 | +@end | |
| 19 | + | |
| 20 | +@implementation MJRefreshBackStateFooter | |
| 21 | +#pragma mark - 懒加载 | |
| 22 | +- (NSMutableDictionary *)stateTitles | |
| 23 | +{ | |
| 24 | + if (!_stateTitles) { | |
| 25 | + self.stateTitles = [NSMutableDictionary dictionary]; | |
| 26 | + } | |
| 27 | + return _stateTitles; | |
| 28 | +} | |
| 29 | + | |
| 30 | +- (UILabel *)stateLabel | |
| 31 | +{ | |
| 32 | + if (!_stateLabel) { | |
| 33 | + [self addSubview:_stateLabel = [UILabel mj_label]]; | |
| 34 | + } | |
| 35 | + return _stateLabel; | |
| 36 | +} | |
| 37 | + | |
| 38 | +#pragma mark - 公共方法 | |
| 39 | +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state | |
| 40 | +{ | |
| 41 | + if (title == nil) return; | |
| 42 | + self.stateTitles[@(state)] = title; | |
| 43 | + self.stateLabel.text = self.stateTitles[@(self.state)]; | |
| 44 | +} | |
| 45 | + | |
| 46 | +- (NSString *)titleForState:(MJRefreshState)state { | |
| 47 | + return self.stateTitles[@(state)]; | |
| 48 | +} | |
| 49 | + | |
| 50 | +#pragma mark - 重写父类的方法 | |
| 51 | +- (void)prepare | |
| 52 | +{ | |
| 53 | + [super prepare]; | |
| 54 | + | |
| 55 | + // 初始化间距 | |
| 56 | + self.labelLeftInset = MJRefreshLabelLeftInset; | |
| 57 | + | |
| 58 | + // 初始化文字 | |
| 59 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterIdleText] forState:MJRefreshStateIdle]; | |
| 60 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterPullingText] forState:MJRefreshStatePulling]; | |
| 61 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterRefreshingText] forState:MJRefreshStateRefreshing]; | |
| 62 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; | |
| 63 | +} | |
| 64 | + | |
| 65 | +- (void)placeSubviews | |
| 66 | +{ | |
| 67 | + [super placeSubviews]; | |
| 68 | + | |
| 69 | + if (self.stateLabel.constraints.count) return; | |
| 70 | + | |
| 71 | + // 状态标签 | |
| 72 | + self.stateLabel.frame = self.bounds; | |
| 73 | +} | |
| 74 | + | |
| 75 | +- (void)setState:(MJRefreshState)state | |
| 76 | +{ | |
| 77 | + MJRefreshCheckState | |
| 78 | + | |
| 79 | + // 设置状态文字 | |
| 80 | + self.stateLabel.text = self.stateTitles[@(state)]; | |
| 81 | +} | |
| 82 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshGifHeader.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshStateHeader.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshGifHeader : MJRefreshStateHeader | |
| 12 | +@property (weak, nonatomic, readonly) UIImageView *gifView; | |
| 13 | + | |
| 14 | +/** 设置state状态下的动画图片images 动画持续时间duration*/ | |
| 15 | +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; | |
| 16 | +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; | |
| 17 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshGifHeader.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshGifHeader.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshGifHeader() | |
| 12 | +{ | |
| 13 | + __unsafe_unretained UIImageView *_gifView; | |
| 14 | +} | |
| 15 | +/** 所有状态对应的动画图片 */ | |
| 16 | +@property (strong, nonatomic) NSMutableDictionary *stateImages; | |
| 17 | +/** 所有状态对应的动画时间 */ | |
| 18 | +@property (strong, nonatomic) NSMutableDictionary *stateDurations; | |
| 19 | +@end | |
| 20 | + | |
| 21 | +@implementation MJRefreshGifHeader | |
| 22 | +#pragma mark - 懒加载 | |
| 23 | +- (UIImageView *)gifView | |
| 24 | +{ | |
| 25 | + if (!_gifView) { | |
| 26 | + UIImageView *gifView = [[UIImageView alloc] init]; | |
| 27 | + [self addSubview:_gifView = gifView]; | |
| 28 | + } | |
| 29 | + return _gifView; | |
| 30 | +} | |
| 31 | + | |
| 32 | +- (NSMutableDictionary *)stateImages | |
| 33 | +{ | |
| 34 | + if (!_stateImages) { | |
| 35 | + self.stateImages = [NSMutableDictionary dictionary]; | |
| 36 | + } | |
| 37 | + return _stateImages; | |
| 38 | +} | |
| 39 | + | |
| 40 | +- (NSMutableDictionary *)stateDurations | |
| 41 | +{ | |
| 42 | + if (!_stateDurations) { | |
| 43 | + self.stateDurations = [NSMutableDictionary dictionary]; | |
| 44 | + } | |
| 45 | + return _stateDurations; | |
| 46 | +} | |
| 47 | + | |
| 48 | +#pragma mark - 公共方法 | |
| 49 | +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state | |
| 50 | +{ | |
| 51 | + if (images == nil) return; | |
| 52 | + | |
| 53 | + self.stateImages[@(state)] = images; | |
| 54 | + self.stateDurations[@(state)] = @(duration); | |
| 55 | + | |
| 56 | + /* 根据图片设置控件的高度 */ | |
| 57 | + UIImage *image = [images firstObject]; | |
| 58 | + if (image.size.height > self.mj_h) { | |
| 59 | + self.mj_h = image.size.height; | |
| 60 | + } | |
| 61 | +} | |
| 62 | + | |
| 63 | +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state | |
| 64 | +{ | |
| 65 | + [self setImages:images duration:images.count * 0.1 forState:state]; | |
| 66 | +} | |
| 67 | + | |
| 68 | +#pragma mark - 实现父类的方法 | |
| 69 | +- (void)prepare | |
| 70 | +{ | |
| 71 | + [super prepare]; | |
| 72 | + | |
| 73 | + // 初始化间距 | |
| 74 | + self.labelLeftInset = 20; | |
| 75 | +} | |
| 76 | + | |
| 77 | +- (void)setPullingPercent:(CGFloat)pullingPercent | |
| 78 | +{ | |
| 79 | + [super setPullingPercent:pullingPercent]; | |
| 80 | + NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; | |
| 81 | + if (self.state != MJRefreshStateIdle || images.count == 0) return; | |
| 82 | + // 停止动画 | |
| 83 | + [self.gifView stopAnimating]; | |
| 84 | + // 设置当前需要显示的图片 | |
| 85 | + NSUInteger index = images.count * pullingPercent; | |
| 86 | + if (index >= images.count) index = images.count - 1; | |
| 87 | + self.gifView.image = images[index]; | |
| 88 | +} | |
| 89 | + | |
| 90 | +- (void)placeSubviews | |
| 91 | +{ | |
| 92 | + [super placeSubviews]; | |
| 93 | + | |
| 94 | + if (self.gifView.constraints.count) return; | |
| 95 | + | |
| 96 | + self.gifView.frame = self.bounds; | |
| 97 | + if (self.stateLabel.hidden && self.lastUpdatedTimeLabel.hidden) { | |
| 98 | + self.gifView.contentMode = UIViewContentModeCenter; | |
| 99 | + } else { | |
| 100 | + self.gifView.contentMode = UIViewContentModeRight; | |
| 101 | + | |
| 102 | + CGFloat stateWidth = self.stateLabel.mj_textWith; | |
| 103 | + CGFloat timeWidth = 0.0; | |
| 104 | + if (!self.lastUpdatedTimeLabel.hidden) { | |
| 105 | + timeWidth = self.lastUpdatedTimeLabel.mj_textWith; | |
| 106 | + } | |
| 107 | + CGFloat textWidth = MAX(stateWidth, timeWidth); | |
| 108 | + self.gifView.mj_w = self.mj_w * 0.5 - textWidth * 0.5 - self.labelLeftInset; | |
| 109 | + } | |
| 110 | +} | |
| 111 | + | |
| 112 | +- (void)setState:(MJRefreshState)state | |
| 113 | +{ | |
| 114 | + MJRefreshCheckState | |
| 115 | + | |
| 116 | + // 根据状态做事情 | |
| 117 | + if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { | |
| 118 | + NSArray *images = self.stateImages[@(state)]; | |
| 119 | + if (images.count == 0) return; | |
| 120 | + | |
| 121 | + [self.gifView stopAnimating]; | |
| 122 | + if (images.count == 1) { // 单张图片 | |
| 123 | + self.gifView.image = [images lastObject]; | |
| 124 | + } else { // 多张图片 | |
| 125 | + self.gifView.animationImages = images; | |
| 126 | + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; | |
| 127 | + [self.gifView startAnimating]; | |
| 128 | + } | |
| 129 | + } else if (state == MJRefreshStateIdle) { | |
| 130 | + [self.gifView stopAnimating]; | |
| 131 | + } | |
| 132 | +} | |
| 133 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshNormalHeader.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshStateHeader.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshNormalHeader : MJRefreshStateHeader | |
| 12 | +@property (weak, nonatomic, readonly) UIImageView *arrowView; | |
| 13 | +/** 菊花的样式 */ | |
| 14 | +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; | |
| 15 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshNormalHeader.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshNormalHeader.h" | |
| 10 | +#import "NSBundle+MJRefresh.h" | |
| 11 | + | |
| 12 | +@interface MJRefreshNormalHeader() | |
| 13 | +{ | |
| 14 | + __unsafe_unretained UIImageView *_arrowView; | |
| 15 | +} | |
| 16 | +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; | |
| 17 | +@end | |
| 18 | + | |
| 19 | +@implementation MJRefreshNormalHeader | |
| 20 | +#pragma mark - 懒加载子控件 | |
| 21 | +- (UIImageView *)arrowView | |
| 22 | +{ | |
| 23 | + if (!_arrowView) { | |
| 24 | + UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; | |
| 25 | + [self addSubview:_arrowView = arrowView]; | |
| 26 | + } | |
| 27 | + return _arrowView; | |
| 28 | +} | |
| 29 | + | |
| 30 | +- (UIActivityIndicatorView *)loadingView | |
| 31 | +{ | |
| 32 | + if (!_loadingView) { | |
| 33 | + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; | |
| 34 | + loadingView.hidesWhenStopped = YES; | |
| 35 | + [self addSubview:_loadingView = loadingView]; | |
| 36 | + } | |
| 37 | + return _loadingView; | |
| 38 | +} | |
| 39 | + | |
| 40 | +#pragma mark - 公共方法 | |
| 41 | +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle | |
| 42 | +{ | |
| 43 | + _activityIndicatorViewStyle = activityIndicatorViewStyle; | |
| 44 | + | |
| 45 | + self.loadingView = nil; | |
| 46 | + [self setNeedsLayout]; | |
| 47 | +} | |
| 48 | + | |
| 49 | +#pragma mark - 重写父类的方法 | |
| 50 | +- (void)prepare | |
| 51 | +{ | |
| 52 | + [super prepare]; | |
| 53 | + | |
| 54 | + self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; | |
| 55 | +} | |
| 56 | + | |
| 57 | +- (void)placeSubviews | |
| 58 | +{ | |
| 59 | + [super placeSubviews]; | |
| 60 | + | |
| 61 | + // 箭头的中心点 | |
| 62 | + CGFloat arrowCenterX = self.mj_w * 0.5; | |
| 63 | + if (!self.stateLabel.hidden) { | |
| 64 | + CGFloat stateWidth = self.stateLabel.mj_textWith; | |
| 65 | + CGFloat timeWidth = 0.0; | |
| 66 | + if (!self.lastUpdatedTimeLabel.hidden) { | |
| 67 | + timeWidth = self.lastUpdatedTimeLabel.mj_textWith; | |
| 68 | + } | |
| 69 | + CGFloat textWidth = MAX(stateWidth, timeWidth); | |
| 70 | + arrowCenterX -= textWidth / 2 + self.labelLeftInset; | |
| 71 | + } | |
| 72 | + CGFloat arrowCenterY = self.mj_h * 0.5; | |
| 73 | + CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); | |
| 74 | + | |
| 75 | + // 箭头 | |
| 76 | + if (self.arrowView.constraints.count == 0) { | |
| 77 | + self.arrowView.mj_size = self.arrowView.image.size; | |
| 78 | + self.arrowView.center = arrowCenter; | |
| 79 | + } | |
| 80 | + | |
| 81 | + // 圈圈 | |
| 82 | + if (self.loadingView.constraints.count == 0) { | |
| 83 | + self.loadingView.center = arrowCenter; | |
| 84 | + } | |
| 85 | + | |
| 86 | + self.arrowView.tintColor = self.stateLabel.textColor; | |
| 87 | +} | |
| 88 | + | |
| 89 | +- (void)setState:(MJRefreshState)state | |
| 90 | +{ | |
| 91 | + MJRefreshCheckState | |
| 92 | + | |
| 93 | + // 根据状态做事情 | |
| 94 | + if (state == MJRefreshStateIdle) { | |
| 95 | + if (oldState == MJRefreshStateRefreshing) { | |
| 96 | + self.arrowView.transform = CGAffineTransformIdentity; | |
| 97 | + | |
| 98 | + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ | |
| 99 | + self.loadingView.alpha = 0.0; | |
| 100 | + } completion:^(BOOL finished) { | |
| 101 | + // 如果执行完动画发现不是idle状态,就直接返回,进入其他状态 | |
| 102 | + if (self.state != MJRefreshStateIdle) return; | |
| 103 | + | |
| 104 | + self.loadingView.alpha = 1.0; | |
| 105 | + [self.loadingView stopAnimating]; | |
| 106 | + self.arrowView.hidden = NO; | |
| 107 | + }]; | |
| 108 | + } else { | |
| 109 | + [self.loadingView stopAnimating]; | |
| 110 | + self.arrowView.hidden = NO; | |
| 111 | + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ | |
| 112 | + self.arrowView.transform = CGAffineTransformIdentity; | |
| 113 | + }]; | |
| 114 | + } | |
| 115 | + } else if (state == MJRefreshStatePulling) { | |
| 116 | + [self.loadingView stopAnimating]; | |
| 117 | + self.arrowView.hidden = NO; | |
| 118 | + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ | |
| 119 | + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); | |
| 120 | + }]; | |
| 121 | + } else if (state == MJRefreshStateRefreshing) { | |
| 122 | + self.loadingView.alpha = 1.0; // 防止refreshing -> idle的动画完毕动作没有被执行 | |
| 123 | + [self.loadingView startAnimating]; | |
| 124 | + self.arrowView.hidden = YES; | |
| 125 | + } | |
| 126 | +} | |
| 127 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshStateHeader.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshHeader.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshStateHeader : MJRefreshHeader | |
| 12 | +#pragma mark - 刷新时间相关 | |
| 13 | +/** 利用这个block来决定显示的更新时间文字 */ | |
| 14 | +@property (copy, nonatomic) NSString *(^lastUpdatedTimeText)(NSDate *lastUpdatedTime); | |
| 15 | +/** 显示上一次刷新时间的label */ | |
| 16 | +@property (weak, nonatomic, readonly) UILabel *lastUpdatedTimeLabel; | |
| 17 | + | |
| 18 | +#pragma mark - 状态相关 | |
| 19 | +/** 文字距离圈圈、箭头的距离 */ | |
| 20 | +@property (assign, nonatomic) CGFloat labelLeftInset; | |
| 21 | +/** 显示刷新状态的label */ | |
| 22 | +@property (weak, nonatomic, readonly) UILabel *stateLabel; | |
| 23 | +/** 设置state状态下的文字 */ | |
| 24 | +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state; | |
| 25 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m
0 → 100644
| 1 | +// | |
| 2 | +// MJRefreshStateHeader.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 15/4/24. | |
| 6 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "MJRefreshStateHeader.h" | |
| 10 | + | |
| 11 | +@interface MJRefreshStateHeader() | |
| 12 | +{ | |
| 13 | + /** 显示上一次刷新时间的label */ | |
| 14 | + __unsafe_unretained UILabel *_lastUpdatedTimeLabel; | |
| 15 | + /** 显示刷新状态的label */ | |
| 16 | + __unsafe_unretained UILabel *_stateLabel; | |
| 17 | +} | |
| 18 | +/** 所有状态对应的文字 */ | |
| 19 | +@property (strong, nonatomic) NSMutableDictionary *stateTitles; | |
| 20 | +@end | |
| 21 | + | |
| 22 | +@implementation MJRefreshStateHeader | |
| 23 | +#pragma mark - 懒加载 | |
| 24 | +- (NSMutableDictionary *)stateTitles | |
| 25 | +{ | |
| 26 | + if (!_stateTitles) { | |
| 27 | + self.stateTitles = [NSMutableDictionary dictionary]; | |
| 28 | + } | |
| 29 | + return _stateTitles; | |
| 30 | +} | |
| 31 | + | |
| 32 | +- (UILabel *)stateLabel | |
| 33 | +{ | |
| 34 | + if (!_stateLabel) { | |
| 35 | + [self addSubview:_stateLabel = [UILabel mj_label]]; | |
| 36 | + } | |
| 37 | + return _stateLabel; | |
| 38 | +} | |
| 39 | + | |
| 40 | +- (UILabel *)lastUpdatedTimeLabel | |
| 41 | +{ | |
| 42 | + if (!_lastUpdatedTimeLabel) { | |
| 43 | + [self addSubview:_lastUpdatedTimeLabel = [UILabel mj_label]]; | |
| 44 | + } | |
| 45 | + return _lastUpdatedTimeLabel; | |
| 46 | +} | |
| 47 | + | |
| 48 | +#pragma mark - 公共方法 | |
| 49 | +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state | |
| 50 | +{ | |
| 51 | + if (title == nil) return; | |
| 52 | + self.stateTitles[@(state)] = title; | |
| 53 | + self.stateLabel.text = self.stateTitles[@(self.state)]; | |
| 54 | +} | |
| 55 | + | |
| 56 | +#pragma mark - 日历获取在9.x之后的系统使用currentCalendar会出异常。在8.0之后使用系统新API。 | |
| 57 | +- (NSCalendar *)currentCalendar { | |
| 58 | + if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) { | |
| 59 | + return [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; | |
| 60 | + } | |
| 61 | + return [NSCalendar currentCalendar]; | |
| 62 | +} | |
| 63 | + | |
| 64 | +#pragma mark key的处理 | |
| 65 | +- (void)setLastUpdatedTimeKey:(NSString *)lastUpdatedTimeKey | |
| 66 | +{ | |
| 67 | + [super setLastUpdatedTimeKey:lastUpdatedTimeKey]; | |
| 68 | + | |
| 69 | + // 如果label隐藏了,就不用再处理 | |
| 70 | + if (self.lastUpdatedTimeLabel.hidden) return; | |
| 71 | + | |
| 72 | + NSDate *lastUpdatedTime = [[NSUserDefaults standardUserDefaults] objectForKey:lastUpdatedTimeKey]; | |
| 73 | + | |
| 74 | + // 如果有block | |
| 75 | + if (self.lastUpdatedTimeText) { | |
| 76 | + self.lastUpdatedTimeLabel.text = self.lastUpdatedTimeText(lastUpdatedTime); | |
| 77 | + return; | |
| 78 | + } | |
| 79 | + | |
| 80 | + if (lastUpdatedTime) { | |
| 81 | + // 1.获得年月日 | |
| 82 | + NSCalendar *calendar = [self currentCalendar]; | |
| 83 | + NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay |NSCalendarUnitHour |NSCalendarUnitMinute; | |
| 84 | + NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:lastUpdatedTime]; | |
| 85 | + NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]]; | |
| 86 | + | |
| 87 | + // 2.格式化日期 | |
| 88 | + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; | |
| 89 | + BOOL isToday = NO; | |
| 90 | + if ([cmp1 day] == [cmp2 day]) { // 今天 | |
| 91 | + formatter.dateFormat = @" HH:mm"; | |
| 92 | + isToday = YES; | |
| 93 | + } else if ([cmp1 year] == [cmp2 year]) { // 今年 | |
| 94 | + formatter.dateFormat = @"MM-dd HH:mm"; | |
| 95 | + } else { | |
| 96 | + formatter.dateFormat = @"yyyy-MM-dd HH:mm"; | |
| 97 | + } | |
| 98 | + NSString *time = [formatter stringFromDate:lastUpdatedTime]; | |
| 99 | + | |
| 100 | + // 3.显示日期 | |
| 101 | + self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@%@", | |
| 102 | + [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], | |
| 103 | + isToday ? [NSBundle mj_localizedStringForKey:MJRefreshHeaderDateTodayText] : @"", | |
| 104 | + time]; | |
| 105 | + } else { | |
| 106 | + self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@", | |
| 107 | + [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], | |
| 108 | + [NSBundle mj_localizedStringForKey:MJRefreshHeaderNoneLastDateText]]; | |
| 109 | + } | |
| 110 | +} | |
| 111 | + | |
| 112 | +#pragma mark - 覆盖父类的方法 | |
| 113 | +- (void)prepare | |
| 114 | +{ | |
| 115 | + [super prepare]; | |
| 116 | + | |
| 117 | + // 初始化间距 | |
| 118 | + self.labelLeftInset = MJRefreshLabelLeftInset; | |
| 119 | + | |
| 120 | + // 初始化文字 | |
| 121 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderIdleText] forState:MJRefreshStateIdle]; | |
| 122 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderPullingText] forState:MJRefreshStatePulling]; | |
| 123 | + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderRefreshingText] forState:MJRefreshStateRefreshing]; | |
| 124 | +} | |
| 125 | + | |
| 126 | +- (void)placeSubviews | |
| 127 | +{ | |
| 128 | + [super placeSubviews]; | |
| 129 | + | |
| 130 | + if (self.stateLabel.hidden) return; | |
| 131 | + | |
| 132 | + BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; | |
| 133 | + | |
| 134 | + if (self.lastUpdatedTimeLabel.hidden) { | |
| 135 | + // 状态 | |
| 136 | + if (noConstrainsOnStatusLabel) self.stateLabel.frame = self.bounds; | |
| 137 | + } else { | |
| 138 | + CGFloat stateLabelH = self.mj_h * 0.5; | |
| 139 | + // 状态 | |
| 140 | + if (noConstrainsOnStatusLabel) { | |
| 141 | + self.stateLabel.mj_x = 0; | |
| 142 | + self.stateLabel.mj_y = 0; | |
| 143 | + self.stateLabel.mj_w = self.mj_w; | |
| 144 | + self.stateLabel.mj_h = stateLabelH; | |
| 145 | + } | |
| 146 | + | |
| 147 | + // 更新时间 | |
| 148 | + if (self.lastUpdatedTimeLabel.constraints.count == 0) { | |
| 149 | + self.lastUpdatedTimeLabel.mj_x = 0; | |
| 150 | + self.lastUpdatedTimeLabel.mj_y = stateLabelH; | |
| 151 | + self.lastUpdatedTimeLabel.mj_w = self.mj_w; | |
| 152 | + self.lastUpdatedTimeLabel.mj_h = self.mj_h - self.lastUpdatedTimeLabel.mj_y; | |
| 153 | + } | |
| 154 | + } | |
| 155 | +} | |
| 156 | + | |
| 157 | +- (void)setState:(MJRefreshState)state | |
| 158 | +{ | |
| 159 | + MJRefreshCheckState | |
| 160 | + | |
| 161 | + // 设置状态文字 | |
| 162 | + self.stateLabel.text = self.stateTitles[@(state)]; | |
| 163 | + | |
| 164 | + // 重新设置key(重新显示时间) | |
| 165 | + self.lastUpdatedTimeKey = self.lastUpdatedTimeKey; | |
| 166 | +} | |
| 167 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/arrow@2x.png
0 → 100755
1.01 KB
Example/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings
0 → 100644
| 1 | +"MJRefreshHeaderIdleText" = "Pull down to refresh"; | |
| 2 | +"MJRefreshHeaderPullingText" = "Release to refresh"; | |
| 3 | +"MJRefreshHeaderRefreshingText" = "Loading..."; | |
| 4 | + | |
| 5 | +"MJRefreshAutoFooterIdleText" = "Tap or pull up to load more"; | |
| 6 | +"MJRefreshAutoFooterRefreshingText" = "Loading..."; | |
| 7 | +"MJRefreshAutoFooterNoMoreDataText" = "No more data"; | |
| 8 | + | |
| 9 | +"MJRefreshBackFooterIdleText" = "Pull up to load more"; | |
| 10 | +"MJRefreshBackFooterPullingText" = "Release to load more."; | |
| 11 | +"MJRefreshBackFooterRefreshingText" = "Loading..."; | |
| 12 | +"MJRefreshBackFooterNoMoreDataText" = "No more data"; | |
| 13 | + | |
| 14 | +"MJRefreshHeaderLastTimeText" = "Last updated: "; | |
| 15 | +"MJRefreshHeaderDateTodayText" = "Today"; | |
| 16 | +"MJRefreshHeaderNoneLastDateText" = "No record"; | ... | ... |
Example/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings
0 → 100644
Example/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings
0 → 100644
| 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" = "無記錄"; | ... | ... |
Example/Pods/MJRefresh/MJRefresh/MJRefresh.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | + | |
| 4 | +#import "UIScrollView+MJRefresh.h" | |
| 5 | +#import "UIScrollView+MJExtension.h" | |
| 6 | +#import "UIView+MJExtension.h" | |
| 7 | + | |
| 8 | +#import "MJRefreshNormalHeader.h" | |
| 9 | +#import "MJRefreshGifHeader.h" | |
| 10 | + | |
| 11 | +#import "MJRefreshBackNormalFooter.h" | |
| 12 | +#import "MJRefreshBackGifFooter.h" | |
| 13 | +#import "MJRefreshAutoNormalFooter.h" | |
| 14 | +#import "MJRefreshAutoGifFooter.h" | |
| 0 | 15 | \ No newline at end of file | ... | ... |
Example/Pods/MJRefresh/MJRefresh/MJRefreshConst.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +#import <UIKit/UIKit.h> | |
| 4 | +#import <objc/message.h> | |
| 5 | + | |
| 6 | +// 弱引用 | |
| 7 | +#define MJWeakSelf __weak typeof(self) weakSelf = self; | |
| 8 | + | |
| 9 | +// 日志输出 | |
| 10 | +#ifdef DEBUG | |
| 11 | +#define MJRefreshLog(...) NSLog(__VA_ARGS__) | |
| 12 | +#else | |
| 13 | +#define MJRefreshLog(...) | |
| 14 | +#endif | |
| 15 | + | |
| 16 | +// 过期提醒 | |
| 17 | +#define MJRefreshDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) | |
| 18 | + | |
| 19 | +// 运行时objc_msgSend | |
| 20 | +#define MJRefreshMsgSend(...) ((void (*)(void *, SEL, UIView *))objc_msgSend)(__VA_ARGS__) | |
| 21 | +#define MJRefreshMsgTarget(target) (__bridge void *)(target) | |
| 22 | + | |
| 23 | +// RGB颜色 | |
| 24 | +#define MJRefreshColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] | |
| 25 | + | |
| 26 | +// 文字颜色 | |
| 27 | +#define MJRefreshLabelTextColor MJRefreshColor(90, 90, 90) | |
| 28 | + | |
| 29 | +// 字体大小 | |
| 30 | +#define MJRefreshLabelFont [UIFont boldSystemFontOfSize:14] | |
| 31 | + | |
| 32 | +// 常量 | |
| 33 | +UIKIT_EXTERN const CGFloat MJRefreshLabelLeftInset; | |
| 34 | +UIKIT_EXTERN const CGFloat MJRefreshHeaderHeight; | |
| 35 | +UIKIT_EXTERN const CGFloat MJRefreshFooterHeight; | |
| 36 | +UIKIT_EXTERN const CGFloat MJRefreshFastAnimationDuration; | |
| 37 | +UIKIT_EXTERN const CGFloat MJRefreshSlowAnimationDuration; | |
| 38 | + | |
| 39 | +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentOffset; | |
| 40 | +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentSize; | |
| 41 | +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentInset; | |
| 42 | +UIKIT_EXTERN NSString *const MJRefreshKeyPathPanState; | |
| 43 | + | |
| 44 | +UIKIT_EXTERN NSString *const MJRefreshHeaderLastUpdatedTimeKey; | |
| 45 | + | |
| 46 | +UIKIT_EXTERN NSString *const MJRefreshHeaderIdleText; | |
| 47 | +UIKIT_EXTERN NSString *const MJRefreshHeaderPullingText; | |
| 48 | +UIKIT_EXTERN NSString *const MJRefreshHeaderRefreshingText; | |
| 49 | + | |
| 50 | +UIKIT_EXTERN NSString *const MJRefreshAutoFooterIdleText; | |
| 51 | +UIKIT_EXTERN NSString *const MJRefreshAutoFooterRefreshingText; | |
| 52 | +UIKIT_EXTERN NSString *const MJRefreshAutoFooterNoMoreDataText; | |
| 53 | + | |
| 54 | +UIKIT_EXTERN NSString *const MJRefreshBackFooterIdleText; | |
| 55 | +UIKIT_EXTERN NSString *const MJRefreshBackFooterPullingText; | |
| 56 | +UIKIT_EXTERN NSString *const MJRefreshBackFooterRefreshingText; | |
| 57 | +UIKIT_EXTERN NSString *const MJRefreshBackFooterNoMoreDataText; | |
| 58 | + | |
| 59 | +UIKIT_EXTERN NSString *const MJRefreshHeaderLastTimeText; | |
| 60 | +UIKIT_EXTERN NSString *const MJRefreshHeaderDateTodayText; | |
| 61 | +UIKIT_EXTERN NSString *const MJRefreshHeaderNoneLastDateText; | |
| 62 | + | |
| 63 | +// 状态检查 | |
| 64 | +#define MJRefreshCheckState \ | |
| 65 | +MJRefreshState oldState = self.state; \ | |
| 66 | +if (state == oldState) return; \ | |
| 67 | +[super setState:state]; | |
| 68 | + | |
| 69 | +// 异步主线程执行,不强持有Self | |
| 70 | +#define MJRefreshDispatchAsyncOnMainQueue(x) \ | |
| 71 | +__weak typeof(self) weakSelf = self; \ | |
| 72 | +dispatch_async(dispatch_get_main_queue(), ^{ \ | |
| 73 | +typeof(weakSelf) self = weakSelf; \ | |
| 74 | +{x} \ | |
| 75 | +}); | |
| 76 | + | ... | ... |
Example/Pods/MJRefresh/MJRefresh/MJRefreshConst.m
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +#import <UIKit/UIKit.h> | |
| 4 | + | |
| 5 | +const CGFloat MJRefreshLabelLeftInset = 25; | |
| 6 | +const CGFloat MJRefreshHeaderHeight = 54.0; | |
| 7 | +const CGFloat MJRefreshFooterHeight = 44.0; | |
| 8 | +const CGFloat MJRefreshFastAnimationDuration = 0.25; | |
| 9 | +const CGFloat MJRefreshSlowAnimationDuration = 0.4; | |
| 10 | + | |
| 11 | +NSString *const MJRefreshKeyPathContentOffset = @"contentOffset"; | |
| 12 | +NSString *const MJRefreshKeyPathContentInset = @"contentInset"; | |
| 13 | +NSString *const MJRefreshKeyPathContentSize = @"contentSize"; | |
| 14 | +NSString *const MJRefreshKeyPathPanState = @"state"; | |
| 15 | + | |
| 16 | +NSString *const MJRefreshHeaderLastUpdatedTimeKey = @"MJRefreshHeaderLastUpdatedTimeKey"; | |
| 17 | + | |
| 18 | +NSString *const MJRefreshHeaderIdleText = @"MJRefreshHeaderIdleText"; | |
| 19 | +NSString *const MJRefreshHeaderPullingText = @"MJRefreshHeaderPullingText"; | |
| 20 | +NSString *const MJRefreshHeaderRefreshingText = @"MJRefreshHeaderRefreshingText"; | |
| 21 | + | |
| 22 | +NSString *const MJRefreshAutoFooterIdleText = @"MJRefreshAutoFooterIdleText"; | |
| 23 | +NSString *const MJRefreshAutoFooterRefreshingText = @"MJRefreshAutoFooterRefreshingText"; | |
| 24 | +NSString *const MJRefreshAutoFooterNoMoreDataText = @"MJRefreshAutoFooterNoMoreDataText"; | |
| 25 | + | |
| 26 | +NSString *const MJRefreshBackFooterIdleText = @"MJRefreshBackFooterIdleText"; | |
| 27 | +NSString *const MJRefreshBackFooterPullingText = @"MJRefreshBackFooterPullingText"; | |
| 28 | +NSString *const MJRefreshBackFooterRefreshingText = @"MJRefreshBackFooterRefreshingText"; | |
| 29 | +NSString *const MJRefreshBackFooterNoMoreDataText = @"MJRefreshBackFooterNoMoreDataText"; | |
| 30 | + | |
| 31 | +NSString *const MJRefreshHeaderLastTimeText = @"MJRefreshHeaderLastTimeText"; | |
| 32 | +NSString *const MJRefreshHeaderDateTodayText = @"MJRefreshHeaderDateTodayText"; | |
| 33 | +NSString *const MJRefreshHeaderNoneLastDateText = @"MJRefreshHeaderNoneLastDateText"; | |
| 0 | 34 | \ No newline at end of file | ... | ... |
Example/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.h
0 → 100644
| 1 | +// | |
| 2 | +// NSBundle+MJRefresh.h | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 16/6/13. | |
| 6 | +// Copyright © 2016年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import <UIKit/UIKit.h> | |
| 10 | + | |
| 11 | +@interface NSBundle (MJRefresh) | |
| 12 | ++ (instancetype)mj_refreshBundle; | |
| 13 | ++ (UIImage *)mj_arrowImage; | |
| 14 | ++ (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value; | |
| 15 | ++ (NSString *)mj_localizedStringForKey:(NSString *)key; | |
| 16 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.m
0 → 100644
| 1 | +// | |
| 2 | +// NSBundle+MJRefresh.m | |
| 3 | +// MJRefreshExample | |
| 4 | +// | |
| 5 | +// Created by MJ Lee on 16/6/13. | |
| 6 | +// Copyright © 2016年 小码哥. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "NSBundle+MJRefresh.h" | |
| 10 | +#import "MJRefreshComponent.h" | |
| 11 | + | |
| 12 | +@implementation NSBundle (MJRefresh) | |
| 13 | ++ (instancetype)mj_refreshBundle | |
| 14 | +{ | |
| 15 | + static NSBundle *refreshBundle = nil; | |
| 16 | + if (refreshBundle == nil) { | |
| 17 | + // 这里不使用mainBundle是为了适配pod 1.x和0.x | |
| 18 | + refreshBundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[MJRefreshComponent class]] pathForResource:@"MJRefresh" ofType:@"bundle"]]; | |
| 19 | + } | |
| 20 | + return refreshBundle; | |
| 21 | +} | |
| 22 | + | |
| 23 | ++ (UIImage *)mj_arrowImage | |
| 24 | +{ | |
| 25 | + static UIImage *arrowImage = nil; | |
| 26 | + if (arrowImage == nil) { | |
| 27 | + arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; | |
| 28 | + } | |
| 29 | + return arrowImage; | |
| 30 | +} | |
| 31 | + | |
| 32 | ++ (NSString *)mj_localizedStringForKey:(NSString *)key | |
| 33 | +{ | |
| 34 | + return [self mj_localizedStringForKey:key value:nil]; | |
| 35 | +} | |
| 36 | + | |
| 37 | ++ (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value | |
| 38 | +{ | |
| 39 | + static NSBundle *bundle = nil; | |
| 40 | + if (bundle == nil) { | |
| 41 | + // (iOS获取的语言字符串比较不稳定)目前框架只处理en、zh-Hans、zh-Hant三种情况,其他按照系统默认处理 | |
| 42 | + NSString *language = [NSLocale preferredLanguages].firstObject; | |
| 43 | + if ([language hasPrefix:@"en"]) { | |
| 44 | + language = @"en"; | |
| 45 | + } else if ([language hasPrefix:@"zh"]) { | |
| 46 | + if ([language rangeOfString:@"Hans"].location != NSNotFound) { | |
| 47 | + language = @"zh-Hans"; // 简体中文 | |
| 48 | + } else { // zh-Hant\zh-HK\zh-TW | |
| 49 | + language = @"zh-Hant"; // 繁體中文 | |
| 50 | + } | |
| 51 | + } else { | |
| 52 | + language = @"en"; | |
| 53 | + } | |
| 54 | + | |
| 55 | + // 从MJRefresh.bundle中查找资源 | |
| 56 | + bundle = [NSBundle bundleWithPath:[[NSBundle mj_refreshBundle] pathForResource:language ofType:@"lproj"]]; | |
| 57 | + } | |
| 58 | + value = [bundle localizedStringForKey:key value:value table:nil]; | |
| 59 | + return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil]; | |
| 60 | +} | |
| 61 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// UIScrollView+Extension.h | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 14-5-28. | |
| 7 | +// Copyright (c) 2014年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import <UIKit/UIKit.h> | |
| 11 | + | |
| 12 | +@interface UIScrollView (MJExtension) | |
| 13 | +@property (readonly, nonatomic) UIEdgeInsets mj_inset; | |
| 14 | + | |
| 15 | +@property (assign, nonatomic) CGFloat mj_insetT; | |
| 16 | +@property (assign, nonatomic) CGFloat mj_insetB; | |
| 17 | +@property (assign, nonatomic) CGFloat mj_insetL; | |
| 18 | +@property (assign, nonatomic) CGFloat mj_insetR; | |
| 19 | + | |
| 20 | +@property (assign, nonatomic) CGFloat mj_offsetX; | |
| 21 | +@property (assign, nonatomic) CGFloat mj_offsetY; | |
| 22 | + | |
| 23 | +@property (assign, nonatomic) CGFloat mj_contentW; | |
| 24 | +@property (assign, nonatomic) CGFloat mj_contentH; | |
| 25 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.m
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// UIScrollView+Extension.m | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 14-5-28. | |
| 7 | +// Copyright (c) 2014年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import "UIScrollView+MJExtension.h" | |
| 11 | +#import <objc/runtime.h> | |
| 12 | + | |
| 13 | +#pragma clang diagnostic push | |
| 14 | +#pragma clang diagnostic ignored "-Wunguarded-availability-new" | |
| 15 | + | |
| 16 | +@implementation UIScrollView (MJExtension) | |
| 17 | + | |
| 18 | +static BOOL respondsToAdjustedContentInset_; | |
| 19 | + | |
| 20 | ++ (void)initialize | |
| 21 | +{ | |
| 22 | + static dispatch_once_t onceToken; | |
| 23 | + dispatch_once(&onceToken, ^{ | |
| 24 | + respondsToAdjustedContentInset_ = [self instancesRespondToSelector:@selector(adjustedContentInset)]; | |
| 25 | + }); | |
| 26 | +} | |
| 27 | + | |
| 28 | +- (UIEdgeInsets)mj_inset | |
| 29 | +{ | |
| 30 | +#ifdef __IPHONE_11_0 | |
| 31 | + if (respondsToAdjustedContentInset_) { | |
| 32 | + return self.adjustedContentInset; | |
| 33 | + } | |
| 34 | +#endif | |
| 35 | + return self.contentInset; | |
| 36 | +} | |
| 37 | + | |
| 38 | +- (void)setMj_insetT:(CGFloat)mj_insetT | |
| 39 | +{ | |
| 40 | + UIEdgeInsets inset = self.contentInset; | |
| 41 | + inset.top = mj_insetT; | |
| 42 | +#ifdef __IPHONE_11_0 | |
| 43 | + if (respondsToAdjustedContentInset_) { | |
| 44 | + inset.top -= (self.adjustedContentInset.top - self.contentInset.top); | |
| 45 | + } | |
| 46 | +#endif | |
| 47 | + self.contentInset = inset; | |
| 48 | +} | |
| 49 | + | |
| 50 | +- (CGFloat)mj_insetT | |
| 51 | +{ | |
| 52 | + return self.mj_inset.top; | |
| 53 | +} | |
| 54 | + | |
| 55 | +- (void)setMj_insetB:(CGFloat)mj_insetB | |
| 56 | +{ | |
| 57 | + UIEdgeInsets inset = self.contentInset; | |
| 58 | + inset.bottom = mj_insetB; | |
| 59 | +#ifdef __IPHONE_11_0 | |
| 60 | + if (respondsToAdjustedContentInset_) { | |
| 61 | + inset.bottom -= (self.adjustedContentInset.bottom - self.contentInset.bottom); | |
| 62 | + } | |
| 63 | +#endif | |
| 64 | + self.contentInset = inset; | |
| 65 | +} | |
| 66 | + | |
| 67 | +- (CGFloat)mj_insetB | |
| 68 | +{ | |
| 69 | + return self.mj_inset.bottom; | |
| 70 | +} | |
| 71 | + | |
| 72 | +- (void)setMj_insetL:(CGFloat)mj_insetL | |
| 73 | +{ | |
| 74 | + UIEdgeInsets inset = self.contentInset; | |
| 75 | + inset.left = mj_insetL; | |
| 76 | +#ifdef __IPHONE_11_0 | |
| 77 | + if (respondsToAdjustedContentInset_) { | |
| 78 | + inset.left -= (self.adjustedContentInset.left - self.contentInset.left); | |
| 79 | + } | |
| 80 | +#endif | |
| 81 | + self.contentInset = inset; | |
| 82 | +} | |
| 83 | + | |
| 84 | +- (CGFloat)mj_insetL | |
| 85 | +{ | |
| 86 | + return self.mj_inset.left; | |
| 87 | +} | |
| 88 | + | |
| 89 | +- (void)setMj_insetR:(CGFloat)mj_insetR | |
| 90 | +{ | |
| 91 | + UIEdgeInsets inset = self.contentInset; | |
| 92 | + inset.right = mj_insetR; | |
| 93 | +#ifdef __IPHONE_11_0 | |
| 94 | + if (respondsToAdjustedContentInset_) { | |
| 95 | + inset.right -= (self.adjustedContentInset.right - self.contentInset.right); | |
| 96 | + } | |
| 97 | +#endif | |
| 98 | + self.contentInset = inset; | |
| 99 | +} | |
| 100 | + | |
| 101 | +- (CGFloat)mj_insetR | |
| 102 | +{ | |
| 103 | + return self.mj_inset.right; | |
| 104 | +} | |
| 105 | + | |
| 106 | +- (void)setMj_offsetX:(CGFloat)mj_offsetX | |
| 107 | +{ | |
| 108 | + CGPoint offset = self.contentOffset; | |
| 109 | + offset.x = mj_offsetX; | |
| 110 | + self.contentOffset = offset; | |
| 111 | +} | |
| 112 | + | |
| 113 | +- (CGFloat)mj_offsetX | |
| 114 | +{ | |
| 115 | + return self.contentOffset.x; | |
| 116 | +} | |
| 117 | + | |
| 118 | +- (void)setMj_offsetY:(CGFloat)mj_offsetY | |
| 119 | +{ | |
| 120 | + CGPoint offset = self.contentOffset; | |
| 121 | + offset.y = mj_offsetY; | |
| 122 | + self.contentOffset = offset; | |
| 123 | +} | |
| 124 | + | |
| 125 | +- (CGFloat)mj_offsetY | |
| 126 | +{ | |
| 127 | + return self.contentOffset.y; | |
| 128 | +} | |
| 129 | + | |
| 130 | +- (void)setMj_contentW:(CGFloat)mj_contentW | |
| 131 | +{ | |
| 132 | + CGSize size = self.contentSize; | |
| 133 | + size.width = mj_contentW; | |
| 134 | + self.contentSize = size; | |
| 135 | +} | |
| 136 | + | |
| 137 | +- (CGFloat)mj_contentW | |
| 138 | +{ | |
| 139 | + return self.contentSize.width; | |
| 140 | +} | |
| 141 | + | |
| 142 | +- (void)setMj_contentH:(CGFloat)mj_contentH | |
| 143 | +{ | |
| 144 | + CGSize size = self.contentSize; | |
| 145 | + size.height = mj_contentH; | |
| 146 | + self.contentSize = size; | |
| 147 | +} | |
| 148 | + | |
| 149 | +- (CGFloat)mj_contentH | |
| 150 | +{ | |
| 151 | + return self.contentSize.height; | |
| 152 | +} | |
| 153 | +@end | |
| 154 | +#pragma clang diagnostic pop | ... | ... |
Example/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// UIScrollView+MJRefresh.h | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/4. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// 给ScrollView增加下拉刷新、上拉刷新的功能 | |
| 9 | + | |
| 10 | +#import <UIKit/UIKit.h> | |
| 11 | +#import "MJRefreshConst.h" | |
| 12 | + | |
| 13 | +@class MJRefreshHeader, MJRefreshFooter; | |
| 14 | + | |
| 15 | +@interface UIScrollView (MJRefresh) | |
| 16 | +/** 下拉刷新控件 */ | |
| 17 | +@property (strong, nonatomic) MJRefreshHeader *mj_header; | |
| 18 | +@property (strong, nonatomic) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header"); | |
| 19 | +/** 上拉刷新控件 */ | |
| 20 | +@property (strong, nonatomic) MJRefreshFooter *mj_footer; | |
| 21 | +@property (strong, nonatomic) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer"); | |
| 22 | + | |
| 23 | +#pragma mark - other | |
| 24 | +- (NSInteger)mj_totalDataCount; | |
| 25 | +@property (copy, nonatomic) void (^mj_reloadDataBlock)(NSInteger totalDataCount); | |
| 26 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// UIScrollView+MJRefresh.m | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 15/3/4. | |
| 7 | +// Copyright (c) 2015年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import "UIScrollView+MJRefresh.h" | |
| 11 | +#import "MJRefreshHeader.h" | |
| 12 | +#import "MJRefreshFooter.h" | |
| 13 | +#import <objc/runtime.h> | |
| 14 | + | |
| 15 | +@implementation NSObject (MJRefresh) | |
| 16 | + | |
| 17 | ++ (void)exchangeInstanceMethod1:(SEL)method1 method2:(SEL)method2 | |
| 18 | +{ | |
| 19 | + method_exchangeImplementations(class_getInstanceMethod(self, method1), class_getInstanceMethod(self, method2)); | |
| 20 | +} | |
| 21 | + | |
| 22 | ++ (void)exchangeClassMethod1:(SEL)method1 method2:(SEL)method2 | |
| 23 | +{ | |
| 24 | + method_exchangeImplementations(class_getClassMethod(self, method1), class_getClassMethod(self, method2)); | |
| 25 | +} | |
| 26 | + | |
| 27 | +@end | |
| 28 | + | |
| 29 | +@implementation UIScrollView (MJRefresh) | |
| 30 | + | |
| 31 | +#pragma mark - header | |
| 32 | +static const char MJRefreshHeaderKey = '\0'; | |
| 33 | +- (void)setMj_header:(MJRefreshHeader *)mj_header | |
| 34 | +{ | |
| 35 | + if (mj_header != self.mj_header) { | |
| 36 | + // 删除旧的,添加新的 | |
| 37 | + [self.mj_header removeFromSuperview]; | |
| 38 | + [self insertSubview:mj_header atIndex:0]; | |
| 39 | + | |
| 40 | + // 存储新的 | |
| 41 | + objc_setAssociatedObject(self, &MJRefreshHeaderKey, | |
| 42 | + mj_header, OBJC_ASSOCIATION_RETAIN); | |
| 43 | + } | |
| 44 | +} | |
| 45 | + | |
| 46 | +- (MJRefreshHeader *)mj_header | |
| 47 | +{ | |
| 48 | + return objc_getAssociatedObject(self, &MJRefreshHeaderKey); | |
| 49 | +} | |
| 50 | + | |
| 51 | +#pragma mark - footer | |
| 52 | +static const char MJRefreshFooterKey = '\0'; | |
| 53 | +- (void)setMj_footer:(MJRefreshFooter *)mj_footer | |
| 54 | +{ | |
| 55 | + if (mj_footer != self.mj_footer) { | |
| 56 | + // 删除旧的,添加新的 | |
| 57 | + [self.mj_footer removeFromSuperview]; | |
| 58 | + [self insertSubview:mj_footer atIndex:0]; | |
| 59 | + | |
| 60 | + // 存储新的 | |
| 61 | + objc_setAssociatedObject(self, &MJRefreshFooterKey, | |
| 62 | + mj_footer, OBJC_ASSOCIATION_RETAIN); | |
| 63 | + } | |
| 64 | +} | |
| 65 | + | |
| 66 | +- (MJRefreshFooter *)mj_footer | |
| 67 | +{ | |
| 68 | + return objc_getAssociatedObject(self, &MJRefreshFooterKey); | |
| 69 | +} | |
| 70 | + | |
| 71 | +#pragma mark - 过期 | |
| 72 | +- (void)setFooter:(MJRefreshFooter *)footer | |
| 73 | +{ | |
| 74 | + self.mj_footer = footer; | |
| 75 | +} | |
| 76 | + | |
| 77 | +- (MJRefreshFooter *)footer | |
| 78 | +{ | |
| 79 | + return self.mj_footer; | |
| 80 | +} | |
| 81 | + | |
| 82 | +- (void)setHeader:(MJRefreshHeader *)header | |
| 83 | +{ | |
| 84 | + self.mj_header = header; | |
| 85 | +} | |
| 86 | + | |
| 87 | +- (MJRefreshHeader *)header | |
| 88 | +{ | |
| 89 | + return self.mj_header; | |
| 90 | +} | |
| 91 | + | |
| 92 | +#pragma mark - other | |
| 93 | +- (NSInteger)mj_totalDataCount | |
| 94 | +{ | |
| 95 | + NSInteger totalCount = 0; | |
| 96 | + if ([self isKindOfClass:[UITableView class]]) { | |
| 97 | + UITableView *tableView = (UITableView *)self; | |
| 98 | + | |
| 99 | + for (NSInteger section = 0; section<tableView.numberOfSections; section++) { | |
| 100 | + totalCount += [tableView numberOfRowsInSection:section]; | |
| 101 | + } | |
| 102 | + } else if ([self isKindOfClass:[UICollectionView class]]) { | |
| 103 | + UICollectionView *collectionView = (UICollectionView *)self; | |
| 104 | + | |
| 105 | + for (NSInteger section = 0; section<collectionView.numberOfSections; section++) { | |
| 106 | + totalCount += [collectionView numberOfItemsInSection:section]; | |
| 107 | + } | |
| 108 | + } | |
| 109 | + return totalCount; | |
| 110 | +} | |
| 111 | + | |
| 112 | +static const char MJRefreshReloadDataBlockKey = '\0'; | |
| 113 | +- (void)setMj_reloadDataBlock:(void (^)(NSInteger))mj_reloadDataBlock | |
| 114 | +{ | |
| 115 | + [self willChangeValueForKey:@"mj_reloadDataBlock"]; // KVO | |
| 116 | + objc_setAssociatedObject(self, &MJRefreshReloadDataBlockKey, mj_reloadDataBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); | |
| 117 | + [self didChangeValueForKey:@"mj_reloadDataBlock"]; // KVO | |
| 118 | +} | |
| 119 | + | |
| 120 | +- (void (^)(NSInteger))mj_reloadDataBlock | |
| 121 | +{ | |
| 122 | + return objc_getAssociatedObject(self, &MJRefreshReloadDataBlockKey); | |
| 123 | +} | |
| 124 | + | |
| 125 | +- (void)executeReloadDataBlock | |
| 126 | +{ | |
| 127 | + !self.mj_reloadDataBlock ? : self.mj_reloadDataBlock(self.mj_totalDataCount); | |
| 128 | +} | |
| 129 | +@end | |
| 130 | + | |
| 131 | +@implementation UITableView (MJRefresh) | |
| 132 | + | |
| 133 | ++ (void)load | |
| 134 | +{ | |
| 135 | + [self exchangeInstanceMethod1:@selector(reloadData) method2:@selector(mj_reloadData)]; | |
| 136 | +} | |
| 137 | + | |
| 138 | +- (void)mj_reloadData | |
| 139 | +{ | |
| 140 | + [self mj_reloadData]; | |
| 141 | + | |
| 142 | + [self executeReloadDataBlock]; | |
| 143 | +} | |
| 144 | +@end | |
| 145 | + | |
| 146 | +@implementation UICollectionView (MJRefresh) | |
| 147 | + | |
| 148 | ++ (void)load | |
| 149 | +{ | |
| 150 | + [self exchangeInstanceMethod1:@selector(reloadData) method2:@selector(mj_reloadData)]; | |
| 151 | +} | |
| 152 | + | |
| 153 | +- (void)mj_reloadData | |
| 154 | +{ | |
| 155 | + [self mj_reloadData]; | |
| 156 | + | |
| 157 | + [self executeReloadDataBlock]; | |
| 158 | +} | |
| 159 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/UIView+MJExtension.h
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// UIView+Extension.h | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 14-5-28. | |
| 7 | +// Copyright (c) 2014年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import <UIKit/UIKit.h> | |
| 11 | + | |
| 12 | +@interface UIView (MJExtension) | |
| 13 | +@property (assign, nonatomic) CGFloat mj_x; | |
| 14 | +@property (assign, nonatomic) CGFloat mj_y; | |
| 15 | +@property (assign, nonatomic) CGFloat mj_w; | |
| 16 | +@property (assign, nonatomic) CGFloat mj_h; | |
| 17 | +@property (assign, nonatomic) CGSize mj_size; | |
| 18 | +@property (assign, nonatomic) CGPoint mj_origin; | |
| 19 | +@end | ... | ... |
Example/Pods/MJRefresh/MJRefresh/UIView+MJExtension.m
0 → 100644
| 1 | +// 代码地址: https://github.com/CoderMJLee/MJRefresh | |
| 2 | +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 | |
| 3 | +// UIView+Extension.m | |
| 4 | +// MJRefreshExample | |
| 5 | +// | |
| 6 | +// Created by MJ Lee on 14-5-28. | |
| 7 | +// Copyright (c) 2014年 小码哥. All rights reserved. | |
| 8 | +// | |
| 9 | + | |
| 10 | +#import "UIView+MJExtension.h" | |
| 11 | + | |
| 12 | +@implementation UIView (MJExtension) | |
| 13 | +- (void)setMj_x:(CGFloat)mj_x | |
| 14 | +{ | |
| 15 | + CGRect frame = self.frame; | |
| 16 | + frame.origin.x = mj_x; | |
| 17 | + self.frame = frame; | |
| 18 | +} | |
| 19 | + | |
| 20 | +- (CGFloat)mj_x | |
| 21 | +{ | |
| 22 | + return self.frame.origin.x; | |
| 23 | +} | |
| 24 | + | |
| 25 | +- (void)setMj_y:(CGFloat)mj_y | |
| 26 | +{ | |
| 27 | + CGRect frame = self.frame; | |
| 28 | + frame.origin.y = mj_y; | |
| 29 | + self.frame = frame; | |
| 30 | +} | |
| 31 | + | |
| 32 | +- (CGFloat)mj_y | |
| 33 | +{ | |
| 34 | + return self.frame.origin.y; | |
| 35 | +} | |
| 36 | + | |
| 37 | +- (void)setMj_w:(CGFloat)mj_w | |
| 38 | +{ | |
| 39 | + CGRect frame = self.frame; | |
| 40 | + frame.size.width = mj_w; | |
| 41 | + self.frame = frame; | |
| 42 | +} | |
| 43 | + | |
| 44 | +- (CGFloat)mj_w | |
| 45 | +{ | |
| 46 | + return self.frame.size.width; | |
| 47 | +} | |
| 48 | + | |
| 49 | +- (void)setMj_h:(CGFloat)mj_h | |
| 50 | +{ | |
| 51 | + CGRect frame = self.frame; | |
| 52 | + frame.size.height = mj_h; | |
| 53 | + self.frame = frame; | |
| 54 | +} | |
| 55 | + | |
| 56 | +- (CGFloat)mj_h | |
| 57 | +{ | |
| 58 | + return self.frame.size.height; | |
| 59 | +} | |
| 60 | + | |
| 61 | +- (void)setMj_size:(CGSize)mj_size | |
| 62 | +{ | |
| 63 | + CGRect frame = self.frame; | |
| 64 | + frame.size = mj_size; | |
| 65 | + self.frame = frame; | |
| 66 | +} | |
| 67 | + | |
| 68 | +- (CGSize)mj_size | |
| 69 | +{ | |
| 70 | + return self.frame.size; | |
| 71 | +} | |
| 72 | + | |
| 73 | +- (void)setMj_origin:(CGPoint)mj_origin | |
| 74 | +{ | |
| 75 | + CGRect frame = self.frame; | |
| 76 | + frame.origin = mj_origin; | |
| 77 | + self.frame = frame; | |
| 78 | +} | |
| 79 | + | |
| 80 | +- (CGPoint)mj_origin | |
| 81 | +{ | |
| 82 | + return self.frame.origin; | |
| 83 | +} | |
| 84 | +@end | ... | ... |
Example/Pods/MJRefresh/README.md
0 → 100644
| 1 | + | |
| 2 | +## MJRefresh | |
| 3 | +* An easy way to use pull-to-refresh | |
| 4 | + | |
| 5 | +## Contents | |
| 6 | +* Getting Started | |
| 7 | + * [Features【Support what kinds of controls to refresh】](#Support_what_kinds_of_controls_to_refresh) | |
| 8 | + * [Installation【How to use MJRefresh】](#How_to_use_MJRefresh) | |
| 9 | + * [Who's using【More than hundreds of Apps are using MJRefresh】](#More_than_hundreds_of_Apps_are_using_MJRefresh) | |
| 10 | + * [Classes【The Class Structure Chart of MJRefresh】](#The_Class_Structure_Chart_of_MJRefresh) | |
| 11 | +* Comment API | |
| 12 | + * [MJRefreshComponent.h](#MJRefreshComponent.h) | |
| 13 | + * [MJRefreshHeader.h](#MJRefreshHeader.h) | |
| 14 | + * [MJRefreshFooter.h](#MJRefreshFooter.h) | |
| 15 | + * [MJRefreshAutoFooter.h](#MJRefreshAutoFooter.h) | |
| 16 | +* Examples | |
| 17 | + * [Reference](#Reference) | |
| 18 | + * [The drop-down refresh 01-Default](#The_drop-down_refresh_01-Default) | |
| 19 | + * [The drop-down refresh 02-Animation image](#The_drop-down_refresh_02-Animation_image) | |
| 20 | + * [The drop-down refresh 03-Hide the time](#The_drop-down_refresh_03-Hide_the_time) | |
| 21 | + * [The drop-down refresh 04-Hide status and time](#The_drop-down_refresh_04-Hide_status_and_time) | |
| 22 | + * [The drop-down refresh 05-DIY title](#The_drop-down_refresh_05-DIY_title) | |
| 23 | + * [The drop-down refresh 06-DIY the control of refresh](#The_drop-down_refresh_06-DIY_the_control_of_refresh) | |
| 24 | + * [The pull to refresh 01-Default](#The_pull_to_refresh_01-Default) | |
| 25 | + * [The pull to refresh 02-Animation image](#The_pull_to_refresh_02-Animation_image) | |
| 26 | + * [The pull to refresh 03-Hide the title of refresh status](#The_pull_to_refresh_03-Hide_the_title_of_refresh_status) | |
| 27 | + * [The pull to refresh 04-All loaded](#The_pull_to_refresh_04-All_loaded) | |
| 28 | + * [The pull to refresh 05-DIY title](#The_pull_to_refresh_05-DIY_title) | |
| 29 | + * [The pull to refresh 06-Hidden After loaded](#The_pull_to_refresh_06-Hidden_After_loaded) | |
| 30 | + * [The pull to refresh 07-Automatic back of the pull01](#The_pull_to_refresh_07-Automatic_back_of_the_pull01) | |
| 31 | + * [The pull to refresh 08-Automatic back of the pull02](#The_pull_to_refresh_08-Automatic_back_of_the_pull02) | |
| 32 | + * [The pull to refresh 09-DIY the control of refresh(Automatic refresh)](#The_pull_to_refresh_09-DIY_the_control_of_refresh(Automatic_refresh)) | |
| 33 | + * [The pull to refresh 10-DIY the control of refresh(Automatic back)](#The_pull_to_refresh_10-DIY_the_control_of_refresh(Automatic_back)) | |
| 34 | + * [UICollectionView01-The pull and drop-down refresh](#UICollectionView01-The_pull_and_drop-down_refresh) | |
| 35 | + * [UIWebView01-The drop-down refresh](#UIWebView01-The_drop-down_refresh) | |
| 36 | +* [Hope](#Hope) | |
| 37 | + | |
| 38 | +## <a id="Support_what_kinds_of_controls_to_refresh"></a>Support what kinds of controls to refresh | |
| 39 | +* `UIScrollView`、`UITableView`、`UICollectionView`、`UIWebView` | |
| 40 | + | |
| 41 | +## <a id="How_to_use_MJRefresh"></a>How to use MJRefresh | |
| 42 | +* Installation with CocoaPods:`pod 'MJRefresh'` | |
| 43 | +* Manual import: | |
| 44 | + * Drag All files in the `MJRefresh` folder to project | |
| 45 | + * Import the main file:`#import "MJRefresh.h"` | |
| 46 | + | |
| 47 | +```objc | |
| 48 | +Base Custom | |
| 49 | +MJRefresh.bundle MJRefresh.h | |
| 50 | +MJRefreshConst.h MJRefreshConst.m | |
| 51 | +UIScrollView+MJExtension.h UIScrollView+MJExtension.m | |
| 52 | +UIScrollView+MJRefresh.h UIScrollView+MJRefresh.m | |
| 53 | +UIView+MJExtension.h UIView+MJExtension.m | |
| 54 | +``` | |
| 55 | + | |
| 56 | +## <a id="More_than_hundreds_of_Apps_are_using_MJRefresh"></a>More than hundreds of Apps are using MJRefresh | |
| 57 | +<img src="http://images0.cnblogs.com/blog2015/497279/201506/141212365041650.png" width="200" height="300"> | |
| 58 | +* More information of App can focus on:[M了个J-博客园](http://www.cnblogs.com/mjios/p/4409853.html) | |
| 59 | + | |
| 60 | +## <a id="The_Class_Structure_Chart_of_MJRefresh"></a>The Class Structure Chart of MJRefresh | |
| 61 | + | |
| 62 | +- `The class of red text` in the chart:You can use them directly | |
| 63 | + - The drop-down refresh control types | |
| 64 | + - Normal:`MJRefreshNormalHeader` | |
| 65 | + - Gif:`MJRefreshGifHeader` | |
| 66 | + - The pull to refresh control types | |
| 67 | + - Auto refresh | |
| 68 | + - Normal:`MJRefreshAutoNormalFooter` | |
| 69 | + - Gif:`MJRefreshAutoGifFooter` | |
| 70 | + - Auto Back | |
| 71 | + - Normal:`MJRefreshBackNormalFooter` | |
| 72 | + - Gif:`MJRefreshBackGifFooter` | |
| 73 | +- `The class of non-red text` in the chart:For inheritance,to use DIY the control of refresh | |
| 74 | +- About how to DIY the control of refresh,You can refer the Class in below Chart<br> | |
| 75 | +<img src="http://images0.cnblogs.com/blog2015/497279/201506/141358159107893.png" width="30%" height="30%"> | |
| 76 | + | |
| 77 | +## <a id="MJRefreshComponent.h"></a>MJRefreshComponent.h | |
| 78 | +```objc | |
| 79 | +/** The Base Class of refresh control */ | |
| 80 | +@interface MJRefreshComponent : UIView | |
| 81 | +#pragma mark - Control the state of Refresh | |
| 82 | + | |
| 83 | +/** BeginRefreshing */ | |
| 84 | +- (void)beginRefreshing; | |
| 85 | +/** EndRefreshing */ | |
| 86 | +- (void)endRefreshing; | |
| 87 | +/** IsRefreshing */ | |
| 88 | +- (BOOL)isRefreshing; | |
| 89 | + | |
| 90 | +#pragma mark - Other | |
| 91 | +/** According to the drag ratio to change alpha automatically */ | |
| 92 | +@property (assign, nonatomic, getter=isAutomaticallyChangeAlpha) BOOL automaticallyChangeAlpha; | |
| 93 | +@end | |
| 94 | +``` | |
| 95 | + | |
| 96 | +## <a id="MJRefreshHeader.h"></a>MJRefreshHeader.h | |
| 97 | +```objc | |
| 98 | +@interface MJRefreshHeader : MJRefreshComponent | |
| 99 | +/** Creat header */ | |
| 100 | ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; | |
| 101 | +/** Creat header */ | |
| 102 | ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; | |
| 103 | + | |
| 104 | +/** This key is used to storage the time that the last time of drown-down successfully */ | |
| 105 | +@property (copy, nonatomic) NSString *lastUpdatedTimeKey; | |
| 106 | +/** The last time of drown-down successfully */ | |
| 107 | +@property (strong, nonatomic, readonly) NSDate *lastUpdatedTime; | |
| 108 | + | |
| 109 | +/** Ignored scrollView contentInset top */ | |
| 110 | +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; | |
| 111 | +@end | |
| 112 | +``` | |
| 113 | + | |
| 114 | +## <a id="MJRefreshFooter.h"></a>MJRefreshFooter.h | |
| 115 | +```objc | |
| 116 | +@interface MJRefreshFooter : MJRefreshComponent | |
| 117 | +/** Creat footer */ | |
| 118 | ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; | |
| 119 | +/** Creat footer */ | |
| 120 | ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; | |
| 121 | + | |
| 122 | +/** NoticeNoMoreData */ | |
| 123 | +- (void)noticeNoMoreData; | |
| 124 | +/** ResetNoMoreData(Clear the status of NoMoreData ) */ | |
| 125 | +- (void)resetNoMoreData; | |
| 126 | + | |
| 127 | +/** Ignored scrollView contentInset bottom */ | |
| 128 | +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; | |
| 129 | + | |
| 130 | +/** Automaticlly show or hidden by the count of data(Show-have data,Hidden- no data) */ | |
| 131 | +@property (assign, nonatomic) BOOL automaticallyHidden; | |
| 132 | +@end | |
| 133 | +``` | |
| 134 | + | |
| 135 | +## <a id="MJRefreshAutoFooter.h"></a>MJRefreshAutoFooter.h | |
| 136 | +```objc | |
| 137 | +@interface MJRefreshAutoFooter : MJRefreshFooter | |
| 138 | +/** Is Automatically Refresh(Default is Yes) */ | |
| 139 | +@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; | |
| 140 | + | |
| 141 | +/** When there is much at the bottom of the control is automatically refresh(Default is 1.0,Is at the bottom of the control appears in full, will refresh automatically) */ | |
| 142 | +@property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; | |
| 143 | +@end | |
| 144 | +``` | |
| 145 | + | |
| 146 | +## <a id="Reference"></a>Reference | |
| 147 | +```objc | |
| 148 | +* Due to there are more functions of this framework,Don't write specific text describe its usage | |
| 149 | +* You can directly reference examples MJTableViewController、MJCollectionViewController、MJWebViewController,More intuitive and fast. | |
| 150 | +``` | |
| 151 | +<img src="http://images0.cnblogs.com/blog2015/497279/201506/141345470048120.png" width="30%" height="30%"> | |
| 152 | + | |
| 153 | +## <a id="The_drop-down_refresh_01-Default"></a>The drop-down refresh 01-Default | |
| 154 | + | |
| 155 | +```objc | |
| 156 | +self.tableView.header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ | |
| 157 | + //Call this Block When enter the refresh status automatically | |
| 158 | +}]; | |
| 159 | +或 | |
| 160 | +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadNewData]) | |
| 161 | +self.tableView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; | |
| 162 | + | |
| 163 | +// Enter the refresh status immediately | |
| 164 | +[self.tableView.header beginRefreshing]; | |
| 165 | +``` | |
| 166 | + | |
| 167 | + | |
| 168 | +## <a id="The_drop-down_refresh_02-Animation_image"></a>The drop-down refresh 02-Animation image | |
| 169 | +```objc | |
| 170 | +// Set the callback(一Once you enter the refresh status,then call the action of target,that is call [self loadNewData]) | |
| 171 | +MJRefreshGifHeader *header = [MJRefreshGifHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; | |
| 172 | +// Set the ordinary state of animated images | |
| 173 | +[header setImages:idleImages forState:MJRefreshStateIdle]; | |
| 174 | +// Set the pulling state of animated images(Enter the status of refreshing as soon as loosen) | |
| 175 | +[header setImages:pullingImages forState:MJRefreshStatePulling]; | |
| 176 | +// Set the refreshing state of animated images | |
| 177 | +[header setImages:refreshingImages forState:MJRefreshStateRefreshing]; | |
| 178 | +// Set header | |
| 179 | +self.tableView.mj_header = header; | |
| 180 | +``` | |
| 181 | + | |
| 182 | + | |
| 183 | +## <a id="The_drop-down_refresh_03-Hide_the_time"></a>The drop-down refresh 03-Hide the time | |
| 184 | +```objc | |
| 185 | +// Hide the time | |
| 186 | +header.lastUpdatedTimeLabel.hidden = YES; | |
| 187 | +``` | |
| 188 | + | |
| 189 | + | |
| 190 | +## <a id="The_drop-down_refresh_04-Hide_status_and_time"></a>The drop-down refresh 04-Hide status and time | |
| 191 | +```objc | |
| 192 | +// Hide the time | |
| 193 | +header.lastUpdatedTimeLabel.hidden = YES; | |
| 194 | + | |
| 195 | +// Hide the status | |
| 196 | +header.stateLabel.hidden = YES; | |
| 197 | +``` | |
| 198 | + | |
| 199 | + | |
| 200 | +## <a id="The_drop-down_refresh_05-DIY_title"></a>The drop-down refresh 05-DIY title | |
| 201 | +```objc | |
| 202 | +// Set title | |
| 203 | +[header setTitle:@"Pull down to refresh" forState:MJRefreshStateIdle]; | |
| 204 | +[header setTitle:@"Release to refresh" forState:MJRefreshStatePulling]; | |
| 205 | +[header setTitle:@"Loading ..." forState:MJRefreshStateRefreshing]; | |
| 206 | + | |
| 207 | +// Set font | |
| 208 | +header.stateLabel.font = [UIFont systemFontOfSize:15]; | |
| 209 | +header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:14]; | |
| 210 | + | |
| 211 | +// Set textColor | |
| 212 | +header.stateLabel.textColor = [UIColor redColor]; | |
| 213 | +header.lastUpdatedTimeLabel.textColor = [UIColor blueColor]; | |
| 214 | +``` | |
| 215 | + | |
| 216 | + | |
| 217 | +## <a id="The_drop-down_refresh_06-DIY_the_control_of_refresh"></a>The drop-down refresh 06-DIY the control of refresh | |
| 218 | +```objc | |
| 219 | +self.tableView.mj_header = [MJDIYHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; | |
| 220 | +// Implementation reference to MJDIYHeader.h和MJDIYHeader.m | |
| 221 | +``` | |
| 222 | + | |
| 223 | + | |
| 224 | +## <a id="The_pull_to_refresh_01-Default"></a>The pull to refresh 01-Default | |
| 225 | +```objc | |
| 226 | +self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ | |
| 227 | + //Call this Block When enter the refresh status automatically | |
| 228 | +}]; | |
| 229 | +或 | |
| 230 | +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadMoreData]) | |
| 231 | +self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; | |
| 232 | +``` | |
| 233 | + | |
| 234 | + | |
| 235 | +## <a id="The_pull_to_refresh_02-Animation_image"></a>The pull to refresh 02-Animation image | |
| 236 | +```objc | |
| 237 | +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadMoreData]) | |
| 238 | +MJRefreshAutoGifFooter *footer = [MJRefreshAutoGifFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; | |
| 239 | + | |
| 240 | +// Set the refresh image | |
| 241 | +[footer setImages:refreshingImages forState:MJRefreshStateRefreshing]; | |
| 242 | + | |
| 243 | +// Set footer | |
| 244 | +self.tableView.mj_footer = footer; | |
| 245 | +``` | |
| 246 | + | |
| 247 | + | |
| 248 | +## <a id="The_pull_to_refresh_03-Hide_the_title_of_refresh_status"></a>The pull to refresh 03-Hide the title of refresh status | |
| 249 | +```objc | |
| 250 | +// Hide the title of refresh status | |
| 251 | +footer.refreshingTitleHidden = YES; | |
| 252 | +// If does have not above method,then use footer.stateLabel.hidden = YES; | |
| 253 | +``` | |
| 254 | + | |
| 255 | + | |
| 256 | +## <a id="The_pull_to_refresh_04-All_loaded"></a>The pull to refresh 04-All loaded | |
| 257 | +```objc | |
| 258 | +//Become the status of NoMoreData | |
| 259 | +[footer noticeNoMoreData]; | |
| 260 | +``` | |
| 261 | + | |
| 262 | + | |
| 263 | +## <a id="The_pull_to_refresh_05-DIY_title"></a>The pull to refresh 05-DIY title | |
| 264 | +```objc | |
| 265 | +// Set title | |
| 266 | +[footer setTitle:@"Click or drag up to refresh" forState:MJRefreshStateIdle]; | |
| 267 | +[footer setTitle:@"Loading more ..." forState:MJRefreshStateRefreshing]; | |
| 268 | +[footer setTitle:@"No more data" forState:MJRefreshStateNoMoreData]; | |
| 269 | + | |
| 270 | +// Set font | |
| 271 | +footer.stateLabel.font = [UIFont systemFontOfSize:17]; | |
| 272 | + | |
| 273 | +// Set textColor | |
| 274 | +footer.stateLabel.textColor = [UIColor blueColor]; | |
| 275 | +``` | |
| 276 | + | |
| 277 | + | |
| 278 | +## <a id="The_pull_to_refresh_06-Hidden_After_loaded"></a>The pull to refresh 06-Hidden After loaded | |
| 279 | +```objc | |
| 280 | +//Hidden current control of the pull to refresh | |
| 281 | +self.tableView.mj_footer.hidden = YES; | |
| 282 | +``` | |
| 283 | + | |
| 284 | + | |
| 285 | +## <a id="The_pull_to_refresh_07-Automatic_back_of_the_pull01"></a>The pull to refresh 07-Automatic back of the pull01 | |
| 286 | +```objc | |
| 287 | +self.tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; | |
| 288 | +``` | |
| 289 | + | |
| 290 | + | |
| 291 | +## <a id="The_pull_to_refresh_08-Automatic_back_of_the_pull02"></a>The pull to refresh 08-Automatic back of the pull02 | |
| 292 | +```objc | |
| 293 | +MJRefreshBackGifFooter *footer = [MJRefreshBackGifFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; | |
| 294 | + | |
| 295 | +// Set the normal state of the animated image | |
| 296 | +[footer setImages:idleImages forState:MJRefreshStateIdle]; | |
| 297 | +// Set the pulling state of animated images(Enter the status of refreshing as soon as loosen) | |
| 298 | +[footer setImages:pullingImages forState:MJRefreshStatePulling]; | |
| 299 | +// Set the refreshing state of animated images | |
| 300 | +[footer setImages:refreshingImages forState:MJRefreshStateRefreshing]; | |
| 301 | + | |
| 302 | +// Set footer | |
| 303 | +self.tableView.mj_footer = footer; | |
| 304 | +``` | |
| 305 | + | |
| 306 | + | |
| 307 | +## <a id="The_pull_to_refresh_09-DIY_the_control_of_refresh(Automatic_refresh)"></a>The pull to refresh 09-DIY the control of refresh(Automatic refresh) | |
| 308 | +```objc | |
| 309 | +self.tableView.mj_footer = [MJDIYAutoFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; | |
| 310 | +// Implementation reference to MJDIYAutoFooter.h和MJDIYAutoFooter.m | |
| 311 | +``` | |
| 312 | + | |
| 313 | + | |
| 314 | +## <a id="The_pull_to_refresh_10-DIY_the_control_of_refresh(Automatic_back)"></a>The pull to refresh 10-DIY the control of refresh(Automatic back) | |
| 315 | +```objc | |
| 316 | +self.tableView.mj_footer = [MJDIYBackFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; | |
| 317 | +// Implementation reference to MJDIYBackFooter.h和MJDIYBackFooter.m | |
| 318 | +``` | |
| 319 | + | |
| 320 | + | |
| 321 | +## <a id="UICollectionView01-The_pull_and_drop-down_refresh"></a>UICollectionView01-The pull and drop-down refresh | |
| 322 | +```objc | |
| 323 | +// The drop-down refresh | |
| 324 | +self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ | |
| 325 | + //Call this Block When enter the refresh status automatically | |
| 326 | +}]; | |
| 327 | + | |
| 328 | +// The pull to refresh | |
| 329 | +self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ | |
| 330 | + //Call this Block When enter the refresh status automatically | |
| 331 | +}]; | |
| 332 | +``` | |
| 333 | + | |
| 334 | + | |
| 335 | +## <a id="UIWebView01-The_drop-down_refresh"></a>UIWebView01-The drop-down refresh | |
| 336 | +```objc | |
| 337 | +//Add the control of The drop-down refresh | |
| 338 | +self.webView.scrollView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ | |
| 339 | + //Call this Block When enter the refresh status automatically | |
| 340 | +}]; | |
| 341 | +``` | |
| 342 | + | |
| 343 | + | |
| 344 | +## Remind | |
| 345 | +* ARC | |
| 346 | +* iOS>=6.0 | |
| 347 | +* iPhone \ iPad screen anyway | |
| 348 | + | |
| 349 | +## <a id="Hope"></a>Hope | |
| 350 | +* If you find bug when used,Hope you can Issues me,Thank you or try to download the latest code of this framework to see the BUG has been fixed or not) | |
| 351 | +* If you find the function is not enough when used,Hope you can Issues me,I very much to add more useful function to this framework ,Thank you ! | |
| 352 | +* If you want to contribute code for MJRefresh,please Pull Requests me | |
| 353 | +* If you use MJRefresh in your develop app,Hope you can go to[CocoaControls](https://www.cocoacontrols.com/controls/mjrefresh)to add the iTunes path | |
| 354 | + of you app,I Will install your app,and according to the usage of many app,to be a better design and improve to MJRefresh,Thank you ! | |
| 355 | + * StepO1(WeChat is just an Example,Explore“Your app name itunes”) | |
| 356 | + | |
| 357 | + * StepO2 | |
| 358 | + | |
| 359 | + * StepO3 | |
| 360 | + | |
| 361 | + * StepO4 | |
| 362 | + | ... | ... |
Example/Pods/Manifest.lock
| 1 | 1 | PODS: |
| 2 | - - CNLiveRefeshHeader (0.1.0) | |
| 2 | + - CNLiveRefeshHeader (0.0.1): | |
| 3 | + - MJRefresh | |
| 4 | + - MJRefresh (3.1.15.7) | |
| 3 | 5 | |
| 4 | 6 | DEPENDENCIES: |
| 5 | 7 | - CNLiveRefeshHeader (from `../`) |
| 8 | + - MJRefresh | |
| 9 | + | |
| 10 | +SPEC REPOS: | |
| 11 | + https://github.com/cocoapods/specs.git: | |
| 12 | + - MJRefresh | |
| 6 | 13 | |
| 7 | 14 | EXTERNAL SOURCES: |
| 8 | 15 | CNLiveRefeshHeader: |
| 9 | 16 | :path: "../" |
| 10 | 17 | |
| 11 | 18 | SPEC CHECKSUMS: |
| 12 | - CNLiveRefeshHeader: d965f2b85e9e7780987a403011aa2bc1ef39699a | |
| 19 | + CNLiveRefeshHeader: 02f3d68e758397c04a98dcf8be0141ff1a8f2874 | |
| 20 | + MJRefresh: 697f8ec75ebdbe9207767bb682cf0f51b0d8a41f | |
| 13 | 21 | |
| 14 | -PODFILE CHECKSUM: 23844f68fff15c2b9e865816ca034e39a4d9cd02 | |
| 22 | +PODFILE CHECKSUM: 813baa37d96ee543acda9928f20b522a49de2526 | |
| 15 | 23 | |
| 16 | 24 | COCOAPODS: 1.5.3 | ... | ... |
Example/Pods/Pods.xcodeproj/project.pbxproj
| ... | ... | @@ -10,11 +10,12 @@ |
| 10 | 10 | 1AFEDE050289F8423445C7EE3ED46E53 /* CNLiveRefeshHeader-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 408E1AB9DE1963AD612445B5D06DE48A /* CNLiveRefeshHeader-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; |
| 11 | 11 | 1B71CEB9084B7CBDDEF73AC67B25AFC8 /* Pods-CNLiveRefeshHeader_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 45280C83DE3CCB21D16A29C984C44C50 /* Pods-CNLiveRefeshHeader_Example-dummy.m */; }; |
| 12 | 12 | 31217648E93FBA89420BEB6BEBC12BED /* Pods-CNLiveRefeshHeader_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DACCBE2360FDD56F51FBD33D66714AC /* Pods-CNLiveRefeshHeader_Tests-dummy.m */; }; |
| 13 | + 4E54F4E721BA572F00147A02 /* Test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E54F4E521BA572F00147A02 /* Test.h */; }; | |
| 14 | + 4E54F4E821BA572F00147A02 /* Test.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E54F4E621BA572F00147A02 /* Test.m */; }; | |
| 13 | 15 | A5D0BFB0B4F725058948A0C91436AF33 /* Pods-CNLiveRefeshHeader_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A2092D08C14CC084F39FCC1BADE5677 /* Pods-CNLiveRefeshHeader_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; |
| 14 | 16 | B42AC0AEE0897F50B6A081801ED7D041 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */; }; |
| 15 | 17 | B7D5680A0E98DC779A6B69F3A2076C26 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */; }; |
| 16 | 18 | CC82AA404C5385317B5D3D3E9A639BE2 /* Pods-CNLiveRefeshHeader_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F4BE943D5EEB79C815665DFC1290F216 /* Pods-CNLiveRefeshHeader_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; |
| 17 | - CEBE41FBE05D1988A34E4D8804745561 /* ReplaceMe.m in Sources */ = {isa = PBXBuildFile; fileRef = 995B671A4B20783098A16B435975C2E7 /* ReplaceMe.m */; }; | |
| 18 | 19 | F0BAD53A2DD29DCC096FA01296BF5F2D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */; }; |
| 19 | 20 | FB756861879D570F282804379667DC07 /* CNLiveRefeshHeader-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 27195245C8C4AFDC2A2E6681068F3C1B /* CNLiveRefeshHeader-dummy.m */; }; |
| 20 | 21 | /* End PBXBuildFile section */ |
| ... | ... | @@ -41,37 +42,38 @@ |
| 41 | 42 | 15A00EF31E316ADC5E75D1275C49F780 /* CNLiveRefeshHeader.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNLiveRefeshHeader.xcconfig; sourceTree = "<group>"; }; |
| 42 | 43 | 27195245C8C4AFDC2A2E6681068F3C1B /* CNLiveRefeshHeader-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNLiveRefeshHeader-dummy.m"; sourceTree = "<group>"; }; |
| 43 | 44 | 296B9241B63A7B0A020A2D4707D3ED1F /* Pods-CNLiveRefeshHeader_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CNLiveRefeshHeader_Example-resources.sh"; sourceTree = "<group>"; }; |
| 44 | - 31C8C5D7B10F1AA358FB51255205E179 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = "<group>"; }; | |
| 45 | + 31C8C5D7B10F1AA358FB51255205E179 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; | |
| 45 | 46 | 3DACCBE2360FDD56F51FBD33D66714AC /* Pods-CNLiveRefeshHeader_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CNLiveRefeshHeader_Tests-dummy.m"; sourceTree = "<group>"; }; |
| 46 | 47 | 408E1AB9DE1963AD612445B5D06DE48A /* CNLiveRefeshHeader-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNLiveRefeshHeader-umbrella.h"; sourceTree = "<group>"; }; |
| 47 | 48 | 41D4F78223A708752C8676A6D9A66FE6 /* CNLiveRefeshHeader.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNLiveRefeshHeader.modulemap; sourceTree = "<group>"; }; |
| 48 | 49 | 45280C83DE3CCB21D16A29C984C44C50 /* Pods-CNLiveRefeshHeader_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CNLiveRefeshHeader_Example-dummy.m"; sourceTree = "<group>"; }; |
| 50 | + 4E54F4E521BA572F00147A02 /* Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Test.h; sourceTree = "<group>"; }; | |
| 51 | + 4E54F4E621BA572F00147A02 /* Test.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Test.m; sourceTree = "<group>"; }; | |
| 49 | 52 | 569D0822A3A489A714290FCF8E3D23F1 /* Pods-CNLiveRefeshHeader_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CNLiveRefeshHeader_Tests-acknowledgements.markdown"; sourceTree = "<group>"; }; |
| 50 | 53 | 57FDAF38D5872821D616762F3B219849 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; |
| 51 | 54 | 67E2FCD38C5119A23D68D4F1F75E9C3E /* Pods-CNLiveRefeshHeader_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CNLiveRefeshHeader_Example-acknowledgements.markdown"; sourceTree = "<group>"; }; |
| 52 | - 6985F16B0950B9EC7F9C5694904E5EB6 /* Pods_CNLiveRefeshHeader_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_CNLiveRefeshHeader_Example.framework; path = "Pods-CNLiveRefeshHeader_Example.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; | |
| 55 | + 6985F16B0950B9EC7F9C5694904E5EB6 /* Pods_CNLiveRefeshHeader_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveRefeshHeader_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | |
| 53 | 56 | 7A2092D08C14CC084F39FCC1BADE5677 /* Pods-CNLiveRefeshHeader_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-CNLiveRefeshHeader_Tests-umbrella.h"; sourceTree = "<group>"; }; |
| 54 | - 832AB082C54610BAB962ADC2054E6F08 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = "<group>"; }; | |
| 57 | + 832AB082C54610BAB962ADC2054E6F08 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; | |
| 55 | 58 | 8EBDD8A39E384A7E3FEB1D14C0052127 /* Pods-CNLiveRefeshHeader_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CNLiveRefeshHeader_Tests-acknowledgements.plist"; sourceTree = "<group>"; }; |
| 56 | - 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; | |
| 59 | + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; | |
| 57 | 60 | 949B3C1084384A451A0E6354D7A84B75 /* Pods-CNLiveRefeshHeader_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CNLiveRefeshHeader_Tests-frameworks.sh"; sourceTree = "<group>"; }; |
| 58 | - 995B671A4B20783098A16B435975C2E7 /* ReplaceMe.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ReplaceMe.m; path = CNLiveRefeshHeader/Classes/ReplaceMe.m; sourceTree = "<group>"; }; | |
| 59 | 61 | 9A207069880DBF05D62E96DC84DB5E28 /* Pods-CNLiveRefeshHeader_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CNLiveRefeshHeader_Example.debug.xcconfig"; sourceTree = "<group>"; }; |
| 60 | 62 | A03397A77C4B3987BE7A4C4F37334C70 /* Pods-CNLiveRefeshHeader_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CNLiveRefeshHeader_Tests.release.xcconfig"; sourceTree = "<group>"; }; |
| 61 | 63 | A7EFADFB6F36DFD8AE7AB8E6AB233EB4 /* Pods-CNLiveRefeshHeader_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CNLiveRefeshHeader_Example-frameworks.sh"; sourceTree = "<group>"; }; |
| 62 | 64 | AC4DFBD98943B8CFABE697F31B4741AD /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; |
| 63 | 65 | AF23A19215E0E3C98154F3C99F8A68D2 /* Pods-CNLiveRefeshHeader_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CNLiveRefeshHeader_Tests.debug.xcconfig"; sourceTree = "<group>"; }; |
| 64 | - BB7AE680646F6E8ECCC3BF02D9414F7D /* CNLiveRefeshHeader.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; path = CNLiveRefeshHeader.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; | |
| 66 | + BB7AE680646F6E8ECCC3BF02D9414F7D /* CNLiveRefeshHeader.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; path = CNLiveRefeshHeader.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; | |
| 65 | 67 | C3B79BD8E72617C5093ADFB65F3D3797 /* Pods-CNLiveRefeshHeader_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CNLiveRefeshHeader_Example-acknowledgements.plist"; sourceTree = "<group>"; }; |
| 66 | 68 | CC7B5D082FA2C3C56A9351ED6CC864F5 /* Pods-CNLiveRefeshHeader_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CNLiveRefeshHeader_Tests-resources.sh"; sourceTree = "<group>"; }; |
| 67 | 69 | CD3B3DD164ECE6AA94C83D58D73CCA08 /* Pods-CNLiveRefeshHeader_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-CNLiveRefeshHeader_Tests.modulemap"; sourceTree = "<group>"; }; |
| 68 | 70 | D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; |
| 69 | 71 | D89D318A1539A61EBDF3F4D05D928E6F /* Pods-CNLiveRefeshHeader_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-CNLiveRefeshHeader_Example.modulemap"; sourceTree = "<group>"; }; |
| 70 | 72 | DB790E63B1EAE48265C6D9D2769574C8 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; |
| 71 | - E66507C7CD0275F0874123F6E9B5C66B /* CNLiveRefeshHeader.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNLiveRefeshHeader.framework; path = CNLiveRefeshHeader.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | |
| 73 | + E66507C7CD0275F0874123F6E9B5C66B /* CNLiveRefeshHeader.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CNLiveRefeshHeader.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | |
| 72 | 74 | EEA71030B18BDC9EE413A38CDFD28100 /* Pods-CNLiveRefeshHeader_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CNLiveRefeshHeader_Example.release.xcconfig"; sourceTree = "<group>"; }; |
| 73 | 75 | F4BE943D5EEB79C815665DFC1290F216 /* Pods-CNLiveRefeshHeader_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-CNLiveRefeshHeader_Example-umbrella.h"; sourceTree = "<group>"; }; |
| 74 | - FC332EE508A07A3876D292E155D42374 /* Pods_CNLiveRefeshHeader_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_CNLiveRefeshHeader_Tests.framework; path = "Pods-CNLiveRefeshHeader_Tests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; | |
| 76 | + FC332EE508A07A3876D292E155D42374 /* Pods_CNLiveRefeshHeader_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveRefeshHeader_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | |
| 75 | 77 | /* End PBXFileReference section */ |
| 76 | 78 | |
| 77 | 79 | /* Begin PBXFrameworksBuildPhase section */ |
| ... | ... | @@ -105,7 +107,7 @@ |
| 105 | 107 | 02AB48A1EAE23330465313D2A5FBBE15 /* CNLiveRefeshHeader */ = { |
| 106 | 108 | isa = PBXGroup; |
| 107 | 109 | children = ( |
| 108 | - 995B671A4B20783098A16B435975C2E7 /* ReplaceMe.m */, | |
| 110 | + 4E54F4DA21BA55F200147A02 /* CNLiveRefeshHeader */, | |
| 109 | 111 | C7618EF45631102F5F74034A0C1E0BDC /* Pod */, |
| 110 | 112 | 3265C484033B708B406087F157CA3500 /* Support Files */, |
| 111 | 113 | ); |
| ... | ... | @@ -135,6 +137,31 @@ |
| 135 | 137 | name = iOS; |
| 136 | 138 | sourceTree = "<group>"; |
| 137 | 139 | }; |
| 140 | + 4E54F4DA21BA55F200147A02 /* CNLiveRefeshHeader */ = { | |
| 141 | + isa = PBXGroup; | |
| 142 | + children = ( | |
| 143 | + 4E54F4DB21BA55F200147A02 /* Classes */, | |
| 144 | + 4E54F4DF21BA55F200147A02 /* Assets */, | |
| 145 | + ); | |
| 146 | + path = CNLiveRefeshHeader; | |
| 147 | + sourceTree = "<group>"; | |
| 148 | + }; | |
| 149 | + 4E54F4DB21BA55F200147A02 /* Classes */ = { | |
| 150 | + isa = PBXGroup; | |
| 151 | + children = ( | |
| 152 | + 4E54F4E521BA572F00147A02 /* Test.h */, | |
| 153 | + 4E54F4E621BA572F00147A02 /* Test.m */, | |
| 154 | + ); | |
| 155 | + path = Classes; | |
| 156 | + sourceTree = "<group>"; | |
| 157 | + }; | |
| 158 | + 4E54F4DF21BA55F200147A02 /* Assets */ = { | |
| 159 | + isa = PBXGroup; | |
| 160 | + children = ( | |
| 161 | + ); | |
| 162 | + path = Assets; | |
| 163 | + sourceTree = "<group>"; | |
| 164 | + }; | |
| 138 | 165 | 51BF3A1EB4E1530EDD4FCEEDE244F515 /* Pods-CNLiveRefeshHeader_Example */ = { |
| 139 | 166 | isa = PBXGroup; |
| 140 | 167 | children = ( |
| ... | ... | @@ -242,6 +269,7 @@ |
| 242 | 269 | isa = PBXHeadersBuildPhase; |
| 243 | 270 | buildActionMask = 2147483647; |
| 244 | 271 | files = ( |
| 272 | + 4E54F4E721BA572F00147A02 /* Test.h in Headers */, | |
| 245 | 273 | 1AFEDE050289F8423445C7EE3ED46E53 /* CNLiveRefeshHeader-umbrella.h in Headers */, |
| 246 | 274 | ); |
| 247 | 275 | runOnlyForDeploymentPostprocessing = 0; |
| ... | ... | @@ -371,7 +399,7 @@ |
| 371 | 399 | buildActionMask = 2147483647; |
| 372 | 400 | files = ( |
| 373 | 401 | FB756861879D570F282804379667DC07 /* CNLiveRefeshHeader-dummy.m in Sources */, |
| 374 | - CEBE41FBE05D1988A34E4D8804745561 /* ReplaceMe.m in Sources */, | |
| 402 | + 4E54F4E821BA572F00147A02 /* Test.m in Sources */, | |
| 375 | 403 | ); |
| 376 | 404 | runOnlyForDeploymentPostprocessing = 0; |
| 377 | 405 | }; |
| ... | ... | @@ -528,8 +556,7 @@ |
| 528 | 556 | MTL_FAST_MATH = YES; |
| 529 | 557 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 530 | 558 | STRIP_INSTALLED_PRODUCT = NO; |
| 531 | - SWIFT_COMPILATION_MODE = wholemodule; | |
| 532 | - SWIFT_OPTIMIZATION_LEVEL = "-O"; | |
| 559 | + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; | |
| 533 | 560 | SWIFT_VERSION = 4.2; |
| 534 | 561 | SYMROOT = "${SRCROOT}/../build"; |
| 535 | 562 | }; | ... | ... |
Example/Pods/Target Support Files/CNLiveRefeshHeader/CNLiveRefeshHeader-umbrella.h
Example/Pods/Target Support Files/CNLiveRefeshHeader/CNLiveRefeshHeader.xcconfig
| 1 | 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader |
| 2 | +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" | |
| 2 | 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 |
| 4 | +OTHER_LDFLAGS = -framework "Foundation" -framework "UIKit" | |
| 3 | 5 | PODS_BUILD_DIR = ${BUILD_DIR} |
| 4 | 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) |
| 5 | 7 | PODS_ROOT = ${SRCROOT} | ... | ... |
Example/Pods/Target Support Files/CNLiveRefeshHeader/Info.plist
Example/Pods/Target Support Files/MJRefresh/Info.plist
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| 3 | +<plist version="1.0"> | |
| 4 | +<dict> | |
| 5 | + <key>CFBundleDevelopmentRegion</key> | |
| 6 | + <string>en</string> | |
| 7 | + <key>CFBundleExecutable</key> | |
| 8 | + <string>${EXECUTABLE_NAME}</string> | |
| 9 | + <key>CFBundleIdentifier</key> | |
| 10 | + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> | |
| 11 | + <key>CFBundleInfoDictionaryVersion</key> | |
| 12 | + <string>6.0</string> | |
| 13 | + <key>CFBundleName</key> | |
| 14 | + <string>${PRODUCT_NAME}</string> | |
| 15 | + <key>CFBundlePackageType</key> | |
| 16 | + <string>FMWK</string> | |
| 17 | + <key>CFBundleShortVersionString</key> | |
| 18 | + <string>3.1.15</string> | |
| 19 | + <key>CFBundleSignature</key> | |
| 20 | + <string>????</string> | |
| 21 | + <key>CFBundleVersion</key> | |
| 22 | + <string>${CURRENT_PROJECT_VERSION}</string> | |
| 23 | + <key>NSPrincipalClass</key> | |
| 24 | + <string></string> | |
| 25 | +</dict> | |
| 26 | +</plist> | ... | ... |
Example/Pods/Target Support Files/MJRefresh/MJRefresh-dummy.m
0 → 100644
Example/Pods/Target Support Files/MJRefresh/MJRefresh-prefix.pch
0 → 100644
Example/Pods/Target Support Files/MJRefresh/MJRefresh-umbrella.h
0 → 100644
| 1 | +#ifdef __OBJC__ | |
| 2 | +#import <UIKit/UIKit.h> | |
| 3 | +#else | |
| 4 | +#ifndef FOUNDATION_EXPORT | |
| 5 | +#if defined(__cplusplus) | |
| 6 | +#define FOUNDATION_EXPORT extern "C" | |
| 7 | +#else | |
| 8 | +#define FOUNDATION_EXPORT extern | |
| 9 | +#endif | |
| 10 | +#endif | |
| 11 | +#endif | |
| 12 | + | |
| 13 | +#import "MJRefreshAutoFooter.h" | |
| 14 | +#import "MJRefreshBackFooter.h" | |
| 15 | +#import "MJRefreshComponent.h" | |
| 16 | +#import "MJRefreshFooter.h" | |
| 17 | +#import "MJRefreshHeader.h" | |
| 18 | +#import "MJRefreshAutoGifFooter.h" | |
| 19 | +#import "MJRefreshAutoNormalFooter.h" | |
| 20 | +#import "MJRefreshAutoStateFooter.h" | |
| 21 | +#import "MJRefreshBackGifFooter.h" | |
| 22 | +#import "MJRefreshBackNormalFooter.h" | |
| 23 | +#import "MJRefreshBackStateFooter.h" | |
| 24 | +#import "MJRefreshGifHeader.h" | |
| 25 | +#import "MJRefreshNormalHeader.h" | |
| 26 | +#import "MJRefreshStateHeader.h" | |
| 27 | +#import "MJRefresh.h" | |
| 28 | +#import "MJRefreshConst.h" | |
| 29 | +#import "NSBundle+MJRefresh.h" | |
| 30 | +#import "UIScrollView+MJExtension.h" | |
| 31 | +#import "UIScrollView+MJRefresh.h" | |
| 32 | +#import "UIView+MJExtension.h" | |
| 33 | + | |
| 34 | +FOUNDATION_EXPORT double MJRefreshVersionNumber; | |
| 35 | +FOUNDATION_EXPORT const unsigned char MJRefreshVersionString[]; | |
| 36 | + | ... | ... |
Example/Pods/Target Support Files/MJRefresh/MJRefresh.modulemap
0 → 100644
Example/Pods/Target Support Files/MJRefresh/MJRefresh.xcconfig
0 → 100644
| 1 | +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh | |
| 2 | +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 | |
| 3 | +PODS_BUILD_DIR = ${BUILD_DIR} | |
| 4 | +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) | |
| 5 | +PODS_ROOT = ${SRCROOT} | |
| 6 | +PODS_TARGET_SRCROOT = ${PODS_ROOT}/MJRefresh | |
| 7 | +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} | |
| 8 | +SKIP_INSTALL = YES | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example-acknowledgements.markdown
| ... | ... | @@ -23,4 +23,27 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 23 | 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 24 | 24 | THE SOFTWARE. |
| 25 | 25 | |
| 26 | + | |
| 27 | +## MJRefresh | |
| 28 | + | |
| 29 | +Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) | |
| 30 | + | |
| 31 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 32 | +of this software and associated documentation files (the "Software"), to deal | |
| 33 | +in the Software without restriction, including without limitation the rights | |
| 34 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 35 | +copies of the Software, and to permit persons to whom the Software is | |
| 36 | +furnished to do so, subject to the following conditions: | |
| 37 | + | |
| 38 | +The above copyright notice and this permission notice shall be included in | |
| 39 | +all copies or substantial portions of the Software. | |
| 40 | + | |
| 41 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 42 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 43 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 44 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 45 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 46 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 47 | +THE SOFTWARE. | |
| 48 | + | |
| 26 | 49 | Generated by CocoaPods - https://cocoapods.org | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example-acknowledgements.plist
| ... | ... | @@ -43,6 +43,35 @@ THE SOFTWARE. |
| 43 | 43 | </dict> |
| 44 | 44 | <dict> |
| 45 | 45 | <key>FooterText</key> |
| 46 | + <string>Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) | |
| 47 | + | |
| 48 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 49 | +of this software and associated documentation files (the "Software"), to deal | |
| 50 | +in the Software without restriction, including without limitation the rights | |
| 51 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 52 | +copies of the Software, and to permit persons to whom the Software is | |
| 53 | +furnished to do so, subject to the following conditions: | |
| 54 | + | |
| 55 | +The above copyright notice and this permission notice shall be included in | |
| 56 | +all copies or substantial portions of the Software. | |
| 57 | + | |
| 58 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 59 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 60 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 61 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 62 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 63 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 64 | +THE SOFTWARE. | |
| 65 | +</string> | |
| 66 | + <key>License</key> | |
| 67 | + <string>MIT</string> | |
| 68 | + <key>Title</key> | |
| 69 | + <string>MJRefresh</string> | |
| 70 | + <key>Type</key> | |
| 71 | + <string>PSGroupSpecifier</string> | |
| 72 | + </dict> | |
| 73 | + <dict> | |
| 74 | + <key>FooterText</key> | |
| 46 | 75 | <string>Generated by CocoaPods - https://cocoapods.org</string> |
| 47 | 76 | <key>Title</key> |
| 48 | 77 | <string></string> | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example-frameworks.sh
| ... | ... | @@ -144,9 +144,11 @@ strip_invalid_archs() { |
| 144 | 144 | |
| 145 | 145 | if [[ "$CONFIGURATION" == "Debug" ]]; then |
| 146 | 146 | install_framework "${BUILT_PRODUCTS_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework" |
| 147 | + install_framework "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework" | |
| 147 | 148 | fi |
| 148 | 149 | if [[ "$CONFIGURATION" == "Release" ]]; then |
| 149 | 150 | install_framework "${BUILT_PRODUCTS_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework" |
| 151 | + install_framework "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework" | |
| 150 | 152 | fi |
| 151 | 153 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then |
| 152 | 154 | wait | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example.debug.xcconfig
| 1 | -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" | |
| 1 | +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" | |
| 2 | 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 |
| 3 | 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' |
| 4 | -OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" | |
| 5 | -OTHER_LDFLAGS = $(inherited) -framework "CNLiveRefeshHeader" | |
| 4 | +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" | |
| 5 | +OTHER_LDFLAGS = $(inherited) -framework "CNLiveRefeshHeader" -framework "MJRefresh" | |
| 6 | 6 | PODS_BUILD_DIR = ${BUILD_DIR} |
| 7 | 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) |
| 8 | 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Example/Pods-CNLiveRefeshHeader_Example.release.xcconfig
| 1 | -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" | |
| 1 | +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" | |
| 2 | 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 |
| 3 | 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' |
| 4 | -OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" | |
| 5 | -OTHER_LDFLAGS = $(inherited) -framework "CNLiveRefeshHeader" | |
| 4 | +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" | |
| 5 | +OTHER_LDFLAGS = $(inherited) -framework "CNLiveRefeshHeader" -framework "MJRefresh" | |
| 6 | 6 | PODS_BUILD_DIR = ${BUILD_DIR} |
| 7 | 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) |
| 8 | 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests-acknowledgements.markdown
| 1 | 1 | # Acknowledgements |
| 2 | 2 | This application makes use of the following third party libraries: |
| 3 | + | |
| 4 | +## MJRefresh | |
| 5 | + | |
| 6 | +Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) | |
| 7 | + | |
| 8 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 9 | +of this software and associated documentation files (the "Software"), to deal | |
| 10 | +in the Software without restriction, including without limitation the rights | |
| 11 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 12 | +copies of the Software, and to permit persons to whom the Software is | |
| 13 | +furnished to do so, subject to the following conditions: | |
| 14 | + | |
| 15 | +The above copyright notice and this permission notice shall be included in | |
| 16 | +all copies or substantial portions of the Software. | |
| 17 | + | |
| 18 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 21 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 23 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 24 | +THE SOFTWARE. | |
| 25 | + | |
| 3 | 26 | Generated by CocoaPods - https://cocoapods.org | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests-acknowledgements.plist
| ... | ... | @@ -14,6 +14,35 @@ |
| 14 | 14 | </dict> |
| 15 | 15 | <dict> |
| 16 | 16 | <key>FooterText</key> |
| 17 | + <string>Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) | |
| 18 | + | |
| 19 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 20 | +of this software and associated documentation files (the "Software"), to deal | |
| 21 | +in the Software without restriction, including without limitation the rights | |
| 22 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 23 | +copies of the Software, and to permit persons to whom the Software is | |
| 24 | +furnished to do so, subject to the following conditions: | |
| 25 | + | |
| 26 | +The above copyright notice and this permission notice shall be included in | |
| 27 | +all copies or substantial portions of the Software. | |
| 28 | + | |
| 29 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 30 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 31 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 32 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 33 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 34 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 35 | +THE SOFTWARE. | |
| 36 | +</string> | |
| 37 | + <key>License</key> | |
| 38 | + <string>MIT</string> | |
| 39 | + <key>Title</key> | |
| 40 | + <string>MJRefresh</string> | |
| 41 | + <key>Type</key> | |
| 42 | + <string>PSGroupSpecifier</string> | |
| 43 | + </dict> | |
| 44 | + <dict> | |
| 45 | + <key>FooterText</key> | |
| 17 | 46 | <string>Generated by CocoaPods - https://cocoapods.org</string> |
| 18 | 47 | <key>Title</key> |
| 19 | 48 | <string></string> | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests-frameworks.sh
| ... | ... | @@ -141,6 +141,13 @@ strip_invalid_archs() { |
| 141 | 141 | STRIP_BINARY_RETVAL=1 |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | + | |
| 145 | +if [[ "$CONFIGURATION" == "Debug" ]]; then | |
| 146 | + install_framework "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework" | |
| 147 | +fi | |
| 148 | +if [[ "$CONFIGURATION" == "Release" ]]; then | |
| 149 | + install_framework "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework" | |
| 150 | +fi | |
| 144 | 151 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then |
| 145 | 152 | wait |
| 146 | 153 | fi | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests.debug.xcconfig
| 1 | -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" | |
| 1 | +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" | |
| 2 | 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 |
| 3 | 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' |
| 4 | -OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" | |
| 4 | +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" | |
| 5 | +OTHER_LDFLAGS = $(inherited) -framework "MJRefresh" | |
| 5 | 6 | PODS_BUILD_DIR = ${BUILD_DIR} |
| 6 | 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) |
| 7 | 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. | ... | ... |
Example/Pods/Target Support Files/Pods-CNLiveRefeshHeader_Tests/Pods-CNLiveRefeshHeader_Tests.release.xcconfig
| 1 | -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" | |
| 1 | +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" | |
| 2 | 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 |
| 3 | 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' |
| 4 | -OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" | |
| 4 | +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveRefeshHeader/CNLiveRefeshHeader.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" | |
| 5 | +OTHER_LDFLAGS = $(inherited) -framework "MJRefresh" | |
| 5 | 6 | PODS_BUILD_DIR = ${BUILD_DIR} |
| 6 | 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) |
| 7 | 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. | ... | ... |