Commit 45be73fe cgx

移除ZFPlayer

1 个父辈 cd31c8f9
正在显示 54 个修改的文件 包含 11 行增加3313 行删除
......@@ -7,7 +7,6 @@
#import "MusicPlayerController.h"
#import "MusicPlayerView.h"
#import <ZFPlayer/ZFPlayer.h>
@interface MusicPlayerController ()
@property (nonatomic, strong) MusicPlayerView *playerView;
......
......@@ -12,7 +12,6 @@ target 'DreamSleep' do
pod 'YYWebImage', '~> 1.0.5'
pod 'YYImage/WebP'
pod 'YYModel', '~> 1.0.4'
pod 'ZFPlayer', '~> 4.0.3'
end
# AFNetworking (4.0.1)
......@@ -27,4 +26,3 @@ end
# YYImage/WebP(模拟器上目前无法运行)
# YYModel (1.0.4)
# SDWebImage (5.12.5)(去掉)
# ZFPlayer(4.0.3)
......@@ -36,9 +36,6 @@ PODS:
- YYWebImage (1.0.5):
- YYCache
- YYImage
- ZFPlayer (4.0.3):
- ZFPlayer/Core (= 4.0.3)
- ZFPlayer/Core (4.0.3)
DEPENDENCIES:
- DKNightVersion (~> 2.4.3)
......@@ -51,7 +48,6 @@ DEPENDENCIES:
- YYImage/WebP
- YYModel (~> 1.0.4)
- YYWebImage (~> 1.0.5)
- ZFPlayer (~> 4.0.3)
SPEC REPOS:
trunk:
......@@ -67,7 +63,6 @@ SPEC REPOS:
- YYImage
- YYModel
- YYWebImage
- ZFPlayer
SPEC CHECKSUMS:
AFNetworking: 7864c38297c79aaca1500c33288e429c3451fdce
......@@ -82,8 +77,7 @@ SPEC CHECKSUMS:
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
ZFPlayer: 624c92de06eb34df322c3b53b4c9ce760f528f7a
PODFILE CHECKSUM: ebcc67379940f6d7de396520351e58af5c93d8cb
PODFILE CHECKSUM: 5f273d0f03f58db41d7f0a6d3d96a8bd054ab744
COCOAPODS: 1.11.3
......@@ -36,9 +36,6 @@ PODS:
- YYWebImage (1.0.5):
- YYCache
- YYImage
- ZFPlayer (4.0.3):
- ZFPlayer/Core (= 4.0.3)
- ZFPlayer/Core (4.0.3)
DEPENDENCIES:
- DKNightVersion (~> 2.4.3)
......@@ -51,7 +48,6 @@ DEPENDENCIES:
- YYImage/WebP
- YYModel (~> 1.0.4)
- YYWebImage (~> 1.0.5)
- ZFPlayer (~> 4.0.3)
SPEC REPOS:
trunk:
......@@ -67,7 +63,6 @@ SPEC REPOS:
- YYImage
- YYModel
- YYWebImage
- ZFPlayer
SPEC CHECKSUMS:
AFNetworking: 7864c38297c79aaca1500c33288e429c3451fdce
......@@ -82,8 +77,7 @@ SPEC CHECKSUMS:
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
ZFPlayer: 624c92de06eb34df322c3b53b4c9ce760f528f7a
PODFILE CHECKSUM: ebcc67379940f6d7de396520351e58af5c93d8cb
PODFILE CHECKSUM: 5f273d0f03f58db41d7f0a6d3d96a8bd054ab744
COCOAPODS: 1.11.3
......@@ -279,29 +279,6 @@ SOFTWARE.
## ZFPlayer
Copyright (c) 2018 renzifeng <zifeng1300@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## lottie-ios
Apache License
......
......@@ -358,35 +358,6 @@ SOFTWARE.
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2018 renzifeng &lt;zifeng1300@gmail.com&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>ZFPlayer</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string> Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
......
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_ROOT}/YYImage/Vendor"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_ROOT}/YYImage/Vendor"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion/DKNightVersion.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer/DOUAudioStreamer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork/YTKNetwork.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer/ZFPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.framework/Headers"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion/DKNightVersion.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer/DOUAudioStreamer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork/YTKNetwork.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -ObjC -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AssetsLibrary" -framework "AudioToolbox" -framework "CFNetwork" -framework "CoreAudio" -framework "CoreFoundation" -framework "CoreGraphics" -framework "DKNightVersion" -framework "DOUAudioStreamer" -framework "Foundation" -framework "ImageIO" -framework "Lottie" -framework "MBProgressHUD" -framework "MJRefresh" -framework "Masonry" -framework "MediaPlayer" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "UIKit" -framework "YTKNetwork" -framework "YYCache" -framework "YYImage" -framework "YYModel" -framework "YYWebImage" -framework "ZFPlayer"
OTHER_LDFLAGS = $(inherited) -ObjC -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AssetsLibrary" -framework "AudioToolbox" -framework "CFNetwork" -framework "CoreAudio" -framework "CoreFoundation" -framework "CoreGraphics" -framework "DKNightVersion" -framework "DOUAudioStreamer" -framework "Foundation" -framework "ImageIO" -framework "Lottie" -framework "MBProgressHUD" -framework "MJRefresh" -framework "Masonry" -framework "MediaPlayer" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "UIKit" -framework "YTKNetwork" -framework "YYCache" -framework "YYImage" -framework "YYModel" -framework "YYWebImage"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
......
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_ROOT}/YYImage/Vendor"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_ROOT}/YYImage/Vendor"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion/DKNightVersion.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer/DOUAudioStreamer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork/YTKNetwork.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer/ZFPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.framework/Headers"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion/DKNightVersion.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer/DOUAudioStreamer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork/YTKNetwork.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -ObjC -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AssetsLibrary" -framework "AudioToolbox" -framework "CFNetwork" -framework "CoreAudio" -framework "CoreFoundation" -framework "CoreGraphics" -framework "DKNightVersion" -framework "DOUAudioStreamer" -framework "Foundation" -framework "ImageIO" -framework "Lottie" -framework "MBProgressHUD" -framework "MJRefresh" -framework "Masonry" -framework "MediaPlayer" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "UIKit" -framework "YTKNetwork" -framework "YYCache" -framework "YYImage" -framework "YYModel" -framework "YYWebImage" -framework "ZFPlayer"
OTHER_LDFLAGS = $(inherited) -ObjC -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AssetsLibrary" -framework "AudioToolbox" -framework "CFNetwork" -framework "CoreAudio" -framework "CoreFoundation" -framework "CoreGraphics" -framework "DKNightVersion" -framework "DOUAudioStreamer" -framework "Foundation" -framework "ImageIO" -framework "Lottie" -framework "MBProgressHUD" -framework "MJRefresh" -framework "Masonry" -framework "MediaPlayer" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "UIKit" -framework "YTKNetwork" -framework "YYCache" -framework "YYImage" -framework "YYModel" -framework "YYWebImage"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
......
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_ROOT}/YYImage/Vendor"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_ROOT}/YYImage/Vendor"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion/DKNightVersion.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer/DOUAudioStreamer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork/YTKNetwork.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer/ZFPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.framework/Headers"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DKNightVersion/DKNightVersion.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DOUAudioStreamer/DOUAudioStreamer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YTKNetwork/YTKNetwork.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios/Lottie.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -ObjC -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AssetsLibrary" -framework "AudioToolbox" -framework "CFNetwork" -framework "CoreAudio" -framework "CoreFoundation" -framework "CoreGraphics" -framework "DKNightVersion" -framework "DOUAudioStreamer" -framework "Foundation" -framework "ImageIO" -framework "Lottie" -framework "MBProgressHUD" -framework "MJRefresh" -framework "Masonry" -framework "MediaPlayer" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "UIKit" -framework "YTKNetwork" -framework "YYCache" -framework "YYImage" -framework "YYModel" -framework "YYWebImage" -framework "ZFPlayer"
OTHER_LDFLAGS = $(inherited) -ObjC -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AssetsLibrary" -framework "AudioToolbox" -framework "CFNetwork" -framework "CoreAudio" -framework "CoreFoundation" -framework "CoreGraphics" -framework "DKNightVersion" -framework "DOUAudioStreamer" -framework "Foundation" -framework "ImageIO" -framework "Lottie" -framework "MBProgressHUD" -framework "MJRefresh" -framework "Masonry" -framework "MediaPlayer" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "UIKit" -framework "YTKNetwork" -framework "YYCache" -framework "YYImage" -framework "YYModel" -framework "YYWebImage"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.0.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_ZFPlayer : NSObject
@end
@implementation PodsDummy_ZFPlayer
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#import "UIScrollView+ZFPlayer.h"
#import "ZFFloatView.h"
#import "ZFKVOController.h"
#import "ZFLandscapeViewController.h"
#import "ZFLandscapeWindow.h"
#import "ZFOrientationObserver.h"
#import "ZFPersentInteractiveTransition.h"
#import "ZFPlayer.h"
#import "ZFPlayerConst.h"
#import "ZFPlayerController.h"
#import "ZFPlayerGestureControl.h"
#import "ZFPlayerLogManager.h"
#import "ZFPlayerMediaControl.h"
#import "ZFPlayerMediaPlayback.h"
#import "ZFPlayerNotification.h"
#import "ZFPlayerView.h"
#import "ZFPortraitViewController.h"
#import "ZFPresentTransition.h"
#import "ZFReachabilityManager.h"
FOUNDATION_EXPORT double ZFPlayerVersionNumber;
FOUNDATION_EXPORT const unsigned char ZFPlayerVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/ZFPlayer
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module ZFPlayer {
umbrella header "ZFPlayer-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ZFPlayer
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/ZFPlayer
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
Copyright (c) 2018 renzifeng <zifeng1300@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<p align="center">
<img src="https://upload-images.jianshu.io/upload_images/635942-092427e571756309.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="ZFPlayer" title="ZFPlayer" width="557"/>
</p>
<p align="center">
<a href="https://img.shields.io/cocoapods/v/ZFPlayer.svg"><img src="https://img.shields.io/cocoapods/v/ZFPlayer.svg"></a>
<a href="https://img.shields.io/github/license/renzifeng/ZFPlayer.svg?style=flat"><img src="https://img.shields.io/github/license/renzifeng/ZFPlayer.svg?style=flat"></a>
<a href="https://img.shields.io/cocoapods/dt/ZFPlayer.svg?maxAge=2592000"><img src="https://img.shields.io/cocoapods/dt/ZFPlayer.svg?maxAge=2592000"></a>
<a href="https://img.shields.io/cocoapods/at/ZFPlayer.svg?maxAge=2592000"><img src="https://img.shields.io/cocoapods/at/ZFPlayer.svg?maxAge=2592000"></a>
<a href="http://cocoadocs.org/docsets/ZFPlayer"><img src="https://img.shields.io/cocoapods/p/ZFPlayer.svg?style=flat"></a>
<a href="http://weibo.com/zifeng1300"><img src="https://img.shields.io/badge/weibo-@%E4%BB%BB%E5%AD%90%E4%B8%B0-yellow.svg?style=flat"></a>
</p>
[中文说明](https://www.jianshu.com/p/90e55deb4d51)
[ZFPlayer 4.x迁移指南](https://github.com/renzifeng/ZFPlayer/wiki/ZFPlayer-4.x%E8%BF%81%E7%A7%BB%E6%8C%87%E5%8D%97)
Before this, you used ZFPlayer, are you worried about encapsulating avplayer instead of using or modifying the source code to support other players, the control layer is not easy to customize, and so on? In order to solve these problems, I have wrote this player template, for player SDK you can conform the `ZFPlayerMediaPlayback` protocol, for control view you can conform the `ZFPlayerMediaControl` protocol, can custom the player and control view.
![ZFPlayer思维导图](https://upload-images.jianshu.io/upload_images/635942-e99d76498cb01afb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 🔨 Requirements
- iOS 7+
- Xcode 8+
## 📲 Installation
ZFPlayer is available through [CocoaPods](https://cocoapods.org). To install it,use player template simply add the following line to your Podfile:
```objc
pod 'ZFPlayer', '~> 4.0'
```
Use default controlView simply add the following line to your Podfile:
```objc
pod 'ZFPlayer/ControlView', '~> 4.0'
```
Use AVPlayer simply add the following line to your Podfile:
```objc
pod 'ZFPlayer/AVPlayer', '~> 4.0'
```
Use ijkplayer simply add the following line to your Podfile:
```objc
pod 'ZFPlayer/ijkplayer', '~> 4.0'
```
[IJKMediaFramework SDK](https://gitee.com/renzifeng/IJKMediaFramework) support cocoapods
边下边播可以参考使用[KTVHTTPCache](https://github.com/ChangbaDevs/KTVHTTPCache)
## 🐒 Usage
#### ZFPlayerController
Main classes,normal style initialization and list style initialization (tableView, collection,scrollView)
Normal style initialization
```objc
ZFPlayerController *player = [ZFPlayerController playerWithPlayerManager:playerManager containerView:containerView];
ZFPlayerController *player = [[ZFPlayerController alloc] initwithPlayerManager:playerManager containerView:containerView];
```
List style initialization
```objc
ZFPlayerController *player = [ZFPlayerController playerWithScrollView:tableView playerManager:playerManager containerViewTag:containerViewTag];
ZFPlayerController *player = [ZFPlayerController alloc] initWithScrollView:tableView playerManager:playerManager containerViewTag:containerViewTag];
ZFPlayerController *player = [ZFPlayerController playerWithScrollView:scrollView playerManager:playerManager containerView:containerView];
ZFPlayerController *player = [ZFPlayerController alloc] initWithScrollView:tableView playerManager:playerManager containerView:containerView];
```
#### ZFPlayerMediaPlayback
For the playerMnager,you must conform `ZFPlayerMediaPlayback` protocol,custom playermanager can supports any player SDK,such as `AVPlayer`,`MPMoviePlayerController`,`ijkplayer`,`vlc`,`PLPlayerKit`,`KSYMediaPlayer`and so on,you can reference the `ZFAVPlayerManager`class.
```objc
Class<ZFPlayerMediaPlayback> *playerManager = ...;
```
#### ZFPlayerMediaControl
This class is used to display the control layer, and you must conform the ZFPlayerMediaControl protocol, you can reference the `ZFPlayerControlView` class.
```objc
UIView<ZFPlayerMediaControl> *controlView = ...;
player.controlView = controlView;
```
## 📷 Screenshots
![Picture effect](https://upload-images.jianshu.io/upload_images/635942-1b0e23b7f5eabd9e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 👨🏻‍💻 Author
- Weibo: [@任子丰](https://weibo.com/zifeng1300)
- Email: zifeng1300@gmail.com
- QQ群: 123449304
![](https://upload-images.jianshu.io/upload_images/635942-a9fbbb2710de8eff.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## ❤️ Contributors
林界:https://github.com/GeekLee609
## 🙋🏻‍♂️🙋🏻‍♀️寻求志同道合的小伙伴
- 现寻求志同道合的小伙伴一起维护此框架,有兴趣的小伙伴可以[发邮件](zifeng1300@gmail.com)给我,非常感谢!
- 如果一切OK,我将开放框架维护权限(github、pod等)
## 💰 打赏作者
如果ZFPlayer在开发中有帮助到你、如果你需要技术支持或者你需要定制功能,都可以拼命打赏我!
![支付.jpg](https://upload-images.jianshu.io/upload_images/635942-b9b836cfbb7a5e44.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 👮🏻 License
ZFPlayer is available under the MIT license. See the LICENSE file for more info.
//
// UIViewController+ZFPlayerRotation.m
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
@implementation UITabBarController (ZFPlayerRotation)
+ (void)initialize {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL selectors[] = {
@selector(selectedIndex)
};
for (NSUInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) {
SEL originalSelector = selectors[index];
SEL swizzledSelector = NSSelectorFromString([@"zf_" stringByAppendingString:NSStringFromSelector(originalSelector)]);
Method originalMethod = class_getInstanceMethod(self, originalSelector);
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
if (class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
});
}
- (NSInteger)zf_selectedIndex {
NSInteger index = [self zf_selectedIndex];
if (index > self.viewControllers.count) return 0;
return index;
}
/**
* If the root view of the window is a UINavigationController, you call this Category first, and then UIViewController called.
* All you need to do is revisit the following three methods on a page that supports directions other than portrait.
*/
// Whether automatic screen rotation is supported.
- (BOOL)shouldAutorotate {
return [[self viewControllerRotation] shouldAutorotate];
}
// Which screen directions are supported.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [[self viewControllerRotation] supportedInterfaceOrientations];
}
// The default screen direction (the current ViewController must be represented by a modal UIViewController (which is not valid with modal navigation) to call this method).
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[self viewControllerRotation] preferredInterfaceOrientationForPresentation];
}
// Return ViewController which decide rotation,if selected in UITabBarController is UINavigationController,return topViewController
- (UIViewController *)viewControllerRotation {
UIViewController *vc = self.viewControllers[self.selectedIndex];
if ([vc isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)vc;
return nav.topViewController;
} else {
return vc;
}
}
@end
@implementation UINavigationController (ZFPlayerRotation)
/**
* If the root view of the window is a UINavigationController, you call this Category first, and then UIViewController called.
* All you need to do is revisit the following three methods on a page that supports directions other than portrait.
*/
// Whether automatic screen rotation is supported
- (BOOL)shouldAutorotate {
return [self.topViewController shouldAutorotate];
}
// Which screen directions are supported
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
// The default screen direction (the current ViewController must be represented by a modal UIViewController (which is not valid with modal navigation) to call this method).
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
- (UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}
- (UIViewController *)childViewControllerForStatusBarHidden {
return self.topViewController;
}
@end
//
// ZFFloatView.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
@interface ZFFloatView : UIView
/// The parent View
@property(nonatomic, weak) UIView *parentView;
/// Safe margins, mainly for those with Navbar and tabbar
@property(nonatomic, assign) UIEdgeInsets safeInsets;
@end
//
// ZFFloatView.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFFloatView.h"
@implementation ZFFloatView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initilize];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
[self initilize];
}
return self;
}
- (void)initilize {
self.safeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doMoveAction:)];
[self addGestureRecognizer:panGestureRecognizer];
}
- (void)setParentView:(UIView *)parentView {
_parentView = parentView;
[parentView addSubview:self];
}
#pragma mark - Action
- (void)doMoveAction:(UIPanGestureRecognizer *)recognizer {
/// The position where the gesture is moving in the self.view.
CGPoint translation = [recognizer translationInView:self.parentView];
CGPoint newCenter = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
// Limited screen range:
// Top margin limit.
newCenter.y = MAX(recognizer.view.frame.size.height/2 + self.safeInsets.top, newCenter.y);
// Bottom margin limit.
newCenter.y = MIN(self.parentView.frame.size.height - self.safeInsets.bottom - recognizer.view.frame.size.height/2, newCenter.y);
// Left margin limit.
newCenter.x = MAX(recognizer.view.frame.size.width/2, newCenter.x);
// Right margin limit.
newCenter.x = MIN(self.parentView.frame.size.width - recognizer.view.frame.size.width/2,newCenter.x);
// Set the center point.
recognizer.view.center = newCenter;
// Set the gesture coordinates to 0, otherwise it will add up.
[recognizer setTranslation:CGPointZero inView:self.parentView];
}
@end
//
// UIScrollView+ZFPlayer.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
@interface ZFKVOController : NSObject
- (instancetype)initWithTarget:(NSObject *)target;
- (void)safelyAddObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(void *)context;
- (void)safelyRemoveObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath;
- (void)safelyRemoveAllObservers;
@end
//
// UIScrollView+ZFPlayer.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFKVOController.h"
@interface ZFKVOEntry : NSObject
@property (nonatomic, weak) NSObject *observer;
@property (nonatomic, copy) NSString *keyPath;
@end
@implementation ZFKVOEntry
@end
@interface ZFKVOController ()
@property (nonatomic, weak) NSObject *target;
@property (nonatomic, strong) NSMutableArray *observerArray;
@end
@implementation ZFKVOController
- (instancetype)initWithTarget:(NSObject *)target {
self = [super init];
if (self) {
_target = target;
_observerArray = [[NSMutableArray alloc] init];
}
return self;
}
- (void)safelyAddObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(void *)context {
if (_target == nil) return;
NSInteger indexEntry = [self indexEntryOfObserver:observer forKeyPath:keyPath];
if (indexEntry != NSNotFound) {
// duplicated register
NSLog(@"duplicated observer");
} else {
@try {
[_target addObserver:observer
forKeyPath:keyPath
options:options
context:context];
ZFKVOEntry *entry = [[ZFKVOEntry alloc] init];
entry.observer = observer;
entry.keyPath = keyPath;
[_observerArray addObject:entry];
} @catch (NSException *e) {
NSLog(@"ZFKVO: failed to add observer for %@\n", keyPath);
}
}
}
- (void)safelyRemoveObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath {
if (_target == nil) return;
NSInteger indexEntry = [self indexEntryOfObserver:observer forKeyPath:keyPath];
if (indexEntry == NSNotFound) {
// duplicated register
NSLog(@"duplicated observer");
} else {
[_observerArray removeObjectAtIndex:indexEntry];
@try {
[_target removeObserver:observer
forKeyPath:keyPath];
} @catch (NSException *e) {
NSLog(@"ZFKVO: failed to remove observer for %@\n", keyPath);
}
}
}
- (void)safelyRemoveAllObservers {
if (_target == nil) return;
[_observerArray enumerateObjectsUsingBlock:^(ZFKVOEntry *entry, NSUInteger idx, BOOL *stop) {
if (entry == nil) return;
NSObject *observer = entry.observer;
if (observer == nil) return;
@try {
[_target removeObserver:observer
forKeyPath:entry.keyPath];
} @catch (NSException *e) {
NSLog(@"ZFKVO: failed to remove observer for %@\n", entry.keyPath);
}
}];
[_observerArray removeAllObjects];
}
- (NSInteger)indexEntryOfObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath {
__block NSInteger foundIndex = NSNotFound;
[_observerArray enumerateObjectsUsingBlock:^(ZFKVOEntry *entry, NSUInteger idx, BOOL *stop) {
if (entry.observer == observer &&
[entry.keyPath isEqualToString:keyPath]) {
foundIndex = idx;
*stop = YES;
}
}];
return foundIndex;
}
@end
//
// ZFFullscreenViewController.h
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
@class ZFLandscapeViewController;
NS_ASSUME_NONNULL_BEGIN
@protocol ZFLandscapeViewControllerDelegate <NSObject>
- (BOOL)ls_shouldAutorotate;
- (void)ls_willRotateToOrientation:(UIInterfaceOrientation)orientation;
- (void)ls_didRotateFromOrientation:(UIInterfaceOrientation)orientation;
- (CGRect)ls_targetRect;
@end
@interface ZFLandscapeViewController : UIViewController
@property (nonatomic, weak) UIView *contentView;
@property (nonatomic, weak) UIView *containerView;
@property (nonatomic, assign) CGRect targetRect;
@property (nonatomic, weak, nullable) id<ZFLandscapeViewControllerDelegate> delegate;
@property (nonatomic, readonly) BOOL isFullscreen;
@property (nonatomic, getter=isRotating) BOOL rotating;
@property (nonatomic, assign) BOOL disableAnimations;
@property (nonatomic, assign) BOOL statusBarHidden;
/// default is UIStatusBarStyleLightContent.
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
/// defalut is UIStatusBarAnimationSlide.
@property (nonatomic, assign) UIStatusBarAnimation statusBarAnimation;
@property (nonatomic, copy) void(^rotatingCompleted)(void);
@end
NS_ASSUME_NONNULL_END
//
// ZFFullScreenViewController.m
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFLandscapeViewController.h"
@interface ZFLandscapeViewController ()
@property (nonatomic, assign) UIInterfaceOrientation currentOrientation;
@end
@implementation ZFLandscapeViewController
- (instancetype)init {
self = [super init];
if (self) {
_currentOrientation = UIInterfaceOrientationPortrait;
_statusBarStyle = UIStatusBarStyleLightContent;
_statusBarAnimation = UIStatusBarAnimationSlide;
}
return self;
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
self.rotating = YES;
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
if (!UIDeviceOrientationIsValidInterfaceOrientation([UIDevice currentDevice].orientation)) {
return;
}
UIInterfaceOrientation newOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
UIInterfaceOrientation oldOrientation = _currentOrientation;
if (UIInterfaceOrientationIsLandscape(newOrientation)) {
if (self.contentView.superview != self.view) {
[self.view addSubview:self.contentView];
}
}
if (oldOrientation == UIInterfaceOrientationPortrait) {
self.contentView.frame = [self.delegate ls_targetRect];
[self.contentView layoutIfNeeded];
}
self.currentOrientation = newOrientation;
[self.delegate ls_willRotateToOrientation:self.currentOrientation];
BOOL isFullscreen = size.width > size.height;
if (self.disableAnimations) {
[CATransaction begin];
[CATransaction setDisableActions:YES];
}
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
if (isFullscreen) {
self.contentView.frame = CGRectMake(0, 0, size.width, size.height);
} else {
self.contentView.frame = [self.delegate ls_targetRect];
}
[self.contentView layoutIfNeeded];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
if (self.disableAnimations) {
[CATransaction commit];
}
[self.delegate ls_didRotateFromOrientation:self.currentOrientation];
if (!isFullscreen) {
self.contentView.frame = self.containerView.bounds;
[self.contentView layoutIfNeeded];
}
self.disableAnimations = NO;
self.rotating = NO;
}];
}
- (BOOL)isFullscreen {
return UIInterfaceOrientationIsLandscape(_currentOrientation);
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate {
return [self.delegate ls_shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
UIInterfaceOrientation currentOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
if (UIInterfaceOrientationIsLandscape(currentOrientation)) {
return UIInterfaceOrientationMaskLandscape;
}
return UIInterfaceOrientationMaskAll;
}
- (BOOL)prefersHomeIndicatorAutoHidden {
UIInterfaceOrientation currentOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
if (UIInterfaceOrientationIsLandscape(currentOrientation)) {
return YES;
}
return NO;
}
- (BOOL)prefersStatusBarHidden {
return self.statusBarHidden;
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return self.statusBarStyle;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return self.statusBarAnimation;
}
- (void)setRotating:(BOOL)rotating {
_rotating = rotating;
if (!rotating && self.rotatingCompleted) {
self.rotatingCompleted();
}
}
@end
//
// ZFLandScaprWindow.h
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#import "ZFLandscapeViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface ZFLandscapeWindow : UIWindow
@property (nonatomic, strong, readonly) ZFLandscapeViewController *landscapeViewController;
@end
NS_ASSUME_NONNULL_END
//
// ZFLandScaprWindow.m
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFLandscapeWindow.h"
@implementation ZFLandscapeWindow
@dynamic rootViewController;
- (void)setBackgroundColor:(nullable UIColor *)backgroundColor {}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.windowLevel = UIWindowLevelNormal;
_landscapeViewController = [[ZFLandscapeViewController alloc] init];
self.rootViewController = _landscapeViewController;
if (@available(iOS 13.0, *)) {
if (self.windowScene == nil) {
self.windowScene = UIApplication.sharedApplication.keyWindow.windowScene;
}
}
self.hidden = YES;
}
return self;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *_Nullable)event {
return YES;
}
- (void)layoutSubviews {
[super layoutSubviews];
static CGRect bounds;
if (!CGRectEqualToRect(bounds, self.bounds)) {
UIView *superview = self;
if (@available(iOS 13.0, *)) {
superview = self.subviews.firstObject;
}
[UIView performWithoutAnimation:^{
for (UIView *view in superview.subviews) {
if (view != self.rootViewController.view && [view isMemberOfClass:UIView.class]) {
view.backgroundColor = UIColor.clearColor;
for (UIView *subview in view.subviews) {
subview.backgroundColor = UIColor.clearColor;
}
}
}
}];
}
bounds = self.bounds;
self.rootViewController.view.frame = bounds;
}
@end
//
// ZFOrentationObserver.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#import "ZFPlayerView.h"
NS_ASSUME_NONNULL_BEGIN
/// Full screen mode
typedef NS_ENUM(NSUInteger, ZFFullScreenMode) {
ZFFullScreenModeAutomatic, // Determine full screen mode automatically
ZFFullScreenModeLandscape, // Landscape full screen mode
ZFFullScreenModePortrait // Portrait full screen Model
};
/// Portrait full screen mode.
typedef NS_ENUM(NSUInteger, ZFPortraitFullScreenMode) {
ZFPortraitFullScreenModeScaleToFill, // Full fill
ZFPortraitFullScreenModeScaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent
};
/// Player view mode
typedef NS_ENUM(NSUInteger, ZFRotateType) {
ZFRotateTypeNormal, // Normal
ZFRotateTypeCell // Cell
};
/**
Rotation of support direction
*/
typedef NS_OPTIONS(NSUInteger, ZFInterfaceOrientationMask) {
ZFInterfaceOrientationMaskPortrait = (1 << 0),
ZFInterfaceOrientationMaskLandscapeLeft = (1 << 1),
ZFInterfaceOrientationMaskLandscapeRight = (1 << 2),
ZFInterfaceOrientationMaskPortraitUpsideDown = (1 << 3),
ZFInterfaceOrientationMaskLandscape = (ZFInterfaceOrientationMaskLandscapeLeft | ZFInterfaceOrientationMaskLandscapeRight),
ZFInterfaceOrientationMaskAll = (ZFInterfaceOrientationMaskPortrait | ZFInterfaceOrientationMaskLandscape | ZFInterfaceOrientationMaskPortraitUpsideDown),
ZFInterfaceOrientationMaskAllButUpsideDown = (ZFInterfaceOrientationMaskPortrait | ZFInterfaceOrientationMaskLandscape),
};
/// This enumeration lists some of the gesture types that the player has by default.
typedef NS_OPTIONS(NSUInteger, ZFDisablePortraitGestureTypes) {
ZFDisablePortraitGestureTypesNone = 0,
ZFDisablePortraitGestureTypesTap = 1 << 0,
ZFDisablePortraitGestureTypesPan = 1 << 1,
ZFDisablePortraitGestureTypesAll = (ZFDisablePortraitGestureTypesTap | ZFDisablePortraitGestureTypesPan)
};
@protocol ZFPortraitOrientationDelegate <NSObject>
- (void)zf_orientationWillChange:(BOOL)isFullScreen;
- (void)zf_orientationDidChanged:(BOOL)isFullScreen;
- (void)zf_interationState:(BOOL)isDragging;
@end
@interface ZFOrientationObserver : NSObject
/// update the rotateView and containerView.
- (void)updateRotateView:(ZFPlayerView *)rotateView
containerView:(UIView *)containerView;
/// list play
- (void)updateRotateView:(ZFPlayerView *)rotateView
rotateViewAtCell:(UIView *)cell
playerViewTag:(NSInteger)playerViewTag;
/// Container view of a full screen state player.
@property (nonatomic, strong) UIView *fullScreenContainerView;
/// Container view of a small screen state player.
@property (nonatomic, weak) UIView *containerView;
/// The block invoked When player will rotate.
@property (nonatomic, copy, nullable) void(^orientationWillChange)(ZFOrientationObserver *observer, BOOL isFullScreen);
/// The block invoked when player rotated.
@property (nonatomic, copy, nullable) void(^orientationDidChanged)(ZFOrientationObserver *observer, BOOL isFullScreen);
/// Full screen mode, the default landscape into full screen
@property (nonatomic) ZFFullScreenMode fullScreenMode;
@property (nonatomic, assign) ZFPortraitFullScreenMode portraitFullScreenMode;
/// rotate duration, default is 0.30
@property (nonatomic) NSTimeInterval duration;
/// If the full screen.
@property (nonatomic, readonly, getter=isFullScreen) BOOL fullScreen;
/// Lock screen orientation
@property (nonatomic, getter=isLockedScreen) BOOL lockedScreen;
/// The fullscreen statusbar hidden.
@property (nonatomic, assign) BOOL fullScreenStatusBarHidden;
/// default is UIStatusBarStyleLightContent.
@property (nonatomic, assign) UIStatusBarStyle fullScreenStatusBarStyle;
/// defalut is UIStatusBarAnimationSlide.
@property (nonatomic, assign) UIStatusBarAnimation fullScreenStatusBarAnimation;
@property (nonatomic, assign) CGSize presentationSize;
/// default is ZFDisablePortraitGestureTypesAll.
@property (nonatomic, assign) ZFDisablePortraitGestureTypes disablePortraitGestureTypes;
/// The current orientation of the player.
/// Default is UIInterfaceOrientationPortrait.
@property (nonatomic, readonly) UIInterfaceOrientation currentOrientation;
/// Whether allow the video orientation rotate.
/// default is YES.
@property (nonatomic, assign) BOOL allowOrientationRotation;
/// The support Interface Orientation,default is ZFInterfaceOrientationMaskAllButUpsideDown
@property (nonatomic, assign) ZFInterfaceOrientationMask supportInterfaceOrientation;
/// Add the device orientation observer.
- (void)addDeviceOrientationObserver;
/// Remove the device orientation observer.
- (void)removeDeviceOrientationObserver;
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated;
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModePortrait.
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated;
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModePortrait.
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
/// FullScreen mode is determined by ZFFullScreenMode.
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated;
/// FullScreen mode is determined by ZFFullScreenMode.
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void (^ _Nullable)(void))completion;
@end
NS_ASSUME_NONNULL_END
//
// ZFPersentInteractiveTransition.h
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "ZFOrientationObserver.h"
@interface ZFPersentInteractiveTransition : UIPercentDrivenInteractiveTransition
@property (nonatomic, weak) id<ZFPortraitOrientationDelegate> delagate;
@property (nonatomic, assign) BOOL interation;
/// default is ZFDisablePortraitGestureTypesNone.
@property (nonatomic, assign) ZFDisablePortraitGestureTypes disablePortraitGestureTypes;
@property (nonatomic, assign) BOOL fullScreenAnimation;
@property (nonatomic, assign) CGRect contentFullScreenRect;
@property (nonatomic, weak) UIViewController *viewController;
- (void)updateContentView:(UIView *)contenView
containerView:(UIView *)containerView;
@end
//
// ZFPlayer.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
//! Project version number for ZFPlayer.
FOUNDATION_EXPORT double ZFPlayerVersionNumber;
//! Project version string for ZFPlayer.
FOUNDATION_EXPORT const unsigned char ZFPlayerVersionString[];
#import "ZFPlayerController.h"
#import "ZFPlayerMediaControl.h"
#import "ZFKVOController.h"
#import "UIScrollView+ZFPlayer.h"
#import "ZFPlayerLogManager.h"
#import "ZFPlayerConst.h"
//
// ZFPlayerConst.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
typedef NS_ENUM(NSUInteger, ZFPlayerPlaybackState) {
ZFPlayerPlayStateUnknown,
ZFPlayerPlayStatePlaying,
ZFPlayerPlayStatePaused,
ZFPlayerPlayStatePlayFailed,
ZFPlayerPlayStatePlayStopped
};
typedef NS_OPTIONS(NSUInteger, ZFPlayerLoadState) {
ZFPlayerLoadStateUnknown = 0,
ZFPlayerLoadStatePrepare = 1 << 0,
ZFPlayerLoadStatePlayable = 1 << 1,
ZFPlayerLoadStatePlaythroughOK = 1 << 2, // Playback will be automatically started.
ZFPlayerLoadStateStalled = 1 << 3, // Playback will be automatically paused in this state, if started.
};
typedef NS_ENUM(NSInteger, ZFPlayerScalingMode) {
ZFPlayerScalingModeNone, // No scaling.
ZFPlayerScalingModeAspectFit, // Uniform scale until one dimension fits.
ZFPlayerScalingModeAspectFill, // Uniform scale until the movie fills the visible bounds. One dimension may have clipped contents.
ZFPlayerScalingModeFill // Non-uniform scale. Both render dimensions will exactly match the visible bounds.
};
/**
Synthsize a weak or strong reference.
Example:
@zf_weakify(self)
[self doSomething^{
@zf_strongify(self)
if (!self) return;
...
}];
*/
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define zf_weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define zf_weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define zf_weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define zf_weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define zf_strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define zf_strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define zf_strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define zf_strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif
// Screen width
#define ZFPlayerScreenWidth [[UIScreen mainScreen] bounds].size.width
// Screen height
#define ZFPlayerScreenHeight [[UIScreen mainScreen] bounds].size.height
// deprecated
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif
//
// ZFPlayerGestureControl.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, ZFPlayerGestureType) {
ZFPlayerGestureTypeUnknown,
ZFPlayerGestureTypeSingleTap,
ZFPlayerGestureTypeDoubleTap,
ZFPlayerGestureTypePan,
ZFPlayerGestureTypePinch
};
typedef NS_ENUM(NSUInteger, ZFPanDirection) {
ZFPanDirectionUnknown,
ZFPanDirectionV,
ZFPanDirectionH,
};
typedef NS_ENUM(NSUInteger, ZFPanLocation) {
ZFPanLocationUnknown,
ZFPanLocationLeft,
ZFPanLocationRight,
};
typedef NS_ENUM(NSUInteger, ZFPanMovingDirection) {
ZFPanMovingDirectionUnkown,
ZFPanMovingDirectionTop,
ZFPanMovingDirectionLeft,
ZFPanMovingDirectionBottom,
ZFPanMovingDirectionRight,
};
/// This enumeration lists some of the gesture types that the player has by default.
typedef NS_OPTIONS(NSUInteger, ZFPlayerDisableGestureTypes) {
ZFPlayerDisableGestureTypesNone = 0,
ZFPlayerDisableGestureTypesSingleTap = 1 << 0,
ZFPlayerDisableGestureTypesDoubleTap = 1 << 1,
ZFPlayerDisableGestureTypesPan = 1 << 2,
ZFPlayerDisableGestureTypesPinch = 1 << 3,
ZFPlayerDisableGestureTypesAll = (ZFPlayerDisableGestureTypesSingleTap | ZFPlayerDisableGestureTypesDoubleTap | ZFPlayerDisableGestureTypesPan | ZFPlayerDisableGestureTypesPinch)
};
/// This enumeration lists some of the pan gesture moving direction that the player not support.
typedef NS_OPTIONS(NSUInteger, ZFPlayerDisablePanMovingDirection) {
ZFPlayerDisablePanMovingDirectionNone = 0, /// Not disable pan moving direction.
ZFPlayerDisablePanMovingDirectionVertical = 1 << 0, /// Disable pan moving vertical direction.
ZFPlayerDisablePanMovingDirectionHorizontal = 1 << 1, /// Disable pan moving horizontal direction.
ZFPlayerDisablePanMovingDirectionAll = (ZFPlayerDisablePanMovingDirectionVertical | ZFPlayerDisablePanMovingDirectionHorizontal) /// Disable pan moving all direction.
};
@interface ZFPlayerGestureControl : NSObject
/// Gesture condition callback.
@property (nonatomic, copy, nullable) BOOL(^triggerCondition)(ZFPlayerGestureControl *control, ZFPlayerGestureType type, UIGestureRecognizer *gesture, UITouch *touch);
/// Single tap gesture callback.
@property (nonatomic, copy, nullable) void(^singleTapped)(ZFPlayerGestureControl *control);
/// Double tap gesture callback.
@property (nonatomic, copy, nullable) void(^doubleTapped)(ZFPlayerGestureControl *control);
/// Begin pan gesture callback.
@property (nonatomic, copy, nullable) void(^beganPan)(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location);
/// Pan gesture changing callback.
@property (nonatomic, copy, nullable) void(^changedPan)(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location, CGPoint velocity);
/// End the Pan gesture callback.
@property (nonatomic, copy, nullable) void(^endedPan)(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location);
/// Pinch gesture callback.
@property (nonatomic, copy, nullable) void(^pinched)(ZFPlayerGestureControl *control, float scale);
/// The single tap gesture.
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTap;
/// The double tap gesture.
@property (nonatomic, strong, readonly) UITapGestureRecognizer *doubleTap;
/// The pan tap gesture.
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *panGR;
/// The pinch tap gesture.
@property (nonatomic, strong, readonly) UIPinchGestureRecognizer *pinchGR;
/// The pan gesture direction.
@property (nonatomic, readonly) ZFPanDirection panDirection;
/// The pan location.
@property (nonatomic, readonly) ZFPanLocation panLocation;
/// The moving drection.
@property (nonatomic, readonly) ZFPanMovingDirection panMovingDirection;
/// The gesture types that the player not support.
@property (nonatomic) ZFPlayerDisableGestureTypes disableTypes;
/// The pan gesture moving direction that the player not support.
@property (nonatomic) ZFPlayerDisablePanMovingDirection disablePanMovingDirection;
/**
Add all gestures(singleTap、doubleTap、panGR、pinchGR) to the view.
*/
- (void)addGestureToView:(UIView *)view;
/**
Remove all gestures(singleTap、doubleTap、panGR、pinchGR) form the view.
*/
- (void)removeGestureToView:(UIView *)view;
@end
NS_ASSUME_NONNULL_END
//
// ZFPlayerGestureControl.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFPlayerGestureControl.h"
@interface ZFPlayerGestureControl ()<UIGestureRecognizerDelegate>
@property (nonatomic, strong) UITapGestureRecognizer *singleTap;
@property (nonatomic, strong) UITapGestureRecognizer *doubleTap;
@property (nonatomic, strong) UIPanGestureRecognizer *panGR;
@property (nonatomic, strong) UIPinchGestureRecognizer *pinchGR;
@property (nonatomic) ZFPanDirection panDirection;
@property (nonatomic) ZFPanLocation panLocation;
@property (nonatomic) ZFPanMovingDirection panMovingDirection;
@property (nonatomic, weak) UIView *targetView;
@end
@implementation ZFPlayerGestureControl
- (void)addGestureToView:(UIView *)view {
self.targetView = view;
self.targetView.multipleTouchEnabled = YES;
[self.singleTap requireGestureRecognizerToFail:self.doubleTap];
[self.singleTap requireGestureRecognizerToFail:self.panGR];
[self.targetView addGestureRecognizer:self.singleTap];
[self.targetView addGestureRecognizer:self.doubleTap];
[self.targetView addGestureRecognizer:self.panGR];
[self.targetView addGestureRecognizer:self.pinchGR];
}
- (void)removeGestureToView:(UIView *)view {
[view removeGestureRecognizer:self.singleTap];
[view removeGestureRecognizer:self.doubleTap];
[view removeGestureRecognizer:self.panGR];
[view removeGestureRecognizer:self.pinchGR];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == self.panGR) {
CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:self.targetView];
CGFloat x = fabs(translation.x);
CGFloat y = fabs(translation.y);
if (x < y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionVertical) { /// up and down moving direction.
return NO;
} else if (x > y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionHorizontal) { /// left and right moving direction.
return NO;
}
}
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
ZFPlayerGestureType type = ZFPlayerGestureTypeUnknown;
if (gestureRecognizer == self.singleTap) type = ZFPlayerGestureTypeSingleTap;
else if (gestureRecognizer == self.doubleTap) type = ZFPlayerGestureTypeDoubleTap;
else if (gestureRecognizer == self.panGR) type = ZFPlayerGestureTypePan;
else if (gestureRecognizer == self.pinchGR) type = ZFPlayerGestureTypePinch;
CGPoint locationPoint = [touch locationInView:touch.view];
if (locationPoint.x > _targetView.bounds.size.width / 2) {
self.panLocation = ZFPanLocationRight;
} else {
self.panLocation = ZFPanLocationLeft;
}
switch (type) {
case ZFPlayerGestureTypeUnknown: break;
case ZFPlayerGestureTypePan: {
if (self.disableTypes & ZFPlayerDisableGestureTypesPan) {
return NO;
}
}
break;
case ZFPlayerGestureTypePinch: {
if (self.disableTypes & ZFPlayerDisableGestureTypesPinch) {
return NO;
}
}
break;
case ZFPlayerGestureTypeDoubleTap: {
if (self.disableTypes & ZFPlayerDisableGestureTypesDoubleTap) {
return NO;
}
}
break;
case ZFPlayerGestureTypeSingleTap: {
if (self.disableTypes & ZFPlayerDisableGestureTypesSingleTap) {
return NO;
}
}
break;
}
if (self.triggerCondition) return self.triggerCondition(self, type, gestureRecognizer, touch);
return YES;
}
// Whether to support multi-trigger, return YES, you can trigger a method with multiple gestures, return NO is mutually exclusive
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if (otherGestureRecognizer != self.singleTap &&
otherGestureRecognizer != self.doubleTap &&
otherGestureRecognizer != self.panGR &&
otherGestureRecognizer != self.pinchGR) return NO;
if (gestureRecognizer == self.panGR) {
CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:self.targetView];
CGFloat x = fabs(translation.x);
CGFloat y = fabs(translation.y);
if (x < y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionVertical) {
return YES;
} else if (x > y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionHorizontal) {
return YES;
}
}
if (gestureRecognizer.numberOfTouches >= 2) {
return NO;
}
return YES;
}
- (UITapGestureRecognizer *)singleTap {
if (!_singleTap){
_singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
_singleTap.delegate = self;
_singleTap.delaysTouchesBegan = YES;
_singleTap.delaysTouchesEnded = YES;
_singleTap.numberOfTouchesRequired = 1;
_singleTap.numberOfTapsRequired = 1;
}
return _singleTap;
}
- (UITapGestureRecognizer *)doubleTap {
if (!_doubleTap) {
_doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
_doubleTap.delegate = self;
_doubleTap.delaysTouchesBegan = YES;
_singleTap.delaysTouchesEnded = YES;
_doubleTap.numberOfTouchesRequired = 1;
_doubleTap.numberOfTapsRequired = 2;
}
return _doubleTap;
}
- (UIPanGestureRecognizer *)panGR {
if (!_panGR) {
_panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
_panGR.delegate = self;
_panGR.delaysTouchesBegan = YES;
_panGR.delaysTouchesEnded = YES;
_panGR.maximumNumberOfTouches = 1;
_panGR.cancelsTouchesInView = YES;
}
return _panGR;
}
- (UIPinchGestureRecognizer *)pinchGR {
if (!_pinchGR) {
_pinchGR = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
_pinchGR.delegate = self;
_pinchGR.delaysTouchesBegan = YES;
}
return _pinchGR;
}
- (void)handleSingleTap:(UITapGestureRecognizer *)tap {
if (self.singleTapped) self.singleTapped(self);
}
- (void)handleDoubleTap:(UITapGestureRecognizer *)tap {
if (self.doubleTapped) self.doubleTapped(self);
}
- (void)handlePan:(UIPanGestureRecognizer *)pan {
CGPoint translate = [pan translationInView:pan.view];
CGPoint velocity = [pan velocityInView:pan.view];
switch (pan.state) {
case UIGestureRecognizerStateBegan: {
self.panMovingDirection = ZFPanMovingDirectionUnkown;
CGFloat x = fabs(velocity.x);
CGFloat y = fabs(velocity.y);
if (x > y) {
self.panDirection = ZFPanDirectionH;
} else if (x < y) {
self.panDirection = ZFPanDirectionV;
} else {
self.panDirection = ZFPanDirectionUnknown;
}
if (self.beganPan) self.beganPan(self, self.panDirection, self.panLocation);
}
break;
case UIGestureRecognizerStateChanged: {
switch (_panDirection) {
case ZFPanDirectionH: {
if (translate.x > 0) {
self.panMovingDirection = ZFPanMovingDirectionRight;
} else {
self.panMovingDirection = ZFPanMovingDirectionLeft;
}
}
break;
case ZFPanDirectionV: {
if (translate.y > 0) {
self.panMovingDirection = ZFPanMovingDirectionBottom;
} else {
self.panMovingDirection = ZFPanMovingDirectionTop;
}
}
break;
case ZFPanDirectionUnknown:
break;
}
if (self.changedPan) self.changedPan(self, self.panDirection, self.panLocation, velocity);
}
break;
case UIGestureRecognizerStateFailed:
case UIGestureRecognizerStateCancelled:
case UIGestureRecognizerStateEnded: {
if (self.endedPan) self.endedPan(self, self.panDirection, self.panLocation);
}
break;
default:
break;
}
[pan setTranslation:CGPointZero inView:pan.view];
}
- (void)handlePinch:(UIPinchGestureRecognizer *)pinch {
switch (pinch.state) {
case UIGestureRecognizerStateEnded: {
if (self.pinched) self.pinched(self, pinch.scale);
}
break;
default:
break;
}
}
@end
//
// ZFPlayerLogManager.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#define ZFPlayerLog(format,...) [ZFPlayerLogManager logWithFunction:__FUNCTION__ lineNumber:__LINE__ formatString:[NSString stringWithFormat:format, ##__VA_ARGS__]]
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface ZFPlayerLogManager : NSObject
// Set the log output status.
+ (void)setLogEnable:(BOOL)enable;
// Gets the log output status.
+ (BOOL)getLogEnable;
/// Get ZFPlayer version.
+ (NSString *)version;
// Log output method.
+ (void)logWithFunction:(const char *)function lineNumber:(int)lineNumber formatString:(NSString *)formatString;
@end
//
// ZFPlayerLogManager.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFPlayerLogManager.h"
static BOOL kLogEnable = NO;
@implementation ZFPlayerLogManager
+ (void)setLogEnable:(BOOL)enable {
kLogEnable = enable;
}
+ (BOOL)getLogEnable {
return kLogEnable;
}
+ (NSString *)version {
return @"4.0.2";
}
+ (void)logWithFunction:(const char *)function lineNumber:(int)lineNumber formatString:(NSString *)formatString {
if ([self getLogEnable]) {
NSLog(@"%s[%d]%@", function, lineNumber, formatString);
}
}
@end
//
// ZFPlayerMediaControl.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import "ZFPlayerMediaPlayback.h"
#import "ZFOrientationObserver.h"
#import "ZFPlayerGestureControl.h"
#import "ZFReachabilityManager.h"
@class ZFPlayerController;
NS_ASSUME_NONNULL_BEGIN
@protocol ZFPlayerMediaControl <NSObject>
@required
/// Current playerController
@property (nonatomic, weak) ZFPlayerController *player;
@optional
#pragma mark - Playback state
/// When the player prepare to play the video.
- (void)videoPlayer:(ZFPlayerController *)videoPlayer prepareToPlay:(NSURL *)assetURL;
/// When th player playback state changed.
- (void)videoPlayer:(ZFPlayerController *)videoPlayer playStateChanged:(ZFPlayerPlaybackState)state;
/// When th player loading state changed.
- (void)videoPlayer:(ZFPlayerController *)videoPlayer loadStateChanged:(ZFPlayerLoadState)state;
#pragma mark - progress
/**
When the playback changed.
@param videoPlayer the player.
@param currentTime the current play time.
@param totalTime the video total time.
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer
currentTime:(NSTimeInterval)currentTime
totalTime:(NSTimeInterval)totalTime;
/**
When buffer progress changed.
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer
bufferTime:(NSTimeInterval)bufferTime;
/**
When you are dragging to change the video progress.
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer
draggingTime:(NSTimeInterval)seekTime
totalTime:(NSTimeInterval)totalTime;
/**
When play end.
*/
- (void)videoPlayerPlayEnd:(ZFPlayerController *)videoPlayer;
/**
When play failed.
*/
- (void)videoPlayerPlayFailed:(ZFPlayerController *)videoPlayer error:(id)error;
#pragma mark - lock screen
/**
When set `videoPlayer.lockedScreen`.
*/
- (void)lockedVideoPlayer:(ZFPlayerController *)videoPlayer lockedScreen:(BOOL)locked;
#pragma mark - Screen rotation
/**
When the fullScreen maode will changed.
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer orientationWillChange:(ZFOrientationObserver *)observer;
/**
When the fullScreen maode did changed.
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer orientationDidChanged:(ZFOrientationObserver *)observer;
#pragma mark - The network changed
/**
When the network changed
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer reachabilityChanged:(ZFReachabilityStatus)status;
#pragma mark - The video size changed
/**
When the video size changed
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer presentationSizeChanged:(CGSize)size;
#pragma mark - Gesture
/**
When the gesture condition
*/
- (BOOL)gestureTriggerCondition:(ZFPlayerGestureControl *)gestureControl
gestureType:(ZFPlayerGestureType)gestureType
gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
touch:(UITouch *)touch;
/**
When the gesture single tapped
*/
- (void)gestureSingleTapped:(ZFPlayerGestureControl *)gestureControl;
/**
When the gesture double tapped
*/
- (void)gestureDoubleTapped:(ZFPlayerGestureControl *)gestureControl;
/**
When the gesture begin panGesture
*/
- (void)gestureBeganPan:(ZFPlayerGestureControl *)gestureControl
panDirection:(ZFPanDirection)direction
panLocation:(ZFPanLocation)location;
/**
When the gesture paning
*/
- (void)gestureChangedPan:(ZFPlayerGestureControl *)gestureControl
panDirection:(ZFPanDirection)direction
panLocation:(ZFPanLocation)location
withVelocity:(CGPoint)velocity;
/**
When the end panGesture
*/
- (void)gestureEndedPan:(ZFPlayerGestureControl *)gestureControl
panDirection:(ZFPanDirection)direction
panLocation:(ZFPanLocation)location;
/**
When the pinchGesture changed
*/
- (void)gesturePinched:(ZFPlayerGestureControl *)gestureControl
scale:(float)scale;
#pragma mark - scrollview
/**
When the player will appear in scrollView.
*/
- (void)playerWillAppearInScrollView:(ZFPlayerController *)videoPlayer;
/**
When the player did appear in scrollView.
*/
- (void)playerDidAppearInScrollView:(ZFPlayerController *)videoPlayer;
/**
When the player will disappear in scrollView.
*/
- (void)playerWillDisappearInScrollView:(ZFPlayerController *)videoPlayer;
/**
When the player did disappear in scrollView.
*/
- (void)playerDidDisappearInScrollView:(ZFPlayerController *)videoPlayer;
/**
When the player appearing in scrollView.
*/
- (void)playerAppearingInScrollView:(ZFPlayerController *)videoPlayer playerApperaPercent:(CGFloat)playerApperaPercent;
/**
When the player disappearing in scrollView.
*/
- (void)playerDisappearingInScrollView:(ZFPlayerController *)videoPlayer playerDisapperaPercent:(CGFloat)playerDisapperaPercent;
/**
When the small float view show.
*/
- (void)videoPlayer:(ZFPlayerController *)videoPlayer floatViewShow:(BOOL)show;
@end
NS_ASSUME_NONNULL_END
//
// ZFMediaPlayback.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import "ZFPlayerView.h"
#import "ZFPlayerConst.h"
NS_ASSUME_NONNULL_BEGIN
@protocol ZFPlayerMediaPlayback <NSObject>
@required
/// The view must inherited `ZFPlayerView`,this view deals with some gesture conflicts.
@property (nonatomic) ZFPlayerView *view;
/// The player volume.
/// Only affects audio volume for the player instance and not for the device.
/// You can change device volume or player volume as needed,change the player volume you can follow the `ZFPlayerMediaPlayback` protocol.
@property (nonatomic) float volume;
/// The player muted.
/// indicates whether or not audio output of the player is muted. Only affects audio muting for the player instance and not for the device.
/// You can change device volume or player muted as needed,change the player muted you can follow the `ZFPlayerMediaPlayback` protocol.
@property (nonatomic, getter=isMuted) BOOL muted;
/// Playback speed,0.5...2
@property (nonatomic) float rate;
/// The player current play time.
@property (nonatomic, readonly) NSTimeInterval currentTime;
/// The player total time.
@property (nonatomic, readonly) NSTimeInterval totalTime;
/// The player buffer time.
@property (nonatomic, readonly) NSTimeInterval bufferTime;
/// The player seek time.
@property (nonatomic) NSTimeInterval seekTime;
/// The player play state,playing or not playing.
@property (nonatomic, readonly) BOOL isPlaying;
/// Determines how the content scales to fit the view. Defaults to ZFPlayerScalingModeNone.
@property (nonatomic) ZFPlayerScalingMode scalingMode;
/**
@abstract Check whether video preparation is complete.
@discussion isPreparedToPlay processing logic
* If isPreparedToPlay is true, you can call [ZFPlayerMediaPlayback play] API start playing;
* If isPreparedToPlay to false, direct call [ZFPlayerMediaPlayback play], in the play the internal automatic call [ZFPlayerMediaPlayback prepareToPlay] API.
* Returns true if prepared for playback.
*/
@property (nonatomic, readonly) BOOL isPreparedToPlay;
/// The player should auto player, default is YES.
@property (nonatomic) BOOL shouldAutoPlay;
/// The play asset URL.
@property (nonatomic) NSURL *assetURL;
/// The video size.
@property (nonatomic) CGSize presentationSize;
/// The playback state.
@property (nonatomic, readonly) ZFPlayerPlaybackState playState;
/// The player load state.
@property (nonatomic, readonly) ZFPlayerLoadState loadState;
///------------------------------------
/// If you don't appoint the controlView, you can called the following blocks.
/// If you appoint the controlView, The following block cannot be called outside, only for `ZFPlayerController` calls.
///------------------------------------
/// The block invoked when the player is Prepare to play.
@property (nonatomic, copy, nullable) void(^playerPrepareToPlay)(id<ZFPlayerMediaPlayback> asset, NSURL *assetURL);
/// The block invoked when the player is Ready to play.
@property (nonatomic, copy, nullable) void(^playerReadyToPlay)(id<ZFPlayerMediaPlayback> asset, NSURL *assetURL);
/// The block invoked when the player play progress changed.
@property (nonatomic, copy, nullable) void(^playerPlayTimeChanged)(id<ZFPlayerMediaPlayback> asset, NSTimeInterval currentTime, NSTimeInterval duration);
/// The block invoked when the player play buffer changed.
@property (nonatomic, copy, nullable) void(^playerBufferTimeChanged)(id<ZFPlayerMediaPlayback> asset, NSTimeInterval bufferTime);
/// The block invoked when the player playback state changed.
@property (nonatomic, copy, nullable) void(^playerPlayStateChanged)(id<ZFPlayerMediaPlayback> asset, ZFPlayerPlaybackState playState);
/// The block invoked when the player load state changed.
@property (nonatomic, copy, nullable) void(^playerLoadStateChanged)(id<ZFPlayerMediaPlayback> asset, ZFPlayerLoadState loadState);
/// The block invoked when the player play failed.
@property (nonatomic, copy, nullable) void(^playerPlayFailed)(id<ZFPlayerMediaPlayback> asset, id error);
/// The block invoked when the player play end.
@property (nonatomic, copy, nullable) void(^playerDidToEnd)(id<ZFPlayerMediaPlayback> asset);
// The block invoked when video size changed.
@property (nonatomic, copy, nullable) void(^presentationSizeChanged)(id<ZFPlayerMediaPlayback> asset, CGSize size);
///------------------------------------
/// end
///------------------------------------
/// Prepares the current queue for playback, interrupting any active (non-mixible) audio sessions.
- (void)prepareToPlay;
/// Reload player.
- (void)reloadPlayer;
/// Play playback.
- (void)play;
/// Pauses playback.
- (void)pause;
/// Replay playback.
- (void)replay;
/// Stop playback.
- (void)stop;
/// Use this method to seek to a specified time for the current player and to be notified when the seek operation is complete.
- (void)seekToTime:(NSTimeInterval)time completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
@optional
/// Video UIImage at the current time.
- (UIImage *)thumbnailImageAtCurrentTime;
/// Video UIImage at the current time.
- (void)thumbnailImageAtCurrentTime:(void(^)(UIImage *))handler;
@end
NS_ASSUME_NONNULL_END
//
// ZFPlayerNotification.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, ZFPlayerBackgroundState) {
ZFPlayerBackgroundStateForeground, // Enter the foreground from the background.
ZFPlayerBackgroundStateBackground, // From the foreground to the background.
};
@interface ZFPlayerNotification : NSObject
@property (nonatomic, readonly) ZFPlayerBackgroundState backgroundState;
@property (nonatomic, copy, nullable) void(^willResignActive)(ZFPlayerNotification *registrar);
@property (nonatomic, copy, nullable) void(^didBecomeActive)(ZFPlayerNotification *registrar);
@property (nonatomic, copy, nullable) void(^newDeviceAvailable)(ZFPlayerNotification *registrar);
@property (nonatomic, copy, nullable) void(^oldDeviceUnavailable)(ZFPlayerNotification *registrar);
@property (nonatomic, copy, nullable) void(^categoryChange)(ZFPlayerNotification *registrar);
@property (nonatomic, copy, nullable) void(^volumeChanged)(float volume);
@property (nonatomic, copy, nullable) void(^audioInterruptionCallback)(AVAudioSessionInterruptionType interruptionType);
- (void)addNotification;
- (void)removeNotification;
@end
NS_ASSUME_NONNULL_END
//
// ZFPlayerNotification.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFPlayerNotification.h"
@interface ZFPlayerNotification ()
@property (nonatomic, assign) ZFPlayerBackgroundState backgroundState;
@end
@implementation ZFPlayerNotification
- (void)addNotification {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(audioSessionRouteChangeNotification:)
name:AVAudioSessionRouteChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillResignActiveNotification)
name:UIApplicationWillResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidBecomeActiveNotification)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(volumeDidChangeNotification:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(audioSessionInterruptionNotification:)
name:AVAudioSessionInterruptionNotification
object:nil];
}
- (void)removeNotification {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionRouteChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionInterruptionNotification object:nil];
}
- (void)dealloc {
[self removeNotification];
}
- (void)audioSessionRouteChangeNotification:(NSNotification*)notification {
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *interuptionDict = notification.userInfo;
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
switch (routeChangeReason) {
case AVAudioSessionRouteChangeReasonNewDeviceAvailable: {
if (self.newDeviceAvailable) self.newDeviceAvailable(self);
}
break;
case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: {
if (self.oldDeviceUnavailable) self.oldDeviceUnavailable(self);
}
break;
case AVAudioSessionRouteChangeReasonCategoryChange: {
if (self.categoryChange) self.categoryChange(self);
}
break;
}
});
}
- (void)volumeDidChangeNotification:(NSNotification *)notification {
float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
if (self.volumeChanged) self.volumeChanged(volume);
}
- (void)applicationWillResignActiveNotification {
self.backgroundState = ZFPlayerBackgroundStateBackground;
if (_willResignActive) _willResignActive(self);
}
- (void)applicationDidBecomeActiveNotification {
self.backgroundState = ZFPlayerBackgroundStateForeground;
if (_didBecomeActive) _didBecomeActive(self);
}
- (void)audioSessionInterruptionNotification:(NSNotification *)notification {
NSDictionary *interuptionDict = notification.userInfo;
AVAudioSessionInterruptionType interruptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
if (self.audioInterruptionCallback) self.audioInterruptionCallback(interruptionType);
}
@end
//
// ZFPlayerView.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#import "ZFPlayerConst.h"
@interface ZFPlayerView : UIView
/// player content view.
@property (nonatomic, strong) UIView *playerView;
/// Determines how the content scales to fit the view.
@property (nonatomic, assign) ZFPlayerScalingMode scalingMode;
/// The video size.
@property (nonatomic, assign) CGSize presentationSize;
/// The cover for playerView.
@property (nonatomic, strong, readonly) UIImageView *coverImageView;
@end
//
// ZFPlayerView.m
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFPlayerView.h"
#import "ZFPlayerConst.h"
@implementation ZFPlayerView
@synthesize presentationSize = _presentationSize;
@synthesize coverImageView = _coverImageView;
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundColor = [UIColor blackColor];
[self addSubview:self.coverImageView];
}
return self;
}
- (void)setPlayerView:(UIView *)playerView {
if (_playerView) {
[_playerView removeFromSuperview];
self.presentationSize = CGSizeZero;
}
_playerView = playerView;
if (playerView != nil) {
[self addSubview:playerView];
}
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat min_x = 0;
CGFloat min_y = 0;
CGFloat min_w = 0;
CGFloat min_h = 0;
CGFloat min_view_w = self.frame.size.width;
CGFloat min_view_h = self.frame.size.height;
CGSize playerViewSize = CGSizeZero;
CGFloat videoWidth = self.presentationSize.width;
CGFloat videoHeight = self.presentationSize.height;
if (videoHeight == 0) return;
CGFloat screenScale = min_view_w/min_view_h;
CGFloat videoScale = videoWidth/videoHeight;
if (screenScale > videoScale) {
CGFloat height = min_view_h;
CGFloat width = height * videoScale;
playerViewSize = CGSizeMake(width, height);
} else {
CGFloat width = min_view_w;
CGFloat height = width / videoScale;
playerViewSize = CGSizeMake(width, height);
}
if (self.scalingMode == ZFPlayerScalingModeNone || self.scalingMode == ZFPlayerScalingModeAspectFit) {
min_w = playerViewSize.width;
min_h = playerViewSize.height;
min_x = (min_view_w - min_w) / 2.0;
min_y = (min_view_h - min_h) / 2.0;
self.playerView.frame = CGRectMake(min_x, min_y, min_w, min_h);
} else if (self.scalingMode == ZFPlayerScalingModeAspectFill || self.scalingMode == ZFPlayerScalingModeFill) {
self.playerView.frame = self.bounds;
}
self.coverImageView.frame = self.playerView.frame;
}
- (CGSize)presentationSize {
if (CGSizeEqualToSize(_presentationSize, CGSizeZero)) {
_presentationSize = self.frame.size;
}
return _presentationSize;
}
- (UIImageView *)coverImageView {
if (!_coverImageView) {
_coverImageView = [[UIImageView alloc] init];
_coverImageView.userInteractionEnabled = YES;
_coverImageView.clipsToBounds = YES;
_coverImageView.contentMode = UIViewContentModeScaleAspectFit;
}
return _coverImageView;
}
- (void)setScalingMode:(ZFPlayerScalingMode)scalingMode {
_scalingMode = scalingMode;
if (scalingMode == ZFPlayerScalingModeNone || scalingMode == ZFPlayerScalingModeAspectFit) {
self.coverImageView.contentMode = UIViewContentModeScaleAspectFit;
} else if (scalingMode == ZFPlayerScalingModeAspectFill) {
self.coverImageView.contentMode = UIViewContentModeScaleAspectFill;
} else if (scalingMode == ZFPlayerScalingModeFill) {
self.coverImageView.contentMode = UIViewContentModeScaleToFill;
}
[self layoutIfNeeded];
}
- (void)setPresentationSize:(CGSize)presentationSize {
_presentationSize = presentationSize;
if (CGSizeEqualToSize(CGSizeZero, presentationSize)) return;
[self setNeedsLayout];
[self layoutIfNeeded];
}
@end
//
// ZFPortraitViewController.h
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#import "ZFOrientationObserver.h"
NS_ASSUME_NONNULL_BEGIN
@interface ZFPortraitViewController : UIViewController
/// The block invoked When player will rotate.
@property (nonatomic, copy, nullable) void(^orientationWillChange)(BOOL isFullScreen);
/// The block invoked when player rotated.
@property (nonatomic, copy, nullable) void(^orientationDidChanged)(BOOL isFullScreen);
@property (nonatomic, strong) UIView *contentView;
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, assign) BOOL statusBarHidden;
/// default is UIStatusBarStyleLightContent.
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
/// defalut is UIStatusBarAnimationSlide.
@property (nonatomic, assign) UIStatusBarAnimation statusBarAnimation;
/// default is ZFDisablePortraitGestureTypesNone.
@property (nonatomic, assign) ZFDisablePortraitGestureTypes disablePortraitGestureTypes;
@property (nonatomic, assign) CGSize presentationSize;
@property (nonatomic, assign) BOOL fullScreenAnimation;
@property (nonatomic, assign) NSTimeInterval duration;
@end
NS_ASSUME_NONNULL_END
//
// ZFPortraitViewController.m
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFPortraitViewController.h"
#import "ZFPersentInteractiveTransition.h"
#import "ZFPresentTransition.h"
@interface ZFPortraitViewController ()<UIViewControllerTransitioningDelegate,ZFPortraitOrientationDelegate>
@property (nonatomic, strong) ZFPresentTransition *transition;
@property (nonatomic, strong) ZFPersentInteractiveTransition *interactiveTransition;
@property (nonatomic, assign, getter=isFullScreen) BOOL fullScreen;
@end
@implementation ZFPortraitViewController
- (instancetype)init {
self = [super init];
if (self) {
self.transitioningDelegate = self;
self.modalPresentationStyle = UIModalPresentationOverFullScreen;
self.modalPresentationCapturesStatusBarAppearance = YES;
_statusBarStyle = UIStatusBarStyleLightContent;
_statusBarAnimation = UIStatusBarAnimationSlide;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!self.fullScreenAnimation) {
if (self.orientationWillChange) {
self.orientationWillChange(YES);
}
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (!self.fullScreenAnimation) {
self.view.alpha = 1;
[self.view addSubview:self.contentView];
self.contentView.frame = [self contentFullScreenRect];
if (self.orientationDidChanged) {
self.orientationDidChanged(YES);
}
}
self.fullScreen = YES;
[self.interactiveTransition updateContentView:self.contentView
containerView:self.containerView];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (!self.fullScreenAnimation) {
if (self.orientationWillChange) {
self.orientationWillChange(NO);
}
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
self.fullScreen = NO;
if (!self.fullScreenAnimation) {
[self.containerView addSubview:self.contentView];
self.contentView.frame = self.containerView.bounds;
if (self.orientationDidChanged) {
self.orientationDidChanged(NO);
}
}
}
#pragma mark - transition delegate
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
[self.transition transitionWithTransitionType:ZFPresentTransitionTypePresent contentView:self.contentView containerView:self.containerView];
return self.transition;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
[self.transition transitionWithTransitionType:ZFPresentTransitionTypeDismiss contentView:self.contentView containerView:self.containerView];
return self.transition;
}
- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator {
return self.interactiveTransition.interation ? self.interactiveTransition : nil;
}
- (BOOL)shouldAutorotate {
return NO;
}
- (BOOL)prefersStatusBarHidden {
return self.statusBarHidden;
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return self.statusBarStyle;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return self.statusBarAnimation;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
#pragma mark - ZFPortraitOrientationDelegate
- (void)zf_orientationWillChange:(BOOL)isFullScreen {
if (self.orientationWillChange) {
self.orientationWillChange(isFullScreen);
}
}
- (void)zf_orientationDidChanged:(BOOL)isFullScreen {
if (self.orientationDidChanged) {
self.orientationDidChanged(isFullScreen);
}
}
- (void)zf_interationState:(BOOL)isDragging {
self.transition.interation = isDragging;
}
#pragma mark - getter
- (ZFPresentTransition *)transition {
if (!_transition) {
_transition = [[ZFPresentTransition alloc] init];
_transition.contentFullScreenRect = [self contentFullScreenRect];
_transition.delagate = self;
}
return _transition;
}
- (ZFPersentInteractiveTransition *)interactiveTransition {
if (!_interactiveTransition) {
_interactiveTransition = [[ZFPersentInteractiveTransition alloc] init];
_interactiveTransition.contentFullScreenRect = [self contentFullScreenRect];
_interactiveTransition.viewController = self;
_interactiveTransition.delagate = self;
}
return _interactiveTransition;;
}
- (void)setDisablePortraitGestureTypes:(ZFDisablePortraitGestureTypes)disablePortraitGestureTypes {
_disablePortraitGestureTypes = disablePortraitGestureTypes;
self.interactiveTransition.disablePortraitGestureTypes = disablePortraitGestureTypes;
}
- (void)setPresentationSize:(CGSize)presentationSize {
_presentationSize = presentationSize;
self.transition.contentFullScreenRect = [self contentFullScreenRect];
self.interactiveTransition.contentFullScreenRect = [self contentFullScreenRect];
if (!self.fullScreenAnimation && self.isFullScreen) {
self.contentView.frame = [self contentFullScreenRect];
}
}
- (void)setFullScreen:(BOOL)fullScreen {
_fullScreen = fullScreen;
self.transition.fullScreen = fullScreen;
}
- (void)setFullScreenAnimation:(BOOL)fullScreenAnimation {
_fullScreenAnimation = fullScreenAnimation;
self.interactiveTransition.fullScreenAnimation = fullScreenAnimation;
}
- (void)setDuration:(NSTimeInterval)duration {
_duration = duration;
self.transition.duration = duration;
}
- (CGRect)contentFullScreenRect {
CGFloat videoWidth = self.presentationSize.width;
CGFloat videoHeight = self.presentationSize.height;
if (videoHeight == 0) {
return CGRectZero;
}
CGSize fullScreenScaleSize = CGSizeZero;
CGFloat screenScale = ZFPlayerScreenWidth/ZFPlayerScreenHeight;
CGFloat videoScale = videoWidth/videoHeight;
if (screenScale > videoScale) {
CGFloat height = ZFPlayerScreenHeight;
CGFloat width = height * videoScale;
fullScreenScaleSize = CGSizeMake(width, height);
} else {
CGFloat width = ZFPlayerScreenWidth;
CGFloat height = (CGFloat)(width / videoScale);
fullScreenScaleSize = CGSizeMake(width, height);
}
videoWidth = fullScreenScaleSize.width;
videoHeight = fullScreenScaleSize.height;
CGRect rect = CGRectMake((ZFPlayerScreenWidth - videoWidth) / 2.0, (ZFPlayerScreenHeight - videoHeight) / 2.0, videoWidth, videoHeight);
return rect;
}
@end
//
// ZFPresentTransition.h
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#import "ZFOrientationObserver.h"
typedef NS_ENUM(NSUInteger, ZFPresentTransitionType) {
ZFPresentTransitionTypePresent,
ZFPresentTransitionTypeDismiss,
};
@interface ZFPresentTransition : NSObject<UIViewControllerAnimatedTransitioning>
@property (nonatomic, weak) id<ZFPortraitOrientationDelegate> delagate;
@property (nonatomic, assign) CGRect contentFullScreenRect;
@property (nonatomic, assign, getter=isFullScreen) BOOL fullScreen;
@property (nonatomic, assign) BOOL interation;
@property (nonatomic, assign) NSTimeInterval duration;
- (void)transitionWithTransitionType:(ZFPresentTransitionType)type
contentView:(UIView *)contentView
containerView:(UIView *)containerView;
@end
//
// ZFPresentTransition.m
// ZFPlayer
//
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFPresentTransition.h"
#import "ZFPlayerConst.h"
@interface ZFPresentTransition ()
@property (nonatomic, strong) UIView *contentView;
@property (nonatomic, assign) ZFPresentTransitionType type;
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, assign, getter=isTransiting) BOOL transiting;
@end
@implementation ZFPresentTransition
- (void)transitionWithTransitionType:(ZFPresentTransitionType)type
contentView:(UIView *)contentView
containerView:(UIView *)containerView {
self.type = type;
self.contentView = contentView;
self.containerView = containerView;
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return self.duration == 0 ? 0.25f : self.duration;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
switch (self.type) {
case ZFPresentTransitionTypePresent: {
[self presentAnimation:transitionContext];
}
break;
case ZFPresentTransitionTypeDismiss: {
[self dismissAnimation:transitionContext];
}
break;
}
}
- (void)presentAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
if ([fromVC isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)fromVC;
fromVC = nav.viewControllers.lastObject;
} else if ([fromVC isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabBar = (UITabBarController *)fromVC;
if ([tabBar.selectedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)tabBar.selectedViewController;
fromVC = nav.viewControllers.lastObject;
} else {
fromVC = tabBar.selectedViewController;
}
}
UIView *containerView = [transitionContext containerView];
[containerView addSubview:toVC.view];
[containerView addSubview:self.contentView];
CGRect originRect = [self.containerView convertRect:self.contentView.frame toView:toVC.view];
self.contentView.frame = originRect;
UIColor *tempColor = toVC.view.backgroundColor;
toVC.view.backgroundColor = [tempColor colorWithAlphaComponent:0];
toVC.view.alpha = 1;
[self.delagate zf_orientationWillChange:YES];
CGRect toRect = self.contentFullScreenRect;
self.transiting = YES;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
self.contentView.frame = toRect;
[self.contentView layoutIfNeeded];
toVC.view.backgroundColor = [tempColor colorWithAlphaComponent:1.f];
} completion:^(BOOL finished) {
self.transiting = NO;
[toVC.view addSubview:self.contentView];
[transitionContext completeTransition:YES];
[self.delagate zf_orientationDidChanged:YES];
if (!CGRectEqualToRect(toRect, self.contentFullScreenRect)) {
self.contentView.frame = self.contentFullScreenRect;
[self.contentView layoutIfNeeded];
}
}];
}
- (void)dismissAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
UIView *containerView = [transitionContext containerView];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
if ([toVC isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)toVC;
toVC = nav.viewControllers.lastObject;
} else if ([toVC isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabBar = (UITabBarController *)toVC;
if ([tabBar.selectedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)tabBar.selectedViewController;
toVC = nav.viewControllers.lastObject;
} else {
toVC = tabBar.selectedViewController;
}
}
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
fromVC.view.frame = containerView.bounds;
[containerView addSubview:fromVC.view];
[containerView addSubview:self.contentView];
CGRect originRect = [fromVC.view convertRect:self.contentView.frame toView:toVC.view];
self.contentView.frame = originRect;
CGRect toRect = [self.containerView convertRect:self.containerView.bounds toView:toVC.view];
[fromVC.view convertRect:self.contentView.bounds toView:self.containerView.window];
[self.delagate zf_orientationWillChange:NO];
self.transiting = YES;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromVC.view.alpha = 0;
self.contentView.frame = toRect;
[self.contentView layoutIfNeeded];
} completion:^(BOOL finished) {
[self.containerView addSubview:self.contentView];
self.contentView.frame = self.containerView.bounds;
[transitionContext completeTransition:YES];
[self.delagate zf_orientationDidChanged:NO];
self.transiting = NO;
}];
}
- (void)setContentFullScreenRect:(CGRect)contentFullScreenRect {
_contentFullScreenRect = contentFullScreenRect;
if (!self.transiting && self.isFullScreen && !self.interation) {
self.contentView.frame = contentFullScreenRect;
}
}
@end
//
// ZFReachabilityManager.h
// ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#if !TARGET_OS_WATCH
#import <SystemConfiguration/SystemConfiguration.h>
typedef NS_ENUM(NSInteger, ZFReachabilityStatus) {
ZFReachabilityStatusUnknown = -1,
ZFReachabilityStatusNotReachable = 0,
ZFReachabilityStatusReachableViaWiFi = 1,
ZFReachabilityStatusReachableVia2G = 2,
ZFReachabilityStatusReachableVia3G = 3,
ZFReachabilityStatusReachableVia4G = 4,
};
NS_ASSUME_NONNULL_BEGIN
/**
`ZFReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability.
See Apple's Reachability Sample Code ( https://developer.apple.com/library/ios/samplecode/reachability/ )
@warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
*/
@interface ZFReachabilityManager : NSObject
/**
The current network reachability status.
*/
@property (readonly, nonatomic, assign) ZFReachabilityStatus networkReachabilityStatus;
/**
Whether or not the network is currently reachable.
*/
@property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable;
/**
Whether or not the network is currently reachable via WWAN.
*/
@property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN;
/**
Whether or not the network is currently reachable via WiFi.
*/
@property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi;
///---------------------
/// @name Initialization
///---------------------
/**
Returns the shared network reachability manager.
*/
+ (instancetype)sharedManager;
/**
Creates and returns a network reachability manager with the default socket address.
@return An initialized network reachability manager, actively monitoring the default socket address.
*/
+ (instancetype)manager;
/**
Creates and returns a network reachability manager for the specified domain.
@param domain The domain used to evaluate network reachability.
@return An initialized network reachability manager, actively monitoring the specified domain.
*/
+ (instancetype)managerForDomain:(NSString *)domain;
/**
Creates and returns a network reachability manager for the socket address.
@param address The socket address (`sockaddr_in6`) used to evaluate network reachability.
@return An initialized network reachability manager, actively monitoring the specified socket address.
*/
+ (instancetype)managerForAddress:(const void *)address;
/**
Initializes an instance of a network reachability manager from the specified reachability object.
@param reachability The reachability object to monitor.
@return An initialized network reachability manager, actively monitoring the specified reachability.
*/
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;
///--------------------------------------------------
/// @name Starting & Stopping Reachability Monitoring
///--------------------------------------------------
/**
Starts monitoring for changes in network reachability status.
*/
- (void)startMonitoring;
/**
Stops monitoring for changes in network reachability status.
*/
- (void)stopMonitoring;
///-------------------------------------------------
/// @name Getting Localized Reachability Description
///-------------------------------------------------
/**
Returns a localized string representation of the current network reachability status.
*/
- (NSString *)localizedNetworkReachabilityStatusString;
///---------------------------------------------------
/// @name Setting Network Reachability Change Callback
///---------------------------------------------------
/**
Sets a callback to be executed when the network availability of the `baseURL` host changes.
@param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`.
*/
- (void)setReachabilityStatusChangeBlock:(nullable void (^)(ZFReachabilityStatus status))block;
@end
///--------------------
/// @name Notifications
///--------------------
FOUNDATION_EXPORT NSString * const ZFReachabilityDidChangeNotification;
FOUNDATION_EXPORT NSString * const ZFReachabilityNotificationStatusItem;
///--------------------
/// @name Functions
///--------------------
/**
Returns a localized string representation of an `ZFReachabilityStatus` value.
*/
FOUNDATION_EXPORT NSString * ZFStringFromNetworkReachabilityStatus(ZFReachabilityStatus status);
NS_ASSUME_NONNULL_END
#endif
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!