al
liurenjie
2021-06-26 afc4a909befeb08739f73c7ef59fd1bf1b870287
al
302个文件已添加
64个文件已修改
60 文件已重命名
55个文件已删除
30767 ■■■■ 已修改文件
.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0.xcodeproj/project.pbxproj 530 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0.xcworkspace/xcuserdata/aeline.xcuserdatad/UserInterfaceState.xcuserstate 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0.xcworkspace/xcuserdata/aeline.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/AppDelegate.m 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Contents.json 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/Contents.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_more.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_more.imageset/home_more@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_more.imageset/home_more@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_change.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_change.imageset/home_recommend_change@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_change.imageset/home_recommend_change@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_gq.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_gq.imageset/home_recommend_gq@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_gq.imageset/home_recommend_gq@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_more.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_more.imageset/home_recommend_more@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_more.imageset/home_recommend_more@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_vip.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_vip.imageset/home_recommend_vip@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_vip.imageset/home_recommend_vip@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_record.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_record.imageset/home_recommend@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_record.imageset/home_recommend@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_search.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_search.imageset/home_search@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/home_search.imageset/home_search@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/search_delete.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/search_delete.imageset/search_delete@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/search_delete.imageset/search_delete@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/search_hot.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/search_hot.imageset/search_hot@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/Home/search_hot.imageset/search_hot@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/Contents.json 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_arrow.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_arrow.imageset/pptv_arrow@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_arrow.imageset/pptv_arrow@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_bg.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_bg.imageset/pptv_bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_bg.imageset/pptv_bg@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_copy.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_copy.imageset/pptv_copy@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_copy.imageset/pptv_copy@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_delete.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_delete.imageset/pptv_delete@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_delete.imageset/pptv_delete@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_more.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_more.imageset/pptv_more@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_more.imageset/pptv_more@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_other.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_other.imageset/形状 16@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_other.imageset/形状 16@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_refresh.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_refresh.imageset/pptv_refresh@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_refresh.imageset/pptv_refresh@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_vip_icon.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_vip_icon.imageset/pptv_vip_icon@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Assets.xcassets/视频详情页面/pptv_vip_icon.imageset/pptv_vip_icon@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/BaseViewController.m 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.bundle/Assets.car 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.bundle/Info.plist 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.bundle/bu_logo@2x.data 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.bundle/bu_logo@3x.data 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.bundle/bu_slienceAudio.aiff 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.bundle/ja.lproj/BULanguage.strings 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.bundle/version.txt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/BUAdSDK 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/BUAdSDK 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDK.h 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDKDefines.h 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDKError.h 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDKManager.h 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSlot.h 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUFullscreenVideoAd.h 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUImage.h 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUMaterialMeta.h 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeAd.h 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeAdRelatedView.h 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressAdViewDelegate.h 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressBannerView.h 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressFullscreenVideoAd.h 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressInterstitialAd.h 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressRewardedVideoAd.h 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressSplashView.h 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUPlayerPublicDefine.h 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BURewardedVideoAd.h 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUSplashAdView.h 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUVideoAdReportor.h 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUVideoAdView.h 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/PangleNativeBannerView.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/PangleNativeInterstitialView.h 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Info.plist 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Resources 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/BUAdSDK 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDK.h 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKConfiguration.h 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKDefines.h 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKError.h 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKManager.h 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKPlayableToolManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKTestToolManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSlot.h 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSmartlookManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUDislike.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUDislikeReportor.h 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUDislikeWords.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUFullscreenVideoAd.h 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUImage.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUMaterialMeta.h 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUMopubAdMarkUpDelegate.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeAd.h 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeAdRelatedView.h 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeAdsManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressAdManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressAdView.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressAdViewDelegate.h 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressBannerView.h 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressFullscreenVideoAd.h 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressInterstitialAd.h 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressRewardedVideoAd.h 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressSplashView.h 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUPersonalizationPrompts.h 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUPlayerPublicDefine.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BURewardedVideoAd.h 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BURewardedVideoModel.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUSize.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUSplashAdView.h 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUSplashZoomOutView.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUVideoAdDelegate.h 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUVideoAdReportor.h 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUVideoAdView.h 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/PangleNativeBannerView.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/PangleNativeInterstitialView.h 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/Current 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/BUCNAuxiliary 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/BUCNAuxiliary 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers/BUCNAuxiliary.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers/BUCNAuxiliaryManager.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers/BUCNCommonHeader.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Info.plist 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Modules/module.modulemap 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/BUCNAuxiliary 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUAppleBacktracesLog.h 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUBacktraceLog.h 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUEmbedAddressRange.h 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUHeaderLog.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUImageLog.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBULog.h 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HeimdallrBUEmbed.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HeimdallrBUEmbedConfig.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/Current 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/BUFoundation 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/BUFoundation 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUBundleHelper.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUCommonMacros.h 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUFoundation.h 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUFoundationAddress.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUGeckoPreloadManager.h 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUJSBDefine.h 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUJSInjectorRule.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUReachability.h 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BURexxarEngineFactory.h 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUTimer.h 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUUIResponderHelper.h 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUWebViewApplication.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSArray+BUUtilities.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSDictionary+BUUtilities.h 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSJSONSerialization+BUSafeSerializaiton.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSString+BUAddtion.h 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSUserDefaults+BUCrypt.h 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIColor+BUTheme.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIImage+BUIcon.h 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIImage+BUTransform.h 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIViewController+BUUtilities.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Info.plist 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/BUFoundation 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUBase64.h 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUBaseRequest.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUCacheManager.h 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUCommonMacros.h 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUConditionTracker.h 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUDynamicPlugin.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUEnvironment.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUFoundation.h 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUFoundationAddress.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUGeckoPreloadManager.h 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUGifImage.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUGifImageView.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUImageUtility.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBAuthorization.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBCommand.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBDefine.h 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBForwarding.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSInjector.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BULogMacros.h 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BULogManager.h 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUNetworkRequest.h 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPersistence.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayer.h 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerDefine.h 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerInternalDefine.h 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerItem.h 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerSettingsProtocol.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUReachability.h 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BURexxarEngine.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BURouter.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUScreenHelper.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUStaticPlugin.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUTNCRequestParam.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUTNCServiceManager.h 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUThreadSafeDictionary.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUThreadSafeMutableArray.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUTimer.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUUIResponderHelper.h 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUUserAgentHelper.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUVideoPrefetchManager.h 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUWKWebView.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUWebViewDefine.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUWebViewProgressView.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUZipArchive.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUZipCommon.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFAutoPurgingImageCache.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFHTTPSessionManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFSecurityPolicy.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFURLRequestSerialization.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFURLResponseSerialization.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFURLSessionManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImage.h 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImageRep.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImageView+BUWebCache.h 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImageView.h 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAsyncBlockOperation.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDDiskCache.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageAPNGCoder.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageAPNGCoderInternal.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageAssetManager.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCache.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCacheConfig.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCacheDefine.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCachesManager.h 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCachesManagerOperation.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCoder.h 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCoderHelper.h 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCodersManager.h 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageFrame.h 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageGIFCoder.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageGIFCoderInternal.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageGraphics.h 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageIOCoder.h 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageLoader.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageLoadersManager.h 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageTransformer.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDInternalMacros.h 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDMemoryCache.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWeakProxy.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageCacheKeyFilter.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageCacheSerializer.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageCompat.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDefine.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloader.h 290 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloaderConfig.h 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloaderOperation.h 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloaderRequestModifier.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageError.h 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageIndicator.h 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageManager.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageOperation.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageOptionsProcessor.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImagePrefetcher.h 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageTransition.h 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDmetamacros.h 667 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_ZFPlayer.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_ZFPlayerControlView.h 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSArray+BUUtilities.h 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSBezierPath+BURoundedCorners.h 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSButton+BUWebCache.h 340 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSData+BUImageContentType.h 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSDictionary+BUUtilities.h 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSImage+BUCompatibility.h 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSJSONSerialization+BUSafeSerializaiton.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSKeyedArchiver+BUKeyedArchiver.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSObject+BUSafeKVO.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSObject+BUUtils.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSPointerArray+BUSafely.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSString+BUAddtion.h 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSTimer+BUBlockSupport.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSUserDefaults+BUCrypt.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIButton+BUWebCache.h 387 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIColor+BUHexString.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIColor+BUTheme.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUForceDecode.h 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUGIF.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUMemoryCacheCost.h 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUMetadata.h 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUMultiFormat.h 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUTransform.h 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImageView+BUHighlightedWebCache.h 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImageView+BUWebCache.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImageView+BU_ZFCache.h 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIView+BUAdditions.h 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIView+BUWebCache.h 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIView+BUWebCacheOperation.h 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIViewController+BUUtilities.h 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIWindow+BUUtilities.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/Current 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Common.h 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Info.plist 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/JSAPI.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/JSAPI.m 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/LeftViewController.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/LeftViewController.m 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/LeftViewController.xib 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Nethader.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVBottomVIpVIew.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVBottomVIpVIew.m 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVController.m 139 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVDelegate.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVNavView.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVNavView.m 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVPopCell.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVPopCell.m 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVPppView.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/PPTVPppView.m 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/BaseController.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/BaseController.m 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/HDController/HDController.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/HDController/HDController.m 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/HDController/cell/HDHeaderCell.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/HDController/cell/HDHeaderCell.m 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/LifeHomeController.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/LifeHomeController.m 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/ListControlelr/ListController.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/ListControlelr/ListController.m 414 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/MainBaseController.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/MainBaseController.m 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/01.jpg 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/02.jpg 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/03.jpg 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/04.jpg 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/05.jpg 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendChangeFooterView.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendChangeFooterView.m 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendHeaderViewCell.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendHeaderViewCell.m 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendThreeColumnCell.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendThreeColumnCell.m 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendTwoColumnCell.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendTwoColumnCell.m 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecpmmendTitleView.h 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/RecpmmendTitleView.m 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/ToDayHotCell.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Cell/ToDayHotCell.m 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/Delegate/RecommendDelegate.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/RecommendController.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/Recommend/RecommendController.m 416 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/RecommendMainController.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/RecommendMainController.m 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/View/RecommendNavView.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/View/RecommendNavView.m 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarousel.h 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarousel.m 645 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarouselHeader.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarouselProtocol.h 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWFlowLayout.h 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWFlowLayout.m 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAbstractDotView.h 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAbstractDotView.m 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAnimatedDotView.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAnimatedDotView.m 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TADotView.h 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TADotView.m 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAPageControl.h 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAPageControl.m 364 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCollectionViewCell.h 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCollectionViewCell.m 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCycleScrollView.h 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCycleScrollView.m 706 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/UIView+SDExtension.h 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/UIView+SDExtension.m 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/UICollectionViewLeftAlignedLayout/UICollectionViewLeftAlignedLayout.h 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/Recommend/lib/UICollectionViewLeftAlignedLayout/UICollectionViewLeftAlignedLayout.m 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchController.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchController.m 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchHotCell.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchHotCell.m 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchHotSearchCell.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchHotSearchCell.m 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchNavView.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchNavView.m 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchRecordCell.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchRecordCell.m 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchRecordHeaderView.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/SearchRecordHeaderView.m 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/YTHNetInterface.h 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/YTHNetInterface.m 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/YTHNetdata.h 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/YTHNetdata.m 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/YTHsharedManger.h 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/UIView+ZJFrame.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/UIView+ZJFrame.m 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/UIViewController+ZJScrollPageController.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/UIViewController+ZJScrollPageController.m 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJCollectionView.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJCollectionView.m 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJContentView.h 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJContentView.m 574 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJScrollPageView.h 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJScrollPageView.m 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJScrollPageViewDelegate.h 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJScrollSegmentView.h 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJScrollSegmentView.m 738 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJSegmentStyle.h 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJSegmentStyle.m 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJTitleView.h 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/ZJScrollPageView/ZJTitleView.m 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/discoverView.m 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/discoverViewController.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/discoverViewController.m 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/DSCallInfo.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/DSCallInfo.m 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/DWKWebView.h 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/DWKWebView.m 494 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/InternalApis.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/InternalApis.m 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/JSBUtil.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/JSBUtil.m 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/dsbridge/dsbridge.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/recommendView.m 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/searchViewController.m 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/subregionView.m 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/subregionViewController.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/subregionViewController.m 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/猜你喜欢/GuessLikeViewController.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BuWanVideo2.0/猜你喜欢/GuessLikeViewController.m 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Podfile 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Podfile.lock 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Manifest.lock 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Pods.xcodeproj/project.pbxproj 2641 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/SDAutoLayout.xcscheme 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/xcschememanagement.plist 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/SDAutoLayout/LICENSE 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/SDAutoLayout/README.md 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/SDAutoLayout.h 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UITableView+SDAutoTableViewCellHeight.h 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UITableView+SDAutoTableViewCellHeight.m 537 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UIView+SDAutoLayout.h 484 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UIView+SDAutoLayout.m 1842 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/AFNetworking/AFNetworking.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/AFNetworking/AFNetworking.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-acknowledgements.markdown 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-acknowledgements.plist 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.debug.xcconfig 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.release.xcconfig 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDAutoLayout/SDAutoLayout-Info.plist 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDAutoLayout/SDAutoLayout-dummy.m 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDAutoLayout/SDAutoLayout-prefix.pch 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDAutoLayout/SDAutoLayout-umbrella.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDAutoLayout/SDAutoLayout.debug.xcconfig 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDAutoLayout/SDAutoLayout.modulemap 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDAutoLayout/SDAutoLayout.release.xcconfig 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SVProgressHUD/SVProgressHUD.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/SVProgressHUD/SVProgressHUD.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/UMCCommon/UMCCommon.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/UMCCommon/UMCCommon.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYCache/YYCache.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYCache/YYCache.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYImage/YYImage.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYImage/YYImage.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYModel/YYModel.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYModel/YYModel.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYWebImage/YYWebImage.debug.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pods/Target Support Files/YYWebImage/YYWebImage.release.xcconfig 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.DS_Store
Binary files differ
BuWanVideo2.0.xcodeproj/project.pbxproj
@@ -131,7 +131,31 @@
        2DECF92D22325172002FF49F /* GuessLikeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DECF92C22325172002FF49F /* GuessLikeViewController.m */; };
        2DECF93122325854002FF49F /* GuessLTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DECF92F22325854002FF49F /* GuessLTableViewCell.m */; };
        2DECF93222325854002FF49F /* GuessLTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2DECF93022325854002FF49F /* GuessLTableViewCell.xib */; };
        7034AC8426638BF30056133F /* RecommendChangeFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC8326638BF30056133F /* RecommendChangeFooterView.m */; };
        7034AC8826639A7B0056133F /* HDHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC8726639A7B0056133F /* HDHeaderCell.m */; };
        7034AC8E2663A03D0056133F /* SearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC8D2663A03D0056133F /* SearchController.m */; };
        7034AC922663A41C0056133F /* SearchNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC912663A41C0056133F /* SearchNavView.m */; };
        7034AC962663BC400056133F /* SearchHotCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC952663BC400056133F /* SearchHotCell.m */; };
        7034AC992663BCF00056133F /* SearchRecordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC982663BCF00056133F /* SearchRecordCell.m */; };
        7034AC9C2663BD650056133F /* SearchHotSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC9B2663BD650056133F /* SearchHotSearchCell.m */; };
        7034AC9F2663BDFE0056133F /* SearchRecordHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7034AC9E2663BDFE0056133F /* SearchRecordHeaderView.m */; };
        70452819250E2C610006C95E /* libGDTMobSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7045280E250E2C5F0006C95E /* libGDTMobSDK.a */; };
        704C1489265A936B009DAB98 /* BaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C1488265A936B009DAB98 /* BaseController.m */; };
        704C148C265A9393009DAB98 /* RecommendMainController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C148B265A9393009DAB98 /* RecommendMainController.m */; };
        704C14A1265A98A1009DAB98 /* RecommendNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14A0265A98A1009DAB98 /* RecommendNavView.m */; };
        704C14B8265B72A5009DAB98 /* UIView+ZJFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14A8265B72A5009DAB98 /* UIView+ZJFrame.m */; };
        704C14B9265B72A5009DAB98 /* ZJTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14AD265B72A5009DAB98 /* ZJTitleView.m */; };
        704C14BA265B72A5009DAB98 /* UIViewController+ZJScrollPageController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14AE265B72A5009DAB98 /* UIViewController+ZJScrollPageController.m */; };
        704C14BB265B72A5009DAB98 /* ZJContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14B1265B72A5009DAB98 /* ZJContentView.m */; };
        704C14BC265B72A5009DAB98 /* ZJCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14B2265B72A5009DAB98 /* ZJCollectionView.m */; };
        704C14BD265B72A5009DAB98 /* ZJSegmentStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14B3265B72A5009DAB98 /* ZJSegmentStyle.m */; };
        704C14BE265B72A5009DAB98 /* ZJScrollSegmentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14B4265B72A5009DAB98 /* ZJScrollSegmentView.m */; };
        704C14BF265B72A5009DAB98 /* ZJScrollPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14B5265B72A5009DAB98 /* ZJScrollPageView.m */; };
        704C14C2265B7623009DAB98 /* RecommendController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14C1265B7623009DAB98 /* RecommendController.m */; };
        704C14C5265B767D009DAB98 /* LifeHomeController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14C4265B767D009DAB98 /* LifeHomeController.m */; };
        704C14C8265B76BA009DAB98 /* HDController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14C7265B76BA009DAB98 /* HDController.m */; };
        704C14CB265B76D2009DAB98 /* ListController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14CA265B76D2009DAB98 /* ListController.m */; };
        704C14CE265B8E38009DAB98 /* MainBaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 704C14CD265B8E38009DAB98 /* MainBaseController.m */; };
        705951F425161153008E0CDF /* SearchTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 705951F325161153008E0CDF /* SearchTitleView.m */; };
        705951F7251633E9008E0CDF /* SearchDetailListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 705951F6251633E9008E0CDF /* SearchDetailListCell.m */; };
        705F1E84251F085D0065350E /* Share.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1E82251F085D0065350E /* Share.m */; };
@@ -159,11 +183,40 @@
        705F1F83251F1CA80065350E /* MJRefreshAutoFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F68251F1CA70065350E /* MJRefreshAutoFooter.m */; };
        705F1F84251F1CA80065350E /* MJRefreshComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F6A251F1CA70065350E /* MJRefreshComponent.m */; };
        705F1F85251F1CA80065350E /* MJRefreshTrailer.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F6D251F1CA70065350E /* MJRefreshTrailer.m */; };
        70D5933E25EA17AB00438F1A /* BUAdSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70D5933A25EA17A900438F1A /* BUAdSDK.framework */; };
        70D5933F25EA17AB00438F1A /* BUCNAuxiliary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70D5933B25EA17AA00438F1A /* BUCNAuxiliary.framework */; };
        70D5934025EA17AB00438F1A /* BUAdSDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 70D5933C25EA17AA00438F1A /* BUAdSDK.bundle */; };
        70D5934125EA17AB00438F1A /* BUFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70D5933D25EA17AB00438F1A /* BUFoundation.framework */; };
        706CECB9264F6F72001FBEB7 /* BUAdSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 706CECB5264F6F6F001FBEB7 /* BUAdSDK.framework */; };
        706CECBA264F6F72001FBEB7 /* BUFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 706CECB6264F6F71001FBEB7 /* BUFoundation.framework */; };
        706CECBB264F6F72001FBEB7 /* BUCNAuxiliary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 706CECB7264F6F72001FBEB7 /* BUCNAuxiliary.framework */; };
        706CECBC264F6F72001FBEB7 /* BUAdSDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 706CECB8264F6F72001FBEB7 /* BUAdSDK.bundle */; };
        706CECC0264F76C1001FBEB7 /* PPTVNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECBF264F76C1001FBEB7 /* PPTVNavView.m */; };
        706CECC5264F94CC001FBEB7 /* PPTVPppView.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECC4264F94CC001FBEB7 /* PPTVPppView.m */; };
        706CECC9264F97EB001FBEB7 /* PPTVPopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECC8264F97EB001FBEB7 /* PPTVPopCell.m */; };
        706CECD4264FB895001FBEB7 /* DSCallInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECCD264FB895001FBEB7 /* DSCallInfo.m */; };
        706CECD5264FB895001FBEB7 /* InternalApis.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECD1264FB895001FBEB7 /* InternalApis.m */; };
        706CECD6264FB895001FBEB7 /* JSBUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECD2264FB895001FBEB7 /* JSBUtil.m */; };
        706CECD7264FB895001FBEB7 /* DWKWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECD3264FB895001FBEB7 /* DWKWebView.m */; };
        706CECDB264FB8CB001FBEB7 /* JSAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECDA264FB8CB001FBEB7 /* JSAPI.m */; };
        706CECDE264FC2A7001FBEB7 /* PPTVBottomVIpVIew.m in Sources */ = {isa = PBXBuildFile; fileRef = 706CECDD264FC2A7001FBEB7 /* PPTVBottomVIpVIew.m */; };
        70D5934525EA1FAE00438F1A /* PPTVController.m in Sources */ = {isa = PBXBuildFile; fileRef = 70D5934425EA1FAE00438F1A /* PPTVController.m */; };
        70ED36BC266233EC00E51E79 /* CWCarousel.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36B6266233EC00E51E79 /* CWCarousel.m */; };
        70ED36BD266233EC00E51E79 /* CWFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36B8266233EC00E51E79 /* CWFlowLayout.m */; };
        70ED36C826623CCC00E51E79 /* 01.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 70ED36C326623CCB00E51E79 /* 01.jpg */; };
        70ED36C926623CCC00E51E79 /* 02.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 70ED36C426623CCB00E51E79 /* 02.jpg */; };
        70ED36CA26623CCC00E51E79 /* 03.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 70ED36C526623CCB00E51E79 /* 03.jpg */; };
        70ED36CB26623CCC00E51E79 /* 04.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 70ED36C626623CCC00E51E79 /* 04.jpg */; };
        70ED36CC26623CCC00E51E79 /* 05.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 70ED36C726623CCC00E51E79 /* 05.jpg */; };
        70ED36D026624BAE00E51E79 /* UICollectionViewLeftAlignedLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36CF26624BAE00E51E79 /* UICollectionViewLeftAlignedLayout.m */; };
        70ED36D926624F4700E51E79 /* RecommendHeaderViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36D826624F4700E51E79 /* RecommendHeaderViewCell.m */; };
        70ED36DC266250B800E51E79 /* RecpmmendTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36DB266250B800E51E79 /* RecpmmendTitleView.m */; };
        70ED36DF26625AF600E51E79 /* ToDayHotCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36DE26625AF600E51E79 /* ToDayHotCell.m */; };
        70ED36E2266264D900E51E79 /* RecommendTwoColumnCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36E1266264D900E51E79 /* RecommendTwoColumnCell.m */; };
        70ED36E526627D4500E51E79 /* RecommendThreeColumnCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36E426627D4500E51E79 /* RecommendThreeColumnCell.m */; };
        70ED36F6266280EA00E51E79 /* SDCycleScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36EA266280EA00E51E79 /* SDCycleScrollView.m */; };
        70ED36F7266280EA00E51E79 /* UIView+SDExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36EB266280EA00E51E79 /* UIView+SDExtension.m */; };
        70ED36F8266280EA00E51E79 /* SDCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36EC266280EA00E51E79 /* SDCollectionViewCell.m */; };
        70ED36F9266280EA00E51E79 /* TADotView.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36EF266280EA00E51E79 /* TADotView.m */; };
        70ED36FA266280EA00E51E79 /* TAPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36F0266280EA00E51E79 /* TAPageControl.m */; };
        70ED36FB266280EA00E51E79 /* TAAnimatedDotView.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36F1266280EA00E51E79 /* TAAnimatedDotView.m */; };
        70ED36FC266280EA00E51E79 /* TAAbstractDotView.m in Sources */ = {isa = PBXBuildFile; fileRef = 70ED36F2266280EA00E51E79 /* TAAbstractDotView.m */; };
        7B0D3B2C1D59BCAB003E74A8 /* AnimationTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B0D3B271D59BCAB003E74A8 /* AnimationTool.m */; };
        7B0D3B2D1D59BCAB003E74A8 /* CMuneBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B0D3B291D59BCAB003E74A8 /* CMuneBar.m */; };
        7B0D3B2E1D59BCAB003E74A8 /* CMuneItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B0D3B2B1D59BCAB003E74A8 /* CMuneItem.m */; };
@@ -543,6 +596,22 @@
        2DECF92F22325854002FF49F /* GuessLTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GuessLTableViewCell.m; sourceTree = "<group>"; };
        2DECF93022325854002FF49F /* GuessLTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GuessLTableViewCell.xib; sourceTree = "<group>"; };
        5326AC3933907F23F3929227 /* Pods-BuWanVideo2.0.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BuWanVideo2.0.release.xcconfig"; path = "Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.release.xcconfig"; sourceTree = "<group>"; };
        7034AC8226638BF30056133F /* RecommendChangeFooterView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendChangeFooterView.h; sourceTree = "<group>"; };
        7034AC8326638BF30056133F /* RecommendChangeFooterView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecommendChangeFooterView.m; sourceTree = "<group>"; };
        7034AC8626639A7B0056133F /* HDHeaderCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HDHeaderCell.h; sourceTree = "<group>"; };
        7034AC8726639A7B0056133F /* HDHeaderCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HDHeaderCell.m; sourceTree = "<group>"; };
        7034AC8C2663A03D0056133F /* SearchController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchController.h; sourceTree = "<group>"; };
        7034AC8D2663A03D0056133F /* SearchController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchController.m; sourceTree = "<group>"; };
        7034AC902663A41C0056133F /* SearchNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchNavView.h; sourceTree = "<group>"; };
        7034AC912663A41C0056133F /* SearchNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchNavView.m; sourceTree = "<group>"; };
        7034AC942663BC400056133F /* SearchHotCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchHotCell.h; sourceTree = "<group>"; };
        7034AC952663BC400056133F /* SearchHotCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchHotCell.m; sourceTree = "<group>"; };
        7034AC972663BCF00056133F /* SearchRecordCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchRecordCell.h; sourceTree = "<group>"; };
        7034AC982663BCF00056133F /* SearchRecordCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchRecordCell.m; sourceTree = "<group>"; };
        7034AC9A2663BD650056133F /* SearchHotSearchCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchHotSearchCell.h; sourceTree = "<group>"; };
        7034AC9B2663BD650056133F /* SearchHotSearchCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchHotSearchCell.m; sourceTree = "<group>"; };
        7034AC9D2663BDFE0056133F /* SearchRecordHeaderView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchRecordHeaderView.h; sourceTree = "<group>"; };
        7034AC9E2663BDFE0056133F /* SearchRecordHeaderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchRecordHeaderView.m; sourceTree = "<group>"; };
        70452801250E2C5C0006C95E /* GDTSDKDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTSDKDefines.h; sourceTree = "<group>"; };
        70452802250E2C5C0006C95E /* GDTRewardVideoAdNetworkConnectorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTRewardVideoAdNetworkConnectorProtocol.h; sourceTree = "<group>"; };
        70452803250E2C5C0006C95E /* GDTMediaView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTMediaView.h; sourceTree = "<group>"; };
@@ -567,6 +636,40 @@
        70452816250E2C600006C95E /* GDTRewardVideoAdNetworkAdapterProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTRewardVideoAdNetworkAdapterProtocol.h; sourceTree = "<group>"; };
        70452817250E2C600006C95E /* GDTUnifiedNativeAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTUnifiedNativeAd.h; sourceTree = "<group>"; };
        70452818250E2C610006C95E /* GDTUnifiedNativeAdView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTUnifiedNativeAdView.h; sourceTree = "<group>"; };
        704C1487265A936B009DAB98 /* BaseController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseController.h; sourceTree = "<group>"; };
        704C1488265A936B009DAB98 /* BaseController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseController.m; sourceTree = "<group>"; };
        704C148A265A9393009DAB98 /* RecommendMainController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendMainController.h; sourceTree = "<group>"; };
        704C148B265A9393009DAB98 /* RecommendMainController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecommendMainController.m; sourceTree = "<group>"; };
        704C149F265A98A1009DAB98 /* RecommendNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendNavView.h; sourceTree = "<group>"; };
        704C14A0265A98A1009DAB98 /* RecommendNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecommendNavView.m; sourceTree = "<group>"; };
        704C14A7265B72A5009DAB98 /* ZJContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZJContentView.h; sourceTree = "<group>"; };
        704C14A8265B72A5009DAB98 /* UIView+ZJFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ZJFrame.m"; sourceTree = "<group>"; };
        704C14A9265B72A5009DAB98 /* ZJCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZJCollectionView.h; sourceTree = "<group>"; };
        704C14AA265B72A5009DAB98 /* ZJScrollSegmentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZJScrollSegmentView.h; sourceTree = "<group>"; };
        704C14AB265B72A5009DAB98 /* ZJScrollPageViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZJScrollPageViewDelegate.h; sourceTree = "<group>"; };
        704C14AC265B72A5009DAB98 /* ZJSegmentStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZJSegmentStyle.h; sourceTree = "<group>"; };
        704C14AD265B72A5009DAB98 /* ZJTitleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZJTitleView.m; sourceTree = "<group>"; };
        704C14AE265B72A5009DAB98 /* UIViewController+ZJScrollPageController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+ZJScrollPageController.m"; sourceTree = "<group>"; };
        704C14AF265B72A5009DAB98 /* ZJScrollPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZJScrollPageView.h; sourceTree = "<group>"; };
        704C14B0265B72A5009DAB98 /* UIView+ZJFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ZJFrame.h"; sourceTree = "<group>"; };
        704C14B1265B72A5009DAB98 /* ZJContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZJContentView.m; sourceTree = "<group>"; };
        704C14B2265B72A5009DAB98 /* ZJCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZJCollectionView.m; sourceTree = "<group>"; };
        704C14B3265B72A5009DAB98 /* ZJSegmentStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZJSegmentStyle.m; sourceTree = "<group>"; };
        704C14B4265B72A5009DAB98 /* ZJScrollSegmentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZJScrollSegmentView.m; sourceTree = "<group>"; };
        704C14B5265B72A5009DAB98 /* ZJScrollPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZJScrollPageView.m; sourceTree = "<group>"; };
        704C14B6265B72A5009DAB98 /* UIViewController+ZJScrollPageController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+ZJScrollPageController.h"; sourceTree = "<group>"; };
        704C14B7265B72A5009DAB98 /* ZJTitleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZJTitleView.h; sourceTree = "<group>"; };
        704C14C0265B7623009DAB98 /* RecommendController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendController.h; sourceTree = "<group>"; };
        704C14C1265B7623009DAB98 /* RecommendController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecommendController.m; sourceTree = "<group>"; };
        704C14C3265B767D009DAB98 /* LifeHomeController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LifeHomeController.h; sourceTree = "<group>"; };
        704C14C4265B767D009DAB98 /* LifeHomeController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LifeHomeController.m; sourceTree = "<group>"; };
        704C14C6265B76BA009DAB98 /* HDController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HDController.h; sourceTree = "<group>"; };
        704C14C7265B76BA009DAB98 /* HDController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HDController.m; sourceTree = "<group>"; };
        704C14C9265B76D2009DAB98 /* ListController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ListController.h; sourceTree = "<group>"; };
        704C14CA265B76D2009DAB98 /* ListController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ListController.m; sourceTree = "<group>"; };
        704C14CC265B8E38009DAB98 /* MainBaseController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainBaseController.h; sourceTree = "<group>"; };
        704C14CD265B8E38009DAB98 /* MainBaseController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainBaseController.m; sourceTree = "<group>"; };
        7054B445266B8625002B6504 /* RecommendDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendDelegate.h; sourceTree = "<group>"; };
        705951F225161153008E0CDF /* SearchTitleView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchTitleView.h; sourceTree = "<group>"; };
        705951F325161153008E0CDF /* SearchTitleView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchTitleView.m; sourceTree = "<group>"; };
        705951F5251633E9008E0CDF /* SearchDetailListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchDetailListCell.h; sourceTree = "<group>"; };
@@ -621,12 +724,69 @@
        705F1F6B251F1CA70065350E /* MJRefreshFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshFooter.h; sourceTree = "<group>"; };
        705F1F6C251F1CA70065350E /* MJRefreshBackFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackFooter.h; sourceTree = "<group>"; };
        705F1F6D251F1CA70065350E /* MJRefreshTrailer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshTrailer.m; sourceTree = "<group>"; };
        70D5933A25EA17A900438F1A /* BUAdSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUAdSDK.framework; sourceTree = "<group>"; };
        70D5933B25EA17AA00438F1A /* BUCNAuxiliary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUCNAuxiliary.framework; sourceTree = "<group>"; };
        70D5933C25EA17AA00438F1A /* BUAdSDK.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = BUAdSDK.bundle; sourceTree = "<group>"; };
        70D5933D25EA17AB00438F1A /* BUFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUFoundation.framework; sourceTree = "<group>"; };
        706CECB5264F6F6F001FBEB7 /* BUAdSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUAdSDK.framework; sourceTree = "<group>"; };
        706CECB6264F6F71001FBEB7 /* BUFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUFoundation.framework; sourceTree = "<group>"; };
        706CECB7264F6F72001FBEB7 /* BUCNAuxiliary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUCNAuxiliary.framework; sourceTree = "<group>"; };
        706CECB8264F6F72001FBEB7 /* BUAdSDK.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = BUAdSDK.bundle; sourceTree = "<group>"; };
        706CECBE264F76C1001FBEB7 /* PPTVNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PPTVNavView.h; sourceTree = "<group>"; };
        706CECBF264F76C1001FBEB7 /* PPTVNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PPTVNavView.m; sourceTree = "<group>"; };
        706CECC2264F7C31001FBEB7 /* PPTVDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PPTVDelegate.h; sourceTree = "<group>"; };
        706CECC3264F94CC001FBEB7 /* PPTVPppView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PPTVPppView.h; sourceTree = "<group>"; };
        706CECC4264F94CC001FBEB7 /* PPTVPppView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PPTVPppView.m; sourceTree = "<group>"; };
        706CECC7264F97EB001FBEB7 /* PPTVPopCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PPTVPopCell.h; sourceTree = "<group>"; };
        706CECC8264F97EB001FBEB7 /* PPTVPopCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PPTVPopCell.m; sourceTree = "<group>"; };
        706CECCB264FB895001FBEB7 /* dsbridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsbridge.h; sourceTree = "<group>"; };
        706CECCC264FB895001FBEB7 /* InternalApis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalApis.h; sourceTree = "<group>"; };
        706CECCD264FB895001FBEB7 /* DSCallInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DSCallInfo.m; sourceTree = "<group>"; };
        706CECCE264FB895001FBEB7 /* JSBUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBUtil.h; sourceTree = "<group>"; };
        706CECCF264FB895001FBEB7 /* DWKWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWKWebView.h; sourceTree = "<group>"; };
        706CECD0264FB895001FBEB7 /* DSCallInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSCallInfo.h; sourceTree = "<group>"; };
        706CECD1264FB895001FBEB7 /* InternalApis.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InternalApis.m; sourceTree = "<group>"; };
        706CECD2264FB895001FBEB7 /* JSBUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSBUtil.m; sourceTree = "<group>"; };
        706CECD3264FB895001FBEB7 /* DWKWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DWKWebView.m; sourceTree = "<group>"; };
        706CECD9264FB8CB001FBEB7 /* JSAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSAPI.h; sourceTree = "<group>"; };
        706CECDA264FB8CB001FBEB7 /* JSAPI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JSAPI.m; sourceTree = "<group>"; };
        706CECDC264FC2A7001FBEB7 /* PPTVBottomVIpVIew.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PPTVBottomVIpVIew.h; sourceTree = "<group>"; };
        706CECDD264FC2A7001FBEB7 /* PPTVBottomVIpVIew.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PPTVBottomVIpVIew.m; sourceTree = "<group>"; };
        70D5934325EA1FAE00438F1A /* PPTVController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PPTVController.h; sourceTree = "<group>"; };
        70D5934425EA1FAE00438F1A /* PPTVController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PPTVController.m; sourceTree = "<group>"; };
        70ED36B6266233EC00E51E79 /* CWCarousel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CWCarousel.m; sourceTree = "<group>"; };
        70ED36B7266233EC00E51E79 /* CWCarouselHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWCarouselHeader.h; sourceTree = "<group>"; };
        70ED36B8266233EC00E51E79 /* CWFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CWFlowLayout.m; sourceTree = "<group>"; };
        70ED36B9266233EC00E51E79 /* CWCarouselProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWCarouselProtocol.h; sourceTree = "<group>"; };
        70ED36BA266233EC00E51E79 /* CWCarousel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWCarousel.h; sourceTree = "<group>"; };
        70ED36BB266233EC00E51E79 /* CWFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWFlowLayout.h; sourceTree = "<group>"; };
        70ED36C326623CCB00E51E79 /* 01.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 01.jpg; sourceTree = "<group>"; };
        70ED36C426623CCB00E51E79 /* 02.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 02.jpg; sourceTree = "<group>"; };
        70ED36C526623CCB00E51E79 /* 03.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 03.jpg; sourceTree = "<group>"; };
        70ED36C626623CCC00E51E79 /* 04.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 04.jpg; sourceTree = "<group>"; };
        70ED36C726623CCC00E51E79 /* 05.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 05.jpg; sourceTree = "<group>"; };
        70ED36CE26624BAE00E51E79 /* UICollectionViewLeftAlignedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICollectionViewLeftAlignedLayout.h; sourceTree = "<group>"; };
        70ED36CF26624BAE00E51E79 /* UICollectionViewLeftAlignedLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICollectionViewLeftAlignedLayout.m; sourceTree = "<group>"; };
        70ED36D726624F4700E51E79 /* RecommendHeaderViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendHeaderViewCell.h; sourceTree = "<group>"; };
        70ED36D826624F4700E51E79 /* RecommendHeaderViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecommendHeaderViewCell.m; sourceTree = "<group>"; };
        70ED36DA266250B800E51E79 /* RecpmmendTitleView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecpmmendTitleView.h; sourceTree = "<group>"; };
        70ED36DB266250B800E51E79 /* RecpmmendTitleView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecpmmendTitleView.m; sourceTree = "<group>"; };
        70ED36DD26625AF600E51E79 /* ToDayHotCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToDayHotCell.h; sourceTree = "<group>"; };
        70ED36DE26625AF600E51E79 /* ToDayHotCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ToDayHotCell.m; sourceTree = "<group>"; };
        70ED36E0266264D900E51E79 /* RecommendTwoColumnCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendTwoColumnCell.h; sourceTree = "<group>"; };
        70ED36E1266264D900E51E79 /* RecommendTwoColumnCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecommendTwoColumnCell.m; sourceTree = "<group>"; };
        70ED36E326627D4500E51E79 /* RecommendThreeColumnCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecommendThreeColumnCell.h; sourceTree = "<group>"; };
        70ED36E426627D4500E51E79 /* RecommendThreeColumnCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecommendThreeColumnCell.m; sourceTree = "<group>"; };
        70ED36E7266280EA00E51E79 /* UIView+SDExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+SDExtension.h"; sourceTree = "<group>"; };
        70ED36E8266280EA00E51E79 /* SDCycleScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDCycleScrollView.h; sourceTree = "<group>"; };
        70ED36E9266280EA00E51E79 /* SDCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDCollectionViewCell.h; sourceTree = "<group>"; };
        70ED36EA266280EA00E51E79 /* SDCycleScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDCycleScrollView.m; sourceTree = "<group>"; };
        70ED36EB266280EA00E51E79 /* UIView+SDExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SDExtension.m"; sourceTree = "<group>"; };
        70ED36EC266280EA00E51E79 /* SDCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDCollectionViewCell.m; sourceTree = "<group>"; };
        70ED36EE266280EA00E51E79 /* TAAbstractDotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TAAbstractDotView.h; sourceTree = "<group>"; };
        70ED36EF266280EA00E51E79 /* TADotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TADotView.m; sourceTree = "<group>"; };
        70ED36F0266280EA00E51E79 /* TAPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TAPageControl.m; sourceTree = "<group>"; };
        70ED36F1266280EA00E51E79 /* TAAnimatedDotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TAAnimatedDotView.m; sourceTree = "<group>"; };
        70ED36F2266280EA00E51E79 /* TAAbstractDotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TAAbstractDotView.m; sourceTree = "<group>"; };
        70ED36F3266280EA00E51E79 /* TADotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TADotView.h; sourceTree = "<group>"; };
        70ED36F4266280EA00E51E79 /* TAAnimatedDotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TAAnimatedDotView.h; sourceTree = "<group>"; };
        70ED36F5266280EA00E51E79 /* TAPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TAPageControl.h; sourceTree = "<group>"; };
        7B0D3B261D59BCAB003E74A8 /* AnimationTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationTool.h; sourceTree = "<group>"; };
        7B0D3B271D59BCAB003E74A8 /* AnimationTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnimationTool.m; sourceTree = "<group>"; };
        7B0D3B281D59BCAB003E74A8 /* CMuneBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMuneBar.h; sourceTree = "<group>"; };
@@ -892,13 +1052,14 @@
                184DBB321DDB0BB00034B39B /* libc++abi.tbd in Frameworks */,
                18F5CA971E1C862D001F526F /* libc++.tbd in Frameworks */,
                7B389BE21D61B2F90043A2F2 /* libc++.1.tbd in Frameworks */,
                706CECBB264F6F72001FBEB7 /* BUCNAuxiliary.framework in Frameworks */,
                2D732550212D6B5200E09821 /* WebP.framework in Frameworks */,
                2D73254E212D626B00E09821 /* YYWebImage.framework in Frameworks */,
                2D73254C212D626600E09821 /* YYCache.framework in Frameworks */,
                706CECBA264F6F72001FBEB7 /* BUFoundation.framework in Frameworks */,
                2D73254A212D626000E09821 /* YYImage.framework in Frameworks */,
                7B8AC4F01D5D802200450285 /* CFNetwork.framework in Frameworks */,
                7B8AC5221D5D822F00450285 /* CoreMotion.framework in Frameworks */,
                70D5933F25EA17AB00438F1A /* BUCNAuxiliary.framework in Frameworks */,
                7B8AC50A1D5D80A500450285 /* Security.framework in Frameworks */,
                7B8AC4EA1D5D7FFC00450285 /* libz.tbd in Frameworks */,
                7B8AC4F61D5D804100450285 /* CoreMedia.framework in Frameworks */,
@@ -933,7 +1094,7 @@
                7B389BDC1D61B1D10043A2F2 /* ModelIO.framework in Frameworks */,
                1845BB4B209BF212009C639B /* PassKit.framework in Frameworks */,
                7B8AC52C1D5D828000450285 /* libz.1.2.5.tbd in Frameworks */,
                70D5933E25EA17AB00438F1A /* BUAdSDK.framework in Frameworks */,
                706CECB9264F6F72001FBEB7 /* BUAdSDK.framework in Frameworks */,
                7B1FF0DF1D6711CF00E6C207 /* libiconv.tbd in Frameworks */,
                1877D1791DCAE119000CEC83 /* JavaScriptCore.framework in Frameworks */,
                1877D1771DCAE100000CEC83 /* CoreData.framework in Frameworks */,
@@ -951,7 +1112,6 @@
                7B8AC5141D5D810A00450285 /* Accelerate.framework in Frameworks */,
                7B8AC5121D5D80F700450285 /* libxml2.tbd in Frameworks */,
                7B8AC5021D5D807F00450285 /* MapKit.framework in Frameworks */,
                70D5934125EA17AB00438F1A /* BUFoundation.framework in Frameworks */,
                7B8AC4FE1D5D806A00450285 /* EventKitUI.framework in Frameworks */,
                7B8AC4EC1D5D800B00450285 /* libsqlite3.0.tbd in Frameworks */,
                8619598F33C90A9D1035A2BD /* Pods_BuWanVideo2_0.framework in Frameworks */,
@@ -1139,6 +1299,7 @@
        18A8D14C1DC32CFD00A03FB7 /* æŽ¨è */ = {
            isa = PBXGroup;
            children = (
                704C148D265A93E2009DAB98 /* Recommend */,
                18E943E42057656C0019FD04 /* recommendViewController.h */,
                18E943E52057656C0019FD04 /* recommendViewController.m */,
                7B32BD2D1D4F259300E96E75 /* recommendView.h */,
@@ -1340,15 +1501,139 @@
            path = "猜你喜欢";
            sourceTree = "<group>";
        };
        7034AC85266399C70056133F /* HDController */ = {
            isa = PBXGroup;
            children = (
                7034AC8926639A7F0056133F /* cell */,
                704C14C6265B76BA009DAB98 /* HDController.h */,
                704C14C7265B76BA009DAB98 /* HDController.m */,
            );
            path = HDController;
            sourceTree = "<group>";
        };
        7034AC8926639A7F0056133F /* cell */ = {
            isa = PBXGroup;
            children = (
                7034AC8626639A7B0056133F /* HDHeaderCell.h */,
                7034AC8726639A7B0056133F /* HDHeaderCell.m */,
            );
            path = cell;
            sourceTree = "<group>";
        };
        7034AC8A26639BC80056133F /* ListControlelr */ = {
            isa = PBXGroup;
            children = (
                704C14C9265B76D2009DAB98 /* ListController.h */,
                704C14CA265B76D2009DAB98 /* ListController.m */,
            );
            path = ListControlelr;
            sourceTree = "<group>";
        };
        7034AC8B2663A0200056133F /* SearchNew */ = {
            isa = PBXGroup;
            children = (
                7034AC932663BBCA0056133F /* Cell */,
                7034AC8F2663A4060056133F /* View */,
                7034AC8C2663A03D0056133F /* SearchController.h */,
                7034AC8D2663A03D0056133F /* SearchController.m */,
            );
            name = SearchNew;
            sourceTree = "<group>";
        };
        7034AC8F2663A4060056133F /* View */ = {
            isa = PBXGroup;
            children = (
                7034AC902663A41C0056133F /* SearchNavView.h */,
                7034AC912663A41C0056133F /* SearchNavView.m */,
            );
            name = View;
            sourceTree = "<group>";
        };
        7034AC932663BBCA0056133F /* Cell */ = {
            isa = PBXGroup;
            children = (
                7034AC942663BC400056133F /* SearchHotCell.h */,
                7034AC952663BC400056133F /* SearchHotCell.m */,
                7034AC972663BCF00056133F /* SearchRecordCell.h */,
                7034AC982663BCF00056133F /* SearchRecordCell.m */,
                7034AC9A2663BD650056133F /* SearchHotSearchCell.h */,
                7034AC9B2663BD650056133F /* SearchHotSearchCell.m */,
                7034AC9D2663BDFE0056133F /* SearchRecordHeaderView.h */,
                7034AC9E2663BDFE0056133F /* SearchRecordHeaderView.m */,
            );
            name = Cell;
            sourceTree = "<group>";
        };
        7042C94A2515A4FE0017F5D8 /* CSJ */ = {
            isa = PBXGroup;
            children = (
                70D5933C25EA17AA00438F1A /* BUAdSDK.bundle */,
                70D5933A25EA17A900438F1A /* BUAdSDK.framework */,
                70D5933B25EA17AA00438F1A /* BUCNAuxiliary.framework */,
                70D5933D25EA17AB00438F1A /* BUFoundation.framework */,
                706CECB8264F6F72001FBEB7 /* BUAdSDK.bundle */,
                706CECB5264F6F6F001FBEB7 /* BUAdSDK.framework */,
                706CECB7264F6F72001FBEB7 /* BUCNAuxiliary.framework */,
                706CECB6264F6F71001FBEB7 /* BUFoundation.framework */,
            );
            path = CSJ;
            sourceTree = "<group>";
        };
        704C148D265A93E2009DAB98 /* Recommend */ = {
            isa = PBXGroup;
            children = (
                70ED36B4266233CE00E51E79 /* lib */,
                704C149E265A9888009DAB98 /* View */,
                704C1487265A936B009DAB98 /* BaseController.h */,
                704C1488265A936B009DAB98 /* BaseController.m */,
                704C14CC265B8E38009DAB98 /* MainBaseController.h */,
                704C14CD265B8E38009DAB98 /* MainBaseController.m */,
                704C148A265A9393009DAB98 /* RecommendMainController.h */,
                704C148B265A9393009DAB98 /* RecommendMainController.m */,
                70ED36BE2662381200E51E79 /* Recommend */,
                704C14C3265B767D009DAB98 /* LifeHomeController.h */,
                704C14C4265B767D009DAB98 /* LifeHomeController.m */,
                7034AC85266399C70056133F /* HDController */,
                7034AC8A26639BC80056133F /* ListControlelr */,
            );
            path = Recommend;
            sourceTree = "<group>";
        };
        704C149E265A9888009DAB98 /* View */ = {
            isa = PBXGroup;
            children = (
                704C149F265A98A1009DAB98 /* RecommendNavView.h */,
                704C14A0265A98A1009DAB98 /* RecommendNavView.m */,
            );
            path = View;
            sourceTree = "<group>";
        };
        704C14A6265B72A5009DAB98 /* ZJScrollPageView */ = {
            isa = PBXGroup;
            children = (
                704C14B7265B72A5009DAB98 /* ZJTitleView.h */,
                704C14AD265B72A5009DAB98 /* ZJTitleView.m */,
                704C14A7265B72A5009DAB98 /* ZJContentView.h */,
                704C14B1265B72A5009DAB98 /* ZJContentView.m */,
                704C14AC265B72A5009DAB98 /* ZJSegmentStyle.h */,
                704C14B3265B72A5009DAB98 /* ZJSegmentStyle.m */,
                704C14B0265B72A5009DAB98 /* UIView+ZJFrame.h */,
                704C14A8265B72A5009DAB98 /* UIView+ZJFrame.m */,
                704C14A9265B72A5009DAB98 /* ZJCollectionView.h */,
                704C14B2265B72A5009DAB98 /* ZJCollectionView.m */,
                704C14AF265B72A5009DAB98 /* ZJScrollPageView.h */,
                704C14B5265B72A5009DAB98 /* ZJScrollPageView.m */,
                704C14B6265B72A5009DAB98 /* UIViewController+ZJScrollPageController.h */,
                704C14AE265B72A5009DAB98 /* UIViewController+ZJScrollPageController.m */,
                704C14AA265B72A5009DAB98 /* ZJScrollSegmentView.h */,
                704C14B4265B72A5009DAB98 /* ZJScrollSegmentView.m */,
                704C14AB265B72A5009DAB98 /* ZJScrollPageViewDelegate.h */,
            );
            path = ZJScrollPageView;
            sourceTree = "<group>";
        };
        7054B444266B8611002B6504 /* Delegate */ = {
            isa = PBXGroup;
            children = (
                7054B445266B8625002B6504 /* RecommendDelegate.h */,
            );
            path = Delegate;
            sourceTree = "<group>";
        };
        705951F12516112D008E0CDF /* View */ = {
@@ -1473,13 +1758,168 @@
            path = Base;
            sourceTree = "<group>";
        };
        706CECBD264F76A1001FBEB7 /* View */ = {
            isa = PBXGroup;
            children = (
                706CECC6264F97C7001FBEB7 /* Cell */,
                706CECBE264F76C1001FBEB7 /* PPTVNavView.h */,
                706CECBF264F76C1001FBEB7 /* PPTVNavView.m */,
                706CECC3264F94CC001FBEB7 /* PPTVPppView.h */,
                706CECC4264F94CC001FBEB7 /* PPTVPppView.m */,
                706CECDC264FC2A7001FBEB7 /* PPTVBottomVIpVIew.h */,
                706CECDD264FC2A7001FBEB7 /* PPTVBottomVIpVIew.m */,
            );
            name = View;
            sourceTree = "<group>";
        };
        706CECC1264F7C16001FBEB7 /* Delegate */ = {
            isa = PBXGroup;
            children = (
                706CECC2264F7C31001FBEB7 /* PPTVDelegate.h */,
            );
            name = Delegate;
            sourceTree = "<group>";
        };
        706CECC6264F97C7001FBEB7 /* Cell */ = {
            isa = PBXGroup;
            children = (
                706CECC7264F97EB001FBEB7 /* PPTVPopCell.h */,
                706CECC8264F97EB001FBEB7 /* PPTVPopCell.m */,
            );
            name = Cell;
            sourceTree = "<group>";
        };
        706CECCA264FB895001FBEB7 /* dsbridge */ = {
            isa = PBXGroup;
            children = (
                706CECCB264FB895001FBEB7 /* dsbridge.h */,
                706CECCC264FB895001FBEB7 /* InternalApis.h */,
                706CECCD264FB895001FBEB7 /* DSCallInfo.m */,
                706CECCE264FB895001FBEB7 /* JSBUtil.h */,
                706CECCF264FB895001FBEB7 /* DWKWebView.h */,
                706CECD0264FB895001FBEB7 /* DSCallInfo.h */,
                706CECD1264FB895001FBEB7 /* InternalApis.m */,
                706CECD2264FB895001FBEB7 /* JSBUtil.m */,
                706CECD3264FB895001FBEB7 /* DWKWebView.m */,
            );
            path = dsbridge;
            sourceTree = "<group>";
        };
        706CECD8264FB8BA001FBEB7 /* Model */ = {
            isa = PBXGroup;
            children = (
                706CECD9264FB8CB001FBEB7 /* JSAPI.h */,
                706CECDA264FB8CB001FBEB7 /* JSAPI.m */,
            );
            name = Model;
            sourceTree = "<group>";
        };
        70D5934225EA1F6D00438F1A /* PPTV */ = {
            isa = PBXGroup;
            children = (
                706CECD8264FB8BA001FBEB7 /* Model */,
                706CECC1264F7C16001FBEB7 /* Delegate */,
                706CECBD264F76A1001FBEB7 /* View */,
                70D5934325EA1FAE00438F1A /* PPTVController.h */,
                70D5934425EA1FAE00438F1A /* PPTVController.m */,
            );
            name = PPTV;
            sourceTree = "<group>";
        };
        70ED36B4266233CE00E51E79 /* lib */ = {
            isa = PBXGroup;
            children = (
                70ED36E6266280EA00E51E79 /* SDCycleScrollView */,
                70ED36CD26624BAE00E51E79 /* UICollectionViewLeftAlignedLayout */,
                70ED36B5266233EC00E51E79 /* OC_CWCarousel */,
            );
            path = lib;
            sourceTree = "<group>";
        };
        70ED36B5266233EC00E51E79 /* OC_CWCarousel */ = {
            isa = PBXGroup;
            children = (
                70ED36B9266233EC00E51E79 /* CWCarouselProtocol.h */,
                70ED36B7266233EC00E51E79 /* CWCarouselHeader.h */,
                70ED36BB266233EC00E51E79 /* CWFlowLayout.h */,
                70ED36B8266233EC00E51E79 /* CWFlowLayout.m */,
                70ED36BA266233EC00E51E79 /* CWCarousel.h */,
                70ED36B6266233EC00E51E79 /* CWCarousel.m */,
            );
            path = OC_CWCarousel;
            sourceTree = "<group>";
        };
        70ED36BE2662381200E51E79 /* Recommend */ = {
            isa = PBXGroup;
            children = (
                7054B444266B8611002B6504 /* Delegate */,
                70ED36BF2662382F00E51E79 /* Cell */,
                704C14C0265B7623009DAB98 /* RecommendController.h */,
                704C14C1265B7623009DAB98 /* RecommendController.m */,
            );
            path = Recommend;
            sourceTree = "<group>";
        };
        70ED36BF2662382F00E51E79 /* Cell */ = {
            isa = PBXGroup;
            children = (
                70ED36C326623CCB00E51E79 /* 01.jpg */,
                70ED36C426623CCB00E51E79 /* 02.jpg */,
                70ED36C526623CCB00E51E79 /* 03.jpg */,
                70ED36C626623CCC00E51E79 /* 04.jpg */,
                70ED36C726623CCC00E51E79 /* 05.jpg */,
                70ED36DA266250B800E51E79 /* RecpmmendTitleView.h */,
                70ED36DB266250B800E51E79 /* RecpmmendTitleView.m */,
                7034AC8226638BF30056133F /* RecommendChangeFooterView.h */,
                7034AC8326638BF30056133F /* RecommendChangeFooterView.m */,
                70ED36D726624F4700E51E79 /* RecommendHeaderViewCell.h */,
                70ED36D826624F4700E51E79 /* RecommendHeaderViewCell.m */,
                70ED36DD26625AF600E51E79 /* ToDayHotCell.h */,
                70ED36DE26625AF600E51E79 /* ToDayHotCell.m */,
                70ED36E0266264D900E51E79 /* RecommendTwoColumnCell.h */,
                70ED36E1266264D900E51E79 /* RecommendTwoColumnCell.m */,
                70ED36E326627D4500E51E79 /* RecommendThreeColumnCell.h */,
                70ED36E426627D4500E51E79 /* RecommendThreeColumnCell.m */,
            );
            path = Cell;
            sourceTree = "<group>";
        };
        70ED36CD26624BAE00E51E79 /* UICollectionViewLeftAlignedLayout */ = {
            isa = PBXGroup;
            children = (
                70ED36CE26624BAE00E51E79 /* UICollectionViewLeftAlignedLayout.h */,
                70ED36CF26624BAE00E51E79 /* UICollectionViewLeftAlignedLayout.m */,
            );
            path = UICollectionViewLeftAlignedLayout;
            sourceTree = "<group>";
        };
        70ED36E6266280EA00E51E79 /* SDCycleScrollView */ = {
            isa = PBXGroup;
            children = (
                70ED36E8266280EA00E51E79 /* SDCycleScrollView.h */,
                70ED36EA266280EA00E51E79 /* SDCycleScrollView.m */,
                70ED36E7266280EA00E51E79 /* UIView+SDExtension.h */,
                70ED36EB266280EA00E51E79 /* UIView+SDExtension.m */,
                70ED36E9266280EA00E51E79 /* SDCollectionViewCell.h */,
                70ED36EC266280EA00E51E79 /* SDCollectionViewCell.m */,
                70ED36ED266280EA00E51E79 /* PageControl */,
            );
            path = SDCycleScrollView;
            sourceTree = "<group>";
        };
        70ED36ED266280EA00E51E79 /* PageControl */ = {
            isa = PBXGroup;
            children = (
                70ED36EE266280EA00E51E79 /* TAAbstractDotView.h */,
                70ED36EF266280EA00E51E79 /* TADotView.m */,
                70ED36F0266280EA00E51E79 /* TAPageControl.m */,
                70ED36F1266280EA00E51E79 /* TAAnimatedDotView.m */,
                70ED36F2266280EA00E51E79 /* TAAbstractDotView.m */,
                70ED36F3266280EA00E51E79 /* TADotView.h */,
                70ED36F4266280EA00E51E79 /* TAAnimatedDotView.h */,
                70ED36F5266280EA00E51E79 /* TAPageControl.h */,
            );
            path = PageControl;
            sourceTree = "<group>";
        };
        7B0A1E1F1D4B1437000518FA /* cell */ = {
@@ -1884,6 +2324,7 @@
        7BC600A01D63F134005CE8FD /* searchView(搜索) */ = {
            isa = PBXGroup;
            children = (
                7034AC8B2663A0200056133F /* SearchNew */,
                705951F12516112D008E0CDF /* View */,
                7BC600A31D63F187005CE8FD /* viewController */,
                7BC600A11D63F167005CE8FD /* view */,
@@ -2059,6 +2500,8 @@
        AD73C5ED1D4DDBAE0060437E /* lib(第三方库) */ = {
            isa = PBXGroup;
            children = (
                704C14A6265B72A5009DAB98 /* ZJScrollPageView */,
                706CECCA264FB895001FBEB7 /* dsbridge */,
                705F1F36251F1CA70065350E /* MJRefresh */,
                7042C94A2515A4FE0017F5D8 /* CSJ */,
                188322341F74AFFD00CCD0B4 /* HXEasyCustomShare */,
@@ -2275,6 +2718,7 @@
                7BCE16781D644EB8004EAD5A /* SearchCollectionViewCell.xib in Resources */,
                18FC90F81D9144320041D298 /* GoogleAdCollectionReusableView.xib in Resources */,
                2DBB90D022320D3D00E70439 /* DisCoverADView.xib in Resources */,
                70ED36CC26623CCC00E51E79 /* 05.jpg in Resources */,
                7BC600AD1D63F560005CE8FD /* searchDetailViewController.xib in Resources */,
                7B59CC141D5B16CC000B357F /* GroupfootSection.xib in Resources */,
                18F5CAA61E1CD25E001F526F /* allCommentsViewController.xib in Resources */,
@@ -2292,8 +2736,9 @@
                18FA68A920916CE300DDF6A6 /* 375.png in Resources */,
                7BFBC65F1D6704E20058FFEB /* NoteCell.xib in Resources */,
                189787871D925B5D006245B9 /* GoogleAdTableViewCell.xib in Resources */,
                70ED36CB26623CCC00E51E79 /* 04.jpg in Resources */,
                7B1FF0A71D67094500E6C207 /* CellOne.xib in Resources */,
                70D5934025EA17AB00438F1A /* BUAdSDK.bundle in Resources */,
                706CECBC264F6F72001FBEB7 /* BUAdSDK.bundle in Resources */,
                7B59CC191D5B16DC000B357F /* ADCollectionReusableView.xib in Resources */,
                18D94EAC1ECD7B6E00B6FA54 /* newADCollectionViewCell.xib in Resources */,
                18BC12B21EDEA87D001E2FB0 /* LiveListTableViewCell.xib in Resources */,
@@ -2308,6 +2753,7 @@
                7B41E9A91D4A04AE00F05CE2 /* Assets.xcassets in Resources */,
                7B4220FE1D6D7DDE007345E6 /* OnlySpecialTwo.xib in Resources */,
                D45473551DBD9FC700EC002B /* ç¼“冲.gif in Resources */,
                70ED36C926623CCC00E51E79 /* 02.jpg in Resources */,
                7B9D31C41D5421E000EDED00 /* SubregionViewCollectionViewCell.xib in Resources */,
                189787821D9233E9006245B9 /* View.xib in Resources */,
                18FA68AC20916CE300DDF6A6 /* 414x736.png in Resources */,
@@ -2328,12 +2774,14 @@
                7B7BB8351D65A3DA00066939 /* searchTableViewCell.xib in Resources */,
                18F5CAA11E1C8E79001F526F /* discoverGoodsDetailViewController.xib in Resources */,
                7BCC19CC1D5C73AD00FB6123 /* titleCollectionReusableView.xib in Resources */,
                70ED36C826623CCC00E51E79 /* 01.jpg in Resources */,
                7B1FF0C51D670A3B00E6C207 /* StarmovieCell.xib in Resources */,
                7BC24A611D50754600F6D2D9 /* FooterCollectionReusableView.xib in Resources */,
                1823F4CB1DACC91F00C114C3 /* forgetPasswordViewController.xib in Resources */,
                7B893F4F1D70549F0028A556 /* CommentTableViewCell.xib in Resources */,
                2D3F513921AE716F00C50FA5 /* AdCollectionViewCell.xib in Resources */,
                18FA68AD20916CE300DDF6A6 /* 621x1104.png in Resources */,
                70ED36CA26623CCC00E51E79 /* 03.jpg in Resources */,
                7B7BB8301D65558500066939 /* SearchCollectionReusableView.xib in Resources */,
                7BFBC6911D6705DD0058FFEB /* StorageSpaceTableViewCell.xib in Resources */,
                7B1FF0C31D670A3B00E6C207 /* Starview.xib in Resources */,
@@ -2379,6 +2827,7 @@
            inputPaths = (
                "${PODS_ROOT}/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh",
                "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
                "${BUILT_PRODUCTS_DIR}/SDAutoLayout/SDAutoLayout.framework",
                "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
                "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework",
                "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework",
@@ -2389,6 +2838,7 @@
            name = "[CP] Embed Pods Frameworks";
            outputPaths = (
                "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
                "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDAutoLayout.framework",
                "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
                "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework",
                "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework",
@@ -2408,6 +2858,7 @@
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                704C148C265A9393009DAB98 /* RecommendMainController.m in Sources */,
                705F1F74251F1CA80065350E /* UIView+MJExtension.m in Sources */,
                705F1F79251F1CA80065350E /* MJRefreshAutoGifFooter.m in Sources */,
                18678ED920BE96D5000F5D54 /* recommendView.m in Sources */,
@@ -2415,20 +2866,27 @@
                2DEC6E5C22017DC5009B06D4 /* UITabBar+mainTab.m in Sources */,
                1883223A1F74B62400CCD0B4 /* HXShareScrollView.m in Sources */,
                18BBB9031E23977E00793EAB /* LSPageScrollView.m in Sources */,
                70ED36D026624BAE00E51E79 /* UICollectionViewLeftAlignedLayout.m in Sources */,
                18B6BE721DADDB6E00DA4F63 /* signatureTableViewCell.m in Sources */,
                18B6BE6D1DADDB4700DA4F63 /* InfoTableViewCell.m in Sources */,
                7BCC19CB1D5C73AD00FB6123 /* titleCollectionReusableView.m in Sources */,
                1884A6021E545D4900548480 /* PopoverAction.m in Sources */,
                70ED36E526627D4500E51E79 /* RecommendThreeColumnCell.m in Sources */,
                706CECC9264F97EB001FBEB7 /* PPTVPopCell.m in Sources */,
                7B893F4A1D7054580028A556 /* commentHeaderView.m in Sources */,
                7BFBC6751D67054A0058FFEB /* HelpViewController.m in Sources */,
                7034AC922663A41C0056133F /* SearchNavView.m in Sources */,
                7BB429151D4B5FC900AA2D11 /* UIImageView+YTH.m in Sources */,
                706CECD6264FB895001FBEB7 /* JSBUtil.m in Sources */,
                7B59CC181D5B16DC000B357F /* ADCollectionReusableView.m in Sources */,
                183080E01E29D0E60017DDD7 /* XYRChildTableViewCell.m in Sources */,
                705F1F7A251F1CA80065350E /* MJRefreshAutoNormalFooter.m in Sources */,
                70ED36FB266280EA00E51E79 /* TAAnimatedDotView.m in Sources */,
                705F1F84251F1CA80065350E /* MJRefreshComponent.m in Sources */,
                7B41E9A11D4A04AE00F05CE2 /* AppDelegate.m in Sources */,
                18F5CAA51E1CD25E001F526F /* allCommentsViewController.m in Sources */,
                18E943EC2057667D0019FD04 /* MineViewController.m in Sources */,
                704C14BA265B72A5009DAB98 /* UIViewController+ZJScrollPageController.m in Sources */,
                7BC24A601D50754600F6D2D9 /* FooterCollectionReusableView.m in Sources */,
                7B4220FD1D6D7DDE007345E6 /* OnlySpecialTwo.m in Sources */,
                7B4220ED1D6D7D34007345E6 /* AllSpecialCell.m in Sources */,
@@ -2442,14 +2900,20 @@
                705951F425161153008E0CDF /* SearchTitleView.m in Sources */,
                7B59CC041D5B15C4000B357F /* IntroductionCollectionViewCell.m in Sources */,
                7B1FF0C21D670A3B00E6C207 /* Starview.m in Sources */,
                706CECD7264FB895001FBEB7 /* DWKWebView.m in Sources */,
                704C14B9265B72A5009DAB98 /* ZJTitleView.m in Sources */,
                706CECD5264FB895001FBEB7 /* InternalApis.m in Sources */,
                7BFBC6621D6704EF0058FFEB /* LookNoteController.m in Sources */,
                2D3F513821AE716F00C50FA5 /* AdCollectionViewCell.m in Sources */,
                18B1C25C1DB5B26B00AB709B /* README.md in Sources */,
                18B1C2681DB5B26B00AB709B /* SlideMenuController.m in Sources */,
                7034AC8426638BF30056133F /* RecommendChangeFooterView.m in Sources */,
                705F1F78251F1CA80065350E /* MJRefreshAutoStateFooter.m in Sources */,
                18E943E9205766510019FD04 /* subregionViewController.m in Sources */,
                70ED36F9266280EA00E51E79 /* TADotView.m in Sources */,
                7B0D3B2E1D59BCAB003E74A8 /* CMuneItem.m in Sources */,
                18E943F52057C5720019FD04 /* JYNetWorking.m in Sources */,
                704C14B8265B72A5009DAB98 /* UIView+ZJFrame.m in Sources */,
                181D3A091E1DFD5300CDBDE9 /* XYRUITextField.m in Sources */,
                705F1F83251F1CA80065350E /* MJRefreshAutoFooter.m in Sources */,
                705F1F85251F1CA80065350E /* MJRefreshTrailer.m in Sources */,
@@ -2461,6 +2925,7 @@
                18D94EAB1ECD7B6E00B6FA54 /* newADCollectionViewCell.m in Sources */,
                705F1F73251F1CA80065350E /* NSBundle+MJRefresh.m in Sources */,
                7BFBC66D1D6705280058FFEB /* ComentCell.m in Sources */,
                704C14C8265B76BA009DAB98 /* HDController.m in Sources */,
                7B1FF0D01D670AA900E6C207 /* TWScell.m in Sources */,
                18E943F2205774D50019FD04 /* BaseViewController.m in Sources */,
                1884A6081E54630300548480 /* LGLAlertView.m in Sources */,
@@ -2482,14 +2947,19 @@
                7BA7E5C81D6BD4CB00D347D0 /* SubregionDetailViewController.m in Sources */,
                1823F4CA1DACC91F00C114C3 /* forgetPasswordViewController.m in Sources */,
                18B1C2671DB5B26B00AB709B /* README.md in Sources */,
                704C14CE265B8E38009DAB98 /* MainBaseController.m in Sources */,
                7BC24A561D5074FC00F6D2D9 /* shufflingCollectionReusableView.m in Sources */,
                7B1FF0C41D670A3B00E6C207 /* StarmovieCell.m in Sources */,
                18BC12B61EDEAB4A001E2FB0 /* HotLiveCollectionViewCell.m in Sources */,
                186BE3021DAA22B60003A943 /* RegisteViewController.m in Sources */,
                704C14A1265A98A1009DAB98 /* RecommendNavView.m in Sources */,
                7B1FF0CB1D670A7F00E6C207 /* StarsController.m in Sources */,
                70ED36BC266233EC00E51E79 /* CWCarousel.m in Sources */,
                7B1FF0D41D670AB200E6C207 /* TWScontroller.m in Sources */,
                18BC12C01EDEAB8D001E2FB0 /* LiveListCollectionViewCell.m in Sources */,
                705F1F72251F1CA80065350E /* UIScrollView+MJExtension.m in Sources */,
                704C14BE265B72A5009DAB98 /* ZJScrollSegmentView.m in Sources */,
                706CECC0264F76C1001FBEB7 /* PPTVNavView.m in Sources */,
                705F1F76251F1CA80065350E /* MJRefreshBackStateFooter.m in Sources */,
                18BC12AC1EDEA838001E2FB0 /* AllLiveTypeTableViewCell.m in Sources */,
                18ABF6E31DDD9B4600C9257E /* YTHNetdata.m in Sources */,
@@ -2503,9 +2973,12 @@
                7BF5266A1D742C80004B9DBB /* WeiKouAdView.m in Sources */,
                705F1F7C251F1CA80065350E /* MJRefreshNormalTrailer.m in Sources */,
                1845BB48209BF13D009C639B /* DisCoverTableViewCell.m in Sources */,
                706CECDB264FB8CB001FBEB7 /* JSAPI.m in Sources */,
                18F5CAAB1E1CFE8C001F526F /* PublishGoodsViewController.m in Sources */,
                70ED36E2266264D900E51E79 /* RecommendTwoColumnCell.m in Sources */,
                18FB20DE1EE7E5330008AFD9 /* liveTopicViewController.m in Sources */,
                7B4220FB1D6D7DDE007345E6 /* OnlySpecialThere.m in Sources */,
                70ED36FA266280EA00E51E79 /* TAPageControl.m in Sources */,
                7BFBC6711D6705330058FFEB /* MymessageContrlloer.m in Sources */,
                18B1C25B1DB5B26B00AB709B /* LICENSE.md in Sources */,
                7BFBC6541D6704780058FFEB /* MyRegardController.m in Sources */,
@@ -2515,6 +2988,7 @@
                7B893F461D7043030028A556 /* AttentionCollectionReusableView.m in Sources */,
                705951F7251633E9008E0CDF /* SearchDetailListCell.m in Sources */,
                705F1F7E251F1CA80065350E /* MJRefreshStateHeader.m in Sources */,
                7034AC8E2663A03D0056133F /* SearchController.m in Sources */,
                18EF91E31D8E47610078C8BD /* WEBViewController.m in Sources */,
                2D1E3DBB213536700021C50A /* NoNetworkView.m in Sources */,
                7B32BD3D1D4F410F00E96E75 /* recommentCollectionViewCell.m in Sources */,
@@ -2523,47 +2997,67 @@
                ADF5E0A51D4E33C1005F8A9E /* LeftTableViewCell.m in Sources */,
                705F1F75251F1CA80065350E /* MJRefreshBackGifFooter.m in Sources */,
                7B9D31C31D5421E000EDED00 /* SubregionViewCollectionViewCell.m in Sources */,
                7034AC962663BC400056133F /* SearchHotCell.m in Sources */,
                705F1F82251F1CA80065350E /* MJRefreshBackFooter.m in Sources */,
                189787861D925B5D006245B9 /* GoogleAdTableViewCell.m in Sources */,
                705F1F70251F1CA80065350E /* MJRefreshConfig.m in Sources */,
                70ED36FC266280EA00E51E79 /* TAAbstractDotView.m in Sources */,
                70ED36BD266233EC00E51E79 /* CWFlowLayout.m in Sources */,
                7034AC9C2663BD650056133F /* SearchHotSearchCell.m in Sources */,
                704C14C2265B7623009DAB98 /* RecommendController.m in Sources */,
                188175201DC05C51004A2540 /* liveOnLineView.m in Sources */,
                704C14BD265B72A5009DAB98 /* ZJSegmentStyle.m in Sources */,
                7BB429171D4B5FC900AA2D11 /* NSString+YTH.m in Sources */,
                7BF5266C1D742C80004B9DBB /* NSString+WeiKouAd.m in Sources */,
                18ED60711E165CE000AF8252 /* findGoodsTableViewCell.m in Sources */,
                7B9D31CC1D54481000EDED00 /* XYRDetailViewController.m in Sources */,
                18B6BE681DADDB2C00DA4F63 /* IconTableViewCell.m in Sources */,
                70ED36F6266280EA00E51E79 /* SDCycleScrollView.m in Sources */,
                7B1FF0951D6708FD00E6C207 /* discoverView.m in Sources */,
                706CECD4264FB895001FBEB7 /* DSCallInfo.m in Sources */,
                705F1F81251F1CA80065350E /* MJRefreshHeader.m in Sources */,
                7BFBC6861D6705AB0058FFEB /* SettingController.m in Sources */,
                7B32BD321D4F26F500E96E75 /* subregionView.m in Sources */,
                7034AC8826639A7B0056133F /* HDHeaderCell.m in Sources */,
                7BC600AC1D63F560005CE8FD /* searchDetailViewController.m in Sources */,
                7B1FF0C81D670A4E00E6C207 /* IndividualStarController.m in Sources */,
                182F49662092DF1200FEAAF7 /* SJTabbarViewController.m in Sources */,
                7B1FF0D91D670B7E00E6C207 /* AttentionCell.m in Sources */,
                70ED36DC266250B800E51E79 /* RecpmmendTitleView.m in Sources */,
                704C14BC265B72A5009DAB98 /* ZJCollectionView.m in Sources */,
                7BCE16701D640A75004EAD5A /* YTHSearchTextField.m in Sources */,
                AD73C5F51D4DE7DD0060437E /* GTMBase64.m in Sources */,
                7B41E99E1D4A04AE00F05CE2 /* main.m in Sources */,
                705F1E84251F085D0065350E /* Share.m in Sources */,
                7BC600A71D63F1B9005CE8FD /* searchViewController.m in Sources */,
                704C14C5265B767D009DAB98 /* LifeHomeController.m in Sources */,
                70ED36F7266280EA00E51E79 /* UIView+SDExtension.m in Sources */,
                2DECF93122325854002FF49F /* GuessLTableViewCell.m in Sources */,
                7BC24A5B1D50752B00F6D2D9 /* HeaderCollectionReusableView.m in Sources */,
                706CECC5264F94CC001FBEB7 /* PPTVPppView.m in Sources */,
                2DECF92D22325172002FF49F /* GuessLikeViewController.m in Sources */,
                7B7BB8341D65A3DA00066939 /* searchTableViewCell.m in Sources */,
                18FC90F71D9144320041D298 /* GoogleAdCollectionReusableView.m in Sources */,
                70ED36F8266280EA00E51E79 /* SDCollectionViewCell.m in Sources */,
                704C14BB265B72A5009DAB98 /* ZJContentView.m in Sources */,
                2D1198E5212E93CD0043EA39 /* UIViewController+Tools.m in Sources */,
                706CECDE264FC2A7001FBEB7 /* PPTVBottomVIpVIew.m in Sources */,
                7B7BB82F1D65558500066939 /* SearchCollectionReusableView.m in Sources */,
                705F1F80251F1CA80065350E /* MJRefreshFooter.m in Sources */,
                7BFBC6901D6705DD0058FFEB /* StorageSpaceTableViewCell.m in Sources */,
                7034AC992663BCF00056133F /* SearchRecordCell.m in Sources */,
                7B1FF0BA1D670A1F00E6C207 /* AllSpecialController.m in Sources */,
                7BC24A521D50282200F6D2D9 /* YTHsharedManger.m in Sources */,
                187A74581DF79DDF001E856F /* UILabel+LXAdd.m in Sources */,
                7BCE16771D644EB8004EAD5A /* SearchCollectionViewCell.m in Sources */,
                7B8ADA461D589448007A3FFD /* XYRVideoDetailModel.m in Sources */,
                18E943EF205767120019FD04 /* discoverViewController.m in Sources */,
                704C14CB265B76D2009DAB98 /* ListController.m in Sources */,
                705F1F7B251F1CA80065350E /* MJRefreshStateTrailer.m in Sources */,
                705F1F7D251F1CA80065350E /* MJRefreshNormalHeader.m in Sources */,
                705F1F7F251F1CA80065350E /* MJRefreshGifHeader.m in Sources */,
                18E943E62057656C0019FD04 /* recommendViewController.m in Sources */,
                70ED36DF26625AF600E51E79 /* ToDayHotCell.m in Sources */,
                7BB429141D4B5FC900AA2D11 /* UIImage+YTH.m in Sources */,
                7B1FF0DD1D670B8800E6C207 /* attentionView.m in Sources */,
                70D5934525EA1FAE00438F1A /* PPTVController.m in Sources */,
@@ -2573,7 +3067,11 @@
                7B1FF0AE1D67094500E6C207 /* CellHead.m in Sources */,
                705F1F6E251F1CA80065350E /* UIScrollView+MJRefresh.m in Sources */,
                18BC12A71EDEA7AD001E2FB0 /* HotLiveTableViewCell.m in Sources */,
                7034AC9F2663BDFE0056133F /* SearchRecordHeaderView.m in Sources */,
                704C14BF265B72A5009DAB98 /* ZJScrollPageView.m in Sources */,
                70ED36D926624F4700E51E79 /* RecommendHeaderViewCell.m in Sources */,
                7B59CC131D5B16CC000B357F /* GroupfootSection.m in Sources */,
                704C1489265A936B009DAB98 /* BaseController.m in Sources */,
                18ED606C1E1632E300AF8252 /* StartCollectionViewCell.m in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
BuWanVideo2.0.xcworkspace/xcuserdata/aeline.xcuserdatad/UserInterfaceState.xcuserstate
Binary files differ
BuWanVideo2.0.xcworkspace/xcuserdata/aeline.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -7,16 +7,76 @@
      <BreakpointProxy
         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
         <BreakpointContent
            uuid = "24C9F381-5D49-4CF5-BD18-1F53C86F33D2"
            shouldBeEnabled = "No"
            uuid = "D58FFF52-3D0E-4493-8780-0C40FE4BCB90"
            shouldBeEnabled = "Yes"
            ignoreCount = "0"
            continueAfterRunningActions = "No"
            filePath = "BuWanVideo2.0/AppDelegate.m"
            filePath = "BuWanVideo2.0/PPTVController.m"
            startingColumnNumber = "9223372036854775807"
            endingColumnNumber = "9223372036854775807"
            startingLineNumber = "100"
            endingLineNumber = "100"
            landmarkName = "-fetchCommenConfig"
            startingLineNumber = "150"
            endingLineNumber = "150"
            landmarkName = "-userContentController:didReceiveScriptMessage:"
            landmarkType = "7">
         </BreakpointContent>
      </BreakpointProxy>
      <BreakpointProxy
         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
         <BreakpointContent
            uuid = "05259D33-D3BF-4CE4-93E2-654B308832DD"
            shouldBeEnabled = "Yes"
            ignoreCount = "0"
            continueAfterRunningActions = "No"
            filePath = "BuWanVideo2.0/PPTVController.m"
            startingColumnNumber = "9223372036854775807"
            endingColumnNumber = "9223372036854775807"
            startingLineNumber = "105"
            endingLineNumber = "105"
            landmarkName = "PPTVController"
            landmarkType = "3">
         </BreakpointContent>
      </BreakpointProxy>
      <BreakpointProxy
         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
         <BreakpointContent
            uuid = "F01537B9-6B66-4C59-80F3-9A7F66813DC7"
            shouldBeEnabled = "Yes"
            ignoreCount = "0"
            continueAfterRunningActions = "No"
            filePath = "BuWanVideo2.0/JSAPI.m"
            startingColumnNumber = "9223372036854775807"
            endingColumnNumber = "9223372036854775807"
            startingLineNumber = "14"
            endingLineNumber = "14"
            landmarkName = "-tryPlayFinish"
            landmarkType = "7">
         </BreakpointContent>
      </BreakpointProxy>
      <BreakpointProxy
         BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
         <BreakpointContent
            uuid = "29261EEF-7821-4FCC-B006-52100113B6BC"
            shouldBeEnabled = "Yes"
            ignoreCount = "0"
            continueAfterRunningActions = "No"
            breakpointStackSelectionBehavior = "1"
            scope = "1"
            stopOnStyle = "0">
         </BreakpointContent>
      </BreakpointProxy>
      <BreakpointProxy
         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
         <BreakpointContent
            uuid = "4EF2693E-AD35-461F-A248-82D8240F68F4"
            shouldBeEnabled = "Yes"
            ignoreCount = "0"
            continueAfterRunningActions = "No"
            filePath = "BuWanVideo2.0/Recommend/ListControlelr/ListController.m"
            startingColumnNumber = "9223372036854775807"
            endingColumnNumber = "9223372036854775807"
            startingLineNumber = "86"
            endingLineNumber = "86"
            landmarkName = "-getHomeAd"
            landmarkType = "7">
         </BreakpointContent>
      </BreakpointProxy>
BuWanVideo2.0/.DS_Store
Binary files differ
BuWanVideo2.0/AppDelegate.m
@@ -21,6 +21,8 @@
//#import <AlibcTradeSDK/AlibcTradeSDK.h>
#import "RecommendMainController.h"
#import "RecommendController.h"
#import "recommendViewController.h"
#import "subregionViewController.h"
#import "MineViewController.h"
@@ -34,6 +36,8 @@
//#import <UMShare/UMShare.h>
#import <BUAdSDK/BUAdSDK.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/ASIdentifierManager.h>
#define LECUsedBundleID   @"com.yeshi.buwanshequ.ios"
@@ -56,7 +60,8 @@
    //清空角标
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
    //设置状态栏的字体颜色
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
    [self requestIDFA];
    //添加网络监测
    [self NetworkMonitoring];
    
@@ -90,6 +95,17 @@
    
    TOCK;
    return YES;
}
- (void)requestIDFA {
    if (@available(iOS 14, *)) {
        [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
        }];
    } else {
        // Fallback on earlier versions
    }
}
- (void)fetchCommenConfig {
@@ -212,9 +228,9 @@
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window {
    if ([NSStringFromClass([[[window subviews]lastObject] class]) isEqualToString:@"UITransitionView"]) {
        return UIInterfaceOrientationMaskAll;
    }
//    if ([NSStringFromClass([[[window subviews]lastObject] class]) isEqualToString:@"UITransitionView"]) {
//        return UIInterfaceOrientationMaskAll;
//    }
    return UIInterfaceOrientationMaskPortrait;
}
@@ -248,9 +264,7 @@
    self.splashAdView.tolerateTimeout = 10;
    self.splashAdView.delegate = self;
    //optional
    self.splashAdView.needSplashZoomOutAd = YES;
    float width = [UIScreen mainScreen].bounds.size.width;
    float height = [UIScreen mainScreen].bounds.size.height;
    UIImageView *imageview = [[UIImageView alloc] init];
@@ -408,15 +422,15 @@
    self.window.backgroundColor=[UIColor whiteColor];
    [self.window makeKeyAndVisible];
    
    recommendViewController *recommendVC = [[recommendViewController alloc]init];
    recommendVC.tabBarItem.image = [[UIImage imageNamed:@"Home-拷贝"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    recommendVC.tabBarItem.selectedImage = [[UIImage imageNamed:@"Home"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    UINavigationController *nrecommendVC = [[UINavigationController alloc]initWithRootViewController:recommendVC];
    RecommendMainController *vcRecommend = [[RecommendMainController alloc]init];
    vcRecommend.tabBarItem.image = [[UIImage imageNamed:@"Home-拷贝"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    vcRecommend.tabBarItem.selectedImage = [[UIImage imageNamed:@"Home"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    UINavigationController *nrecommendVC = [[UINavigationController alloc]initWithRootViewController:vcRecommend];
    
    subregionViewController *subVC = [[subregionViewController alloc]init];
    subVC.tabBarItem.image = [[UIImage imageNamed:@"Camera-拷贝"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    subVC.tabBarItem.selectedImage = [[UIImage imageNamed:@"Camera"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    UINavigationController *nsubVC = [[UINavigationController alloc]initWithRootViewController:subVC];
    
    discoverViewController *disVC = [[discoverViewController alloc]init];
BuWanVideo2.0/Assets.xcassets/.DS_Store
Binary files differ
BuWanVideo2.0/Assets.xcassets/Contents.json
@@ -1,6 +1,6 @@
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
    "author" : "xcode",
    "version" : 1
  }
}
}
BuWanVideo2.0/Assets.xcassets/Home/Contents.json
New file
@@ -0,0 +1,6 @@
{
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_more.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "home_more@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "home_more@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_more.imageset/home_more@2x.png
BuWanVideo2.0/Assets.xcassets/Home/home_more.imageset/home_more@3x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_change.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "home_recommend_change@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "home_recommend_change@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_change.imageset/home_recommend_change@2x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_change.imageset/home_recommend_change@3x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_gq.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "home_recommend_gq@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "home_recommend_gq@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_gq.imageset/home_recommend_gq@2x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_gq.imageset/home_recommend_gq@3x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_more.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "home_recommend_more@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "home_recommend_more@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_more.imageset/home_recommend_more@2x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_more.imageset/home_recommend_more@3x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_vip.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "home_recommend_vip@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "home_recommend_vip@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_vip.imageset/home_recommend_vip@2x.png
BuWanVideo2.0/Assets.xcassets/Home/home_recommend_vip.imageset/home_recommend_vip@3x.png
BuWanVideo2.0/Assets.xcassets/Home/home_record.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "home_recommend@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "home_recommend@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_record.imageset/home_recommend@2x.png
BuWanVideo2.0/Assets.xcassets/Home/home_record.imageset/home_recommend@3x.png
BuWanVideo2.0/Assets.xcassets/Home/home_search.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "home_search@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "home_search@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/home_search.imageset/home_search@2x.png
BuWanVideo2.0/Assets.xcassets/Home/home_search.imageset/home_search@3x.png
BuWanVideo2.0/Assets.xcassets/Home/search_delete.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "search_delete@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "search_delete@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/search_delete.imageset/search_delete@2x.png
BuWanVideo2.0/Assets.xcassets/Home/search_delete.imageset/search_delete@3x.png
BuWanVideo2.0/Assets.xcassets/Home/search_hot.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "search_hot@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "search_hot@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/Home/search_hot.imageset/search_hot@2x.png
BuWanVideo2.0/Assets.xcassets/Home/search_hot.imageset/search_hot@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/Contents.json
@@ -1,6 +1,6 @@
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
    "author" : "xcode",
    "version" : 1
  }
}
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_arrow.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "pptv_arrow@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "pptv_arrow@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_arrow.imageset/pptv_arrow@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_arrow.imageset/pptv_arrow@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_bg.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "pptv_bg@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "pptv_bg@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_bg.imageset/pptv_bg@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_bg.imageset/pptv_bg@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_copy.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "pptv_copy@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "pptv_copy@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_copy.imageset/pptv_copy@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_copy.imageset/pptv_copy@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_delete.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "pptv_delete@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "pptv_delete@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_delete.imageset/pptv_delete@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_delete.imageset/pptv_delete@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_more.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "pptv_more@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "pptv_more@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_more.imageset/pptv_more@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_more.imageset/pptv_more@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_other.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "形状 16@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "形状 16@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_other.imageset/ÐÎ×´ 16@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_other.imageset/ÐÎ×´ 16@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_refresh.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "pptv_refresh@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "pptv_refresh@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_refresh.imageset/pptv_refresh@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_refresh.imageset/pptv_refresh@3x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_vip_icon.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "pptv_vip_icon@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "filename" : "pptv_vip_icon@3x.png",
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_vip_icon.imageset/pptv_vip_icon@2x.png
BuWanVideo2.0/Assets.xcassets/ÊÓÆµÏêÇéÒ³Ãæ/pptv_vip_icon.imageset/pptv_vip_icon@3x.png
BuWanVideo2.0/BaseViewController.m
@@ -44,7 +44,7 @@
    }
    NSLog(@"%f == %f  \n  %f === %f",KScreenH,KScreenW,[[UIScreen mainScreen] currentMode].size.height,[[UIScreen mainScreen] currentMode].size.width);
    //    è®¾ç½®é¢œè‰²
    statusBarView.backgroundColor=kGlobalMainColor;
    statusBarView.backgroundColor = kGlobalMainColor;
    [self.navigationController.navigationBar setBackgroundColor:kGlobalMainColor];
//    [self.navigationController.navigationBar setBackgroundColor:[UIColor orangeColor]];
BuWanVideo2.0/CSJ/BUAdSDK.bundle/Assets.car
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.bundle/Info.plist
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.bundle/bu_logo@2x.data
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.bundle/bu_logo@3x.data
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.bundle/bu_slienceAudio.aiff
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.bundle/ja.lproj/BULanguage.strings
@@ -30,7 +30,7 @@
"GetRewardAfterWatching" = "動画を最後まで視聴いただけるとリワードを付与されます";
"GiveUpReward" = "やらない";
"ContinueWatching" = "視聴し続ける";
"CanbeTurnedOffAfter" = "%ds後に閉じられます";
"CanbeTurnedOffAfter" = "%ds後にスキップ";
"Get" = "入手";
"View" = "見る";
"ContinuePlaying" = "つづける";
BuWanVideo2.0/CSJ/BUAdSDK.bundle/version.txt
@@ -1 +1 @@
3.4.2.3
3.6.1.2
BuWanVideo2.0/CSJ/BUAdSDK.framework/BUAdSDK
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.framework/BUAdSDK
New file
@@ -0,0 +1 @@
Versions/Current/BUAdSDK
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers
New file
@@ -0,0 +1 @@
Versions/Current/Headers
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDK.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDKDefines.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDKError.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSDKManager.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUAdSlot.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUFullscreenVideoAd.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUImage.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUMaterialMeta.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeAd.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeAdRelatedView.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressAdViewDelegate.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressBannerView.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressFullscreenVideoAd.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressInterstitialAd.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressRewardedVideoAd.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUNativeExpressSplashView.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUPlayerPublicDefine.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BURewardedVideoAd.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUSplashAdView.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUVideoAdReportor.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/BUVideoAdView.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/PangleNativeBannerView.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Headers/PangleNativeInterstitialView.h
File was deleted
BuWanVideo2.0/CSJ/BUAdSDK.framework/Info.plist
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.framework/Resources
New file
@@ -0,0 +1 @@
Versions/Current/Resources
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/BUAdSDK
Binary files differ
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDK.h
New file
@@ -0,0 +1,63 @@
//
//  BUAdSDK.h
//  BUAdSDK
//
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
// In this header, you should import all the public headers of your framework using statements like #import <BUAdSDK/PublicHeader.h>
#import <BUAdSDK/BUAdSDKConfiguration.h>
#import <BUAdSDK/BUAdSDKDefines.h>
#import <BUAdSDK/BUAdSDKManager.h>
#import <BUAdSDK/BUAdSDKError.h>
#import <BUAdSDK/BUAdSlot.h>
#import <BUAdSDK/BUImage.h>
#import <BUAdSDK/BUSize.h>
#import <BUAdSDK/BUMaterialMeta.h>
#import <BUAdSDK/BUPlayerPublicDefine.h>
#import <BUAdSDK/BUVideoAdView.h>
///customize dislike style
#import <BUAdSDK/BUDislike.h>
#import <BUAdSDK/BUDislikeWords.h>
#import <BUAdSDK/BUDislikeReportor.h>
/// native ads
#import <BUAdSDK/BUNativeAd.h>
#import <BUAdSDK/BUNativeAdRelatedView.h>
#import <BUAdSDK/BUNativeAdsManager.h>
/// native express ads
#import <BUAdSDK/BUNativeExpressAdViewDelegate.h>
#import <BUAdSDK/BUNativeExpressAdManager.h>
#import <BUAdSDK/BUNativeExpressAdView.h>
#import <BUAdSDK/BUNativeExpressBannerView.h>
#import <BUAdSDK/BUNativeExpressInterstitialAd.h>
#import <BUAdSDK/BUNativeExpressRewardedVideoAd.h>
#import <BUAdSDK/BUNativeExpressFullscreenVideoAd.h>
#import <BUAdSDK/BUNativeExpressSplashView.h>
/// splash ads
#import <BUAdSDK/BUSplashAdView.h>
/// rewarded video ads
#import <BUAdSDK/BURewardedVideoModel.h>
#import <BUAdSDK/BURewardedVideoAd.h>
/// full-screen video ads
#import <BUAdSDK/BUFullscreenVideoAd.h>
/// playable tool
#import <BUAdSDK/BUAdSDKPlayableToolManager.h>
// smartlook
#import <BUAdSDK/BUAdSmartlookManager.h>
/// test tools
#import <BUAdSDK/BUAdSDKTestToolManager.h>
/// pangle view
#import <BUAdSDK/PangleNativeBannerView.h>
#import <BUAdSDK/PangleNativeInterstitialView.h>
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKConfiguration.h
New file
@@ -0,0 +1,74 @@
//
//  BUAdSDKConfiguration.h
//  BUAdSDK
//
//  Created by Eason on 2021/3/4.
//
#import <Foundation/Foundation.h>
#import "BUAdSDKDefines.h"
NS_ASSUME_NONNULL_BEGIN
@interface BUAdSDKConfiguration : NSObject
+ (instancetype)configuration;
/// This property should be set when integrating non-China and china areas at the same time,
/// otherwise it need'nt to be set.you‘d better set Territory first,  if you need to set them
@property (nonatomic, assign) BUAdSDKTerritory territory;
///Register the App key that’s already been applied before requesting an ad from TikTok Audience Network.
/// the unique identifier of the App
@property (nonatomic, copy) NSString *appID;
/// Configure development mode. default BUAdSDKLogLevelNone
@property (nonatomic, assign) BUAdSDKLogLevel logLevel;
/// the COPPA of the user, COPPA is the short of Children's Online Privacy Protection Rule,
/// the interface only works in the United States.
/// Coppa 0 adult, 1 child
/// You can change its value at any time
@property (nonatomic, strong) NSNumber *coppa;
/// additional user information.
@property (nonatomic, copy) NSString *userExtData;
/// Solve the problem when your WKWebview post message empty,
/// default is BUOfflineTypeWebview
@property (nonatomic, assign) BUOfflineType webViewOfflineType;
/// Custom set the GDPR of the user,GDPR is the short of General Data Protection Regulation,the interface only works in The European.
/// GDPR 0 close privacy protection, 1 open privacy protection
/// You can change its value at any time
@property (nonatomic, strong) NSNumber *GDPR;
/// Custom set the CCPA of the user,CCPA is the short of General Data Protection Regulation,the interface only works in USA.
/// CCPA  0: "sale" of personal information is permitted, 1: user has opted out of "sale" of personal information -1: default
@property (nonatomic, strong) NSNumber *CCPA;
@property (nonatomic, strong) NSNumber *themeStatus;
/// Custom set the AB vid of the user. Array element type is NSNumber
@property (nonatomic, strong) NSArray<NSNumber *> *abvids;
/// Custom set the tob ab sdk version of the user.
@property (nonatomic, copy) NSString *abSDKVersion;
/// Custom set idfa value
/// You can change its value at any time
@property (nonatomic, copy) NSString *customIdfa;
/**
 Whether to allow SDK to modify the category and options of AVAudioSession when playing audio, default is NO.
 The category set by the SDK is AVAudioSessionCategoryAmbient, and the options are AVAudioSessionCategoryOptionDuckOthers
 */
@property (atomic, assign) BOOL allowModifyAudioSessionSetting;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKDefines.h
New file
@@ -0,0 +1,58 @@
//
//  BUAdSDKDefines.h
//  BUAdSDK
//
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#ifndef BUAdSDK_DEFINES_h
#define BUAdSDK_DEFINES_h
#import <Foundation/Foundation.h>
///CN china, NO_CN is not china
typedef NS_ENUM(NSUInteger, BUAdSDKTerritory) {
    BUAdSDKTerritory_CN = 1,
    BUAdSDKTerritory_NO_CN,
};
typedef NS_ENUM(NSInteger, BUAdSDKThemeStatus) {
    BUAdSDKThemeStatus_Normal = 0,
    BUAdSDKThemeStatus_Night  = 1,
};
typedef NS_ENUM(NSInteger, BUOfflineType) {
    BUOfflineTypeNone,  // Do not set offline
    BUOfflineTypeWebview, // Offline dependence WKWebview
};
typedef NS_ENUM(NSInteger, BUAdSDKLogLevel) {
    BUAdSDKLogLevelNone,
    BUAdSDKLogLevelError,
    BUAdSDKLogLevelWarning,
    BUAdSDKLogLevelInfo,
    BUAdSDKLogLevelDebug,
    BUAdSDKLogLevelVerbose,
};
typedef NS_ENUM(NSInteger, BURitSceneType) {
    BURitSceneType_custom                  = 0,//custom
    BURitSceneType_home_open_bonus         = 1,//Login/open rewards (login, sign-in, offline rewards doubling, etc.)
    BURitSceneType_home_svip_bonus         = 2,//Special privileges (VIP privileges, daily rewards, etc.)
    BURitSceneType_home_get_props          = 3,//Watch rewarded video ad to gain skin, props, levels, skills, etc
    BURitSceneType_home_try_props          = 4,//Watch rewarded video ad to try out skins, props, levels, skills, etc
    BURitSceneType_home_get_bonus          = 5,//Watch rewarded video ad to get gold COINS, diamonds, etc
    BURitSceneType_home_gift_bonus         = 6,//Sweepstakes, turntables, gift boxes, etc
    BURitSceneType_game_start_bonus        = 7,//Before the opening to obtain physical strength, opening to strengthen, opening buff, task props
    BURitSceneType_game_reduce_waiting     = 8,//Reduce wait and cooldown on skill CD, building CD, quest CD, etc
    BURitSceneType_game_more_opportunities = 9,//More chances (resurrect death, extra game time, decrypt tips, etc.)
    BURitSceneType_game_finish_rewards     = 10,//Settlement multiple times/extra bonus (completion of chapter, victory over boss, first place, etc.)
    BURitSceneType_game_gift_bonus         = 11//The game dropped treasure box, treasures and so on
};
@protocol BUToDictionary <NSObject>
- (NSDictionary *)dictionaryValue;
@end
#endif
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKError.h
New file
@@ -0,0 +1,76 @@
//
//  BUAdSDKError.h
//  BUAdSDK
//
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
extern NSErrorDomain BUErrorDomain ;
typedef NS_ENUM(NSInteger, BUErrorCode) {
    BUErrorCodeTempError        = -6,       // native template is invalid
    BUErrorCodeTempAddationError= -5,       // native template addation is invalid
    BUErrorCodeOpenAPPStoreFail = -4,       // failed to open appstore
    BUErrorCodeNOAdError        = -3,       // parsed data has no ads
    BUErrorCodeNetError         = -2,       // network request failed
    BUErrorCodeParseError       = -1,       // parsing failed
    BUErrorCodeSDKInitConfigUnfinished      = -100,   // sdk init config is unfinished
    BUErrorCodePlayableError_ERR_HAS_CACHE  = -702,   // has cache
    BUErrorCodePlayableError_ERR_UNZIP      = -704,   // unzip error
    BUErrorCodeNERenderResultError= 101,    // native Express ad, render result parse fail
    BUErrorCodeNETempError        = 102,    // native Express ad, template is invalid
    BUErrorCodeNETempPluginError  = 103,    // native Express ad, template plugin is invalid
    BUErrorCodeNEDataError        = 104,    // native Express ad, data is invalid
    BUErrorCodeNEParseError       = 105,    // native Express ad, parse fail
    BUErrorCodeNERenderError      = 106,    // native Express ad, render fail
    BUErrorCodeNERenderTimoutError= 107,    // native Express ad, render timeout
    BUErrorCodeTempLoadError      = 109,    // native Express ad, template load fail
    BUErrorCodeDRRenderEngineError = 401,   // native Express ad, engine error
    BUErrorCodeDRRenderContextError = 402,  // native Express ad, context error
    BUErrorCodeDRRenderItemNotExist = 403,  // native Express ad, item not exist
    BUErrorCodeSDKStop          = 1000,     // SDK stop forcely
    BUErrorCodeParamError       = 10001,    // parameter error
    BUErrorCodeTimeout          = 10002,
    BUErrorCodeSuccess          = 20000,
    BUErrorCodeNOAD             = 20001,    // no ads
    BUErrorCodeContentType      = 40000,    // http conent_type error
    BUErrorCodeRequestPBError   = 40001,    // http request pb error
    BUErrorCodeAppEmpty         = 40002,    // request app can't be empty
    BUErrorCodeWapEMpty         = 40003,    // request wap can't be empty
    BUErrorCodeAdSlotEmpty      = 40004,    // missing ad slot description
    BUErrorCodeAdSlotSizeEmpty  = 40005,    // the ad slot size is invalid
    BUErrorCodeAdSlotIDError    = 40006,    // the ad slot ID is invalid
    BUErrorCodeAdCountError     = 40007,    // request the wrong number of ads
    BUUnionAdImageSizeError     = 40008,    // wrong image size
    BUUnionAdSiteIdError        = 40009,    // Media ID is illegal
    BUUnionAdSiteMeiaTypeError  = 40010,    // Media type is illegal
    BUUnionAdSiteAdTypeError    = 40011,    // Ad type is illegal
    BUUnionAdSiteAccessMethodError  = 40012,// Media access type is illegal and has been deprecated
    BUUnionSplashAdTypeError    = 40013,    // Code bit id is less than 900 million, but adType is not splash ad
    BUUnionRedirectError        = 40014,    // The redirect parameter is incorrect
    BUUnionRequestInvalidError  = 40015,    // Media rectification exceeds deadline, request illegal
    BUUnionAppSiteRelError      = 40016,    // The relationship between slot_id and app_id is invalid.
    BUUnionAccessMethodError    = 40017,    // Media access type is not legal API/SDK
    BUUnionPackageNameError     = 40018,    // Media package name is inconsistent with entry
    BUUnionConfigurationError   = 40019,    // Media configuration ad type is inconsistent with request
    BUUnionRequestLimitError    = 40020,    // The ad space registered by developers exceeds daily request limit
    BUUnionSignatureError       = 40021,    // Apk signature sha1 value is inconsistent with media platform entry
    BUUnionIncompleteError      = 40022,    // Whether the media request material is inconsistent with the media platform entry
    BUUnionOSError              = 40023,    // The OS field is incorrectly filled
    BUUnionLowVersion           = 40024,    // The SDK version is too low to return ads
    BUErrorCodeAdPackageIncomplete  = 40025,// the SDK package is incomplete. It is recommended to verify the integrity of SDK package or contact technical support.
    BUUnionMedialCheckError     = 40026,    // Non-international account request for overseas delivery system
    BUUnionSlotIDRenderMthodNoMatch = 40029,// The rendering method for slot ID does not match.
    BUErrorCodeSysError         = 50001     // ad server error
};
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKManager.h
New file
@@ -0,0 +1,127 @@
//
//  BUAdSDKManager.h
//  BUAdSDK
//
//  Copyright Â© 2017 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "BUAdSDKDefines.h"
#import "BUMopubAdMarkUpDelegate.h"
typedef void (^BUConfirmGDPR)(BOOL isAgreed);
typedef void (^BUCompletionHandler)(BOOL success,NSError *error);
@interface BUAdSDKManager : NSObject
@property (nonatomic, copy, readonly, class) NSString *SDKVersion;
/// The synchronize initialization method of Pangle
/// @param completionHandler Callback to the initialization state of the calling thread
+ (void)startWithSyncCompletionHandler:(BUCompletionHandler)completionHandler;
/// The asynchronize initialization method of Pangle
/// @param completionHandler Callback to the initialization state of the non-main thread
+ (void)startWithAsyncCompletionHandler:(BUCompletionHandler)completionHandler;
/// Open GDPR Privacy for the user to choose before setAppID.
+ (void)openGDPRPrivacyFromRootViewController:(UIViewController *)rootViewController confirm:(BUConfirmGDPR)confirm;
@end
@interface BUAdSDKManager (MopubAdaptor) <BUMopubAdMarkUpDelegate>
@end
@interface BUAdSDKManager (BUAdNR)
+ (NSString *)bunr_dictionaryWithSlot:(BUAdSlot *)slot isDynamicRender:(BOOL)isDynamicRender;
@end
@interface BUAdSDKManager (InterfaceReadyReplacement)
/**
This property should be set when integrating non-China and china areas at the same time, otherwise it need'nt to be set.you‘d better set Territory first,  if you need to set them
@param territory : Regional value
*/
+ (void)setTerritory:(BUAdSDKTerritory)territory;
/**
 Register the App key that’s already been applied before requesting an ad from TikTok Audience Network.
 @param appID : the unique identifier of the App
 */
+ (void)setAppID:(NSString *)appID;
/**
 Configure development mode.
 @param level : default BUAdSDKLogLevelNone
 */
+ (void)setLoglevel:(BUAdSDKLogLevel)level;
/* Set the COPPA of the user, COPPA is the short of Children's Online Privacy Protection Rule, the interface only works in the United States.
 * @params Coppa 0 adult, 1 child
 */
+ (void)setCoppa:(NSUInteger)coppa;
/// Set the user's keywords, such as interests and hobbies, etc.
/// Must obtain the consent of the user before incoming.
+ (void)setUserKeywords:(NSString *)keywords;
/// set additional user information.
+ (void)setUserExtData:(NSString *)data;
/// Set whether the app is a paid app, the default is a non-paid app.
/// Must obtain the consent of the user before incoming
+ (void)setIsPaidApp:(BOOL)isPaidApp;
/// Solve the problem when your WKWebview post message empty,default is BUOfflineTypeWebview
+ (void)setOfflineType:(BUOfflineType)type;
/// Custom set the GDPR of the user,GDPR is the short of General Data Protection Regulation,the interface only works in The European.
/// @params GDPR 0 close privacy protection, 1 open privacy protection
+ (void)setGDPR:(NSInteger)GDPR;
/// Custom set the CCPA of the user,CCPA is the short of General Data Protection Regulation,the interface only works in USA.
/// @params CCPA  0: "sale" of personal information is permitted, 1: user has opted out of "sale" of personal information -1: default
+ (void)setCCPA:(NSInteger)CCPA;
/// Custom set the AB vid of the user. Array element type is NSNumber
+ (void)setABVidArray:(NSArray<NSNumber *> *)abvids;
/// Custom set the tob ab sdk version of the user.
+ (void)setABSDKVersion:(NSString *)abSDKVersion;
/// Custom set idfa value
+ (void)setCustomIDFA:(NSString *)idfa;
+ (void)setThemeStatus:(BUAdSDKThemeStatus)themeStatus;
/// get appID
+ (NSString *)appID;
/// get isPaidApp
+ (BOOL)isPaidApp;
/// get GDPR
+ (NSInteger)GDPR;
/// get coppa
+ (NSUInteger)coppa;
/// get CCPA
+ (NSInteger)CCPA;
/**
 Whether to allow SDK to modify the category and options of AVAudioSession when playing audio, default is NO.
 The category set by the SDK is AVAudioSessionCategoryAmbient, and the options are AVAudioSessionCategoryOptionDuckOthers
 */
+ (void)allowModifyAudioSessionSetting:(BOOL)isAllow;
+ (BUAdSDKThemeStatus)themeStatus;
@end
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKPlayableToolManager.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSDKTestToolManager.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSlot.h
New file
@@ -0,0 +1,92 @@
//
//  BUAdSlot.h
//  BUAdSDK
//
//  Copyright Â© 2017 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUSize.h"
typedef NS_ENUM(NSInteger, BUAdSlotAdType) {
    BUAdSlotAdTypeUnknown       = 0,
    BUAdSlotAdTypeBanner        = 1,       // banner ads
    BUAdSlotAdTypeInterstitial  = 2,       // interstitial ads
    BUAdSlotAdTypeSplash        = 3,       // splash ads
    BUAdSlotAdTypeSplash_Cache  = 4,       // cache splash ads
    BUAdSlotAdTypeFeed          = 5,       // feed ads
    BUAdSlotAdTypePaster        = 6,       // paster ads
    BUAdSlotAdTypeRewardVideo   = 7,       // rewarded video ads
    BUAdSlotAdTypeFullscreenVideo = 8,     // full-screen video ads
    BUAdSlotAdTypeDrawVideo     = 9,       // vertical (immersive) video ads
};
typedef NS_ENUM(NSInteger, BUAdSlotPosition) {
    BUAdSlotPositionTop = 1,
    BUAdSlotPositionBottom = 2,
    BUAdSlotPositionFeed = 3,
    BUAdSlotPositionMiddle = 4, // for interstitial ad only
    BUAdSlotPositionFullscreen = 5,
};
@interface BUAdSlot : NSObject
/// required. The unique identifier of a native ad.
@property (nonatomic, copy) NSString *ID;
/// required. Ad type.
@property (nonatomic, assign) BUAdSlotAdType AdType;
/// optional. Ad display location. defaults is BUAdSlotPositionTop
@property (nonatomic, assign) BUAdSlotPosition position;
/// Accept a set of image sizes, please pass in the BUSize object.
@property (nonatomic, strong) NSMutableArray<BUSize *> *imgSizeArray;
/// required. Image size.
@property (nonatomic, strong) BUSize *imgSize;
/// Icon size.
@property (nonatomic, strong) BUSize *iconSize;
/// Maximum length of the title.
@property (nonatomic, assign) NSInteger titleLengthLimit;
/// Maximum length of description.
@property (nonatomic, assign) NSInteger descLengthLimit;
/// optional. Whether to support deeplink.defaults is true
@property (nonatomic, assign) BOOL isSupportDeepLink DEPRECATED_MSG_ATTRIBUTE("This property is deprecated,Settings are no longer required after version 3300");
/// Native banner ads and native interstitial ads are set to 1, other ad types are 0, the default is 0.
@property (nonatomic, assign) BOOL isOriginAd;
/// optional. Whether to support render control
@property (nonatomic, assign) BOOL supportRenderControl;
//adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。
@property (nonatomic, assign) NSInteger adloadSeq;
// Valid only in Native Banner and Native Interstitial
@property (nonatomic, assign) CGSize adSize;
//prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。
@property (nonatomic, copy) NSString *primeRit;
/// optional. AD id for preview
@property (nonatomic, copy) NSString *previewAdID;
/// optional. AD creative id for preview
@property (nonatomic, copy) NSString *previewCreativeID;
/// optional. extend msg
@property (nonatomic, copy) NSDictionary *ext;
/// optional. additional user information
@property (nonatomic, copy) NSString *userData;
- (NSDictionary *)dictionaryValue;
@end
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUAdSmartlookManager.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUDislike.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUDislikeReportor.h
New file
@@ -0,0 +1,49 @@
//
//  BUDislikeReportor.h
//  BUAdSDK
//
//  Created by bytedance on 2020/12/14.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#ifndef BUDislikeReportor_h
#define BUDislikeReportor_h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class BUDislikeWords;
@class BUPersonalizationPrompts;
/// the reportor for custom dislike
@protocol BUDislikeReportorDelegate <NSObject>
@optional
/// report selected dislike word
/// @param dislikeWords dislike words
- (void)dislikeDidSelected:(NSArray<BUDislikeWords *> *)dislikeWords;
/// report submit feedback string
/// @param feedback feedback string
- (void)dislikeDidSubmitFeedback:(NSString *)feedback;
/// reportor when personalization prompts's name did show
/// @param prompts personalization Ads prompts
- (void)dislikeDidShowPersonalizationPrompts:(BUPersonalizationPrompts *)prompts;
/// reportor when personalization prompts did selected
/// @param prompts personalization Ads prompts
- (void)dislikeDidSelectedPersonalizationPrompts:(BUPersonalizationPrompts *)prompts;
/// reportor when personalization prompts's url did load
/// @param prompts personalization prompts
- (void)dislikeDidLoadPersonalizationPromptsURL:(BUPersonalizationPrompts *)prompts;
@end
@class BUNativeAd;
/// Dislike Data Reportor for Native Ad
@interface BUDislikeReportor : NSObject <BUDislikeReportorDelegate>
/// Dislike Reportor Instance
/// @param nativeAd native Ad
- (instancetype)initWithNativeAd:(BUNativeAd *)nativeAd;
@end
#endif /* BUDislikeReportor_h */
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUDislikeWords.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUFullscreenVideoAd.h
New file
@@ -0,0 +1,131 @@
//
//  BUFullscreenVideoAd.h
//  BUAdSDK
//
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "BUAdSlot.h"
#import "BUMopubAdMarkUpDelegate.h"
typedef NS_ENUM(NSUInteger, BUFullScreenVideoAdType) {
    BUFullScreenAdTypeEndcard        = 0,    // video + endcard
    BUFullScreenAdTypeVideoPlayable  = 1,    // video + playable
    BUFullScreenAdTypePurePlayable   = 2     // pure playable
};
NS_ASSUME_NONNULL_BEGIN
@class BUFullscreenVideoAd;
@protocol BUFullscreenVideoAdDelegate <NSObject>
@optional
/**
 This method is called when video ad material loaded successfully.
 */
- (void)fullscreenVideoMaterialMetaAdDidLoad:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad materia failed to load.
 @param error : the reason of error
 */
- (void)fullscreenVideoAd:(BUFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error;
/**
 This method is called when video cached successfully.
 */
- (void)fullscreenVideoAdVideoDataDidLoad:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad slot will be showing.
 */
- (void)fullscreenVideoAdWillVisible:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad slot has been shown.
 */
- (void)fullscreenVideoAdDidVisible:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad is clicked.
 */
- (void)fullscreenVideoAdDidClick:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad is about to close.
 */
- (void)fullscreenVideoAdWillClose:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad is closed.
 */
- (void)fullscreenVideoAdDidClose:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad play completed or an error occurred.
 @param error : the reason of error
 */
- (void)fullscreenVideoAdDidPlayFinish:(BUFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error;
/**
 This method is called when the user clicked skip button.
 */
- (void)fullscreenVideoAdDidClickSkip:(BUFullscreenVideoAd *)fullscreenVideoAd;
/**
this method is used to get the type of fullscreen video ad
 */
- (void)fullscreenVideoAdCallback:(BUFullscreenVideoAd *)fullscreenVideoAd withType:(BUFullScreenVideoAdType)fullscreenVideoAdType;
@end
@interface BUFullscreenVideoAd : NSObject <BUMopubAdMarkUpDelegate>
@property (nonatomic, weak, nullable) id<BUFullscreenVideoAdDelegate> delegate;
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid __attribute__((deprecated("Use fullscreenVideoMaterialMetaAdDidLoad: instead.")));
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
/**
 Initializes video ad with slot id.
 @param slotID : the unique identifier of video ad.
 @return BUFullscreenVideoAd
 */
- (instancetype)initWithSlotID:(NSString *)slotID;
/**
 Initializes video ad with slot.
 @param slot : A object, through which you can pass in the fullscreen unique identifier, ad type, and so on.
 @return BUFullscreenVideoAd
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot;
/**
 Load video ad datas.
 */
- (void)loadAdData;
/**
 Display video ad.
 @param rootViewController : root view controller for displaying ad.
 @return : whether it is successfully displayed.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController;
/**
 Display video ad.
 @param rootViewController : root view controller for displaying ad.
 @param sceneDescirbe : optional. Identifies a custom description of the presentation scenario.
 @return : whether it is successfully displayed.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritSceneDescribe:(NSString *_Nullable)sceneDescirbe;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUImage.h
New file
@@ -0,0 +1,34 @@
//
//  BUImage.h
//  BUAdSDK
//
//  Copyright Â© 2017 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface BUImage : NSObject <NSCoding>
// image address URL
@property (nonatomic, copy) NSString *imageURL;
// image key
@property (nonatomic, copy) NSString *image_key;
// image width
@property (nonatomic, assign) float width;
// image height
@property (nonatomic, assign) float height;
// stream ad image druation
@property (nonatomic, assign) float duration;
- (instancetype)initWithDictionary:(NSDictionary *)dic;
- (NSDictionary *)dictionaryValue;
@end
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUMaterialMeta.h
New file
@@ -0,0 +1,99 @@
//
//  BUMaterialMeta.h
//  BUAdSDK
//
//  Copyright Â© 2017 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BUDislikeWords.h"
#import "BUImage.h"
#import "BUPersonalizationPrompts.h"
typedef NS_ENUM(NSInteger, BUInteractionType) {
    BUInteractionTypeCustorm = 0,
    BUInteractionTypeNO_INTERACTION = 1,  // pure ad display
    BUInteractionTypeURL = 2,             // open the webpage using a browser
    BUInteractionTypePage = 3,            // open the webpage within the app
    BUInteractionTypeDownload = 4,        // download the app
    BUInteractionTypePhone = 5,           // make a call
    BUInteractionTypeMessage = 6,         // send messages
    BUInteractionTypeEmail = 7,           // send email
    BUInteractionTypeVideoAdDetail = 8    // video ad details page
};
typedef NS_ENUM(NSInteger, BUFeedADMode) {
    BUFeedADModeSmallImage = 2,
    BUFeedADModeLargeImage = 3,
    BUFeedADModeGroupImage = 4,
    BUFeedVideoAdModeImage = 5, // video ad || rewarded video ad horizontal screen
    BUFeedVideoAdModePortrait = 15, // rewarded video ad vertical screen
    BUFeedADModeImagePortrait = 16,
    BUFeedADModeSquareImage   = 33, //SquareImage Currently it exists only in the oversea now. V3200 add
    BUFeedADModeSquareVideo   = 50, //SquareVideo Currently it exists only in the oversea now. V3200 add
};
@interface BUMaterialMeta : NSObject <NSCoding>
/// interaction types supported by ads.
@property (nonatomic, assign) BUInteractionType interactionType;
/// material pictures.
@property (nonatomic, strong) NSArray<BUImage *> *imageAry;
/// ad logo icon.
@property (nonatomic, strong) BUImage *icon;
/// ad headline.
@property (nonatomic, copy) NSString *AdTitle;
/// ad description.
@property (nonatomic, copy) NSString *AdDescription;
/// ad source.
@property (nonatomic, copy) NSString *source;
/// text displayed on the creative button.
@property (nonatomic, copy) NSString *buttonText;
/// display format of the in-feed ad, other ads ignores it.
@property (nonatomic, assign) BUFeedADMode imageMode;
/// Star rating, range from 1 to 5.
@property (nonatomic, assign) NSInteger score;
/// Number of comments.
@property (nonatomic, assign) NSInteger commentNum;
/// ad installation package size, unit byte.
@property (nonatomic, assign) NSInteger appSize;
/// video duration
@property (nonatomic, assign) NSInteger videoDuration;
/// video url, will be empty string if allowCustomVideoPlayer is NO, contact BD to add to allow list.
@property (nonatomic, copy, readonly) NSString *videoUrl;
/// be allowed to play video ad via custome player, contact BD to add to allow list.
@property (nonatomic, assign, readonly) BOOL allowCustomVideoPlayer;
/// video resolution width
@property (nonatomic, assign, readonly) NSInteger videoResolutionWidth;
/// video resolution height
@property (nonatomic, assign, readonly) NSInteger videoResolutionHeight;
/// the reason why dislike the ad.
@property (nonatomic, copy) NSArray<BUDislikeWords *> *filterWords;
/// compliance statement of personalized advertising push
@property (nonatomic, strong) BUPersonalizationPrompts *personalPrompts;
/// media configuration parameters.
@property (nonatomic, copy) NSDictionary *mediaExt;
- (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError * __autoreleasing *)error;
@end
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUMopubAdMarkUpDelegate.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeAd.h
New file
@@ -0,0 +1,138 @@
//
//  BUNativeAd.h
//  BUAdSDK
//
//  Copyright Â© 2017 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "BUAdSlot.h"
#import "BUMaterialMeta.h"
#import "BUVideoAdView.h"
#import "BUMopubAdMarkUpDelegate.h"
@protocol BUNativeAdDelegate;
NS_ASSUME_NONNULL_BEGIN
/**
 Abstract ad slot containing ad data loading, response callbacks.
 BUNativeAd currently supports native ads.
 Native ads include in-feed ad (multiple ads, image + video), general native ad (single ad, image + video), native banner ad, and native interstitial ad.
 Support interstitial ad, banner ad, splash ad, rewarded video ad, full-screen video ad.
 */
@interface BUNativeAd : NSObject <BUMopubAdMarkUpDelegate>
/**
 Ad slot description.
 */
@property (nonatomic, strong, readwrite, nullable) BUAdSlot *adslot;
/**
 Ad slot material.
 */
@property (atomic, strong, readonly, nullable) BUMaterialMeta *data;
/**
 The delegate for receiving state change messages.
 The delegate is not limited to viewcontroller.
 The delegate can be set to any object which conforming to <BUNativeAdDelegate>.
 */
@property (nonatomic, weak, readwrite, nullable) id<BUNativeAdDelegate> delegate;
/**
 required.
 Root view controller for handling ad actions.
 Action method includes is 'presentViewController'.
 */
@property (nonatomic, weak, readwrite) UIViewController *rootViewController;
/**
 Initializes native ad with ad slot.
 @param slot : ad slot description.
               including slotID,adType,adPosition,etc.
 @return BUNativeAd
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot;
/**
 Register clickable views in native ads view.
 Interaction types can be configured on TikTok Audience Network.
 Interaction types include view video ad details page, make a call, send email, download the app, open the webpage using a browser,open the webpage within the app, etc.
 @param containerView : required.
                        container view of the native ad.
 @param clickableViews : optional.
                        Array of views that are clickable.
 */
- (void)registerContainer:(__kindof UIView *)containerView
       withClickableViews:(NSArray<__kindof UIView *> *_Nullable)clickableViews;
/**
 Unregister ad view from the native ad.
 */
- (void)unregisterView;
/**
 Actively request nativeAd datas.
 */
- (void)loadAdData;
@end
@protocol BUNativeAdDelegate <NSObject>
@optional
/**
 This method is called when native ad material loaded successfully. This method will be deprecated. Use nativeAdDidLoad:view: instead
 */
- (void)nativeAdDidLoad:(BUNativeAd *)nativeAd;
/**
 This method is called when native ad material loaded successfully.
 */
- (void)nativeAdDidLoad:(BUNativeAd *)nativeAd view:(UIView *_Nullable)view;
/**
 This method is called when native ad materia failed to load.
 @param error : the reason of error
 */
- (void)nativeAd:(BUNativeAd *)nativeAd didFailWithError:(NSError *_Nullable)error;
/**
 This method is called when native ad slot has been shown.
 */
- (void)nativeAdDidBecomeVisible:(BUNativeAd *)nativeAd;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)nativeAdDidCloseOtherController:(BUNativeAd *)nativeAd interactionType:(BUInteractionType)interactionType;
/**
 This method is called when native ad is clicked.
 */
- (void)nativeAdDidClick:(BUNativeAd *)nativeAd withView:(UIView *_Nullable)view;
/**
 This method is called when the user clicked dislike reasons.
 Only used for dislikeButton in BUNativeAdRelatedView.h
 @param filterWords : reasons for dislike
 */
- (void)nativeAd:(BUNativeAd *_Nullable)nativeAd dislikeWithReason:(NSArray<BUDislikeWords *> *_Nullable)filterWords;
/**
 This method is called when the Ad view container is forced to be removed.
 @param nativeAd : Ad material
 @param adContainerView : Ad view container
 */
- (void)nativeAd:(BUNativeAd *_Nullable)nativeAd adContainerViewDidRemoved:(UIView *)adContainerView;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeAdRelatedView.h
New file
@@ -0,0 +1,56 @@
//
//  BUNativeAdRelatedView.h
//  BUAdSDK
//
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUVideoAdView.h"
#import "BUNativeAd.h"
#import "BUVideoAdReportor.h"
#import "BUDislikeReportor.h"
NS_ASSUME_NONNULL_BEGIN
@interface BUNativeAdRelatedView : NSObject
/**
 Need to actively add to the view in order to deal with the feedback and improve the accuracy of ad.
 */
@property (nonatomic, strong, readonly, nullable) UIButton *dislikeButton;
/**
 Promotion label.Need to actively add to the view.
 */
@property (nonatomic, strong, readonly, nullable) UILabel *adLabel;
/**
 Ad logo.Need to actively add to the view.
 */
@property (nonatomic, strong, readonly, nullable) UIImageView *logoImageView;
/**
 Ad logo + Promotion label.Need to actively add to the view.
 */
@property (nonatomic, strong, readonly, nullable) UIImageView *logoADImageView;
/**
 Video ad view. Need to actively add to the view. Can not coexist with videoAdReportor.
 */
@property (nonatomic, strong, readonly, nullable) BUVideoAdView *videoAdView;
/**
Video ad Reportor. Can not coexist with videoAdView.
*/
@property (nonatomic, strong, readonly, nullable) id<BUVideoAdReportor> videoAdReportor;
/**
 Refresh the data every time you get new datas in order to show ad perfectly.
 */
- (void)refreshData:(BUNativeAd *)nativeAd;
//@property (nonatomic, copy) BOOL(^expectUseCustomVideoPlayer)(BOOL isSupported, NSString *videoUrl);
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeAdsManager.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressAdManager.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressAdView.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressAdViewDelegate.h
New file
@@ -0,0 +1,89 @@
//
//  BUNativeExpressAdViewDelegate.h
//  BUAdSDK
//
//  Created by Rush.D.Xzj on 2020/10/12.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BUMaterialMeta.h"
NS_ASSUME_NONNULL_BEGIN
@class BUNativeExpressAdManager;
@class BUNativeExpressAdView;
@class BUDislikeWords;
@protocol BUNativeExpressAdViewDelegate <NSObject>
@optional
/**
 * Sent when views successfully load ad
 */
- (void)nativeExpressAdSuccessToLoad:(BUNativeExpressAdManager *)nativeExpressAdManager views:(NSArray<__kindof BUNativeExpressAdView *> *)views;
/**
 * Sent when views fail to load ad
 */
- (void)nativeExpressAdFailToLoad:(BUNativeExpressAdManager *)nativeExpressAdManager error:(NSError *_Nullable)error;
/**
 * This method is called when rendering a nativeExpressAdView successed, and nativeExpressAdView.size.height has been updated
 */
- (void)nativeExpressAdViewRenderSuccess:(BUNativeExpressAdView *)nativeExpressAdView;
/**
 * This method is called when a nativeExpressAdView failed to render
 */
- (void)nativeExpressAdViewRenderFail:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *_Nullable)error;
/**
 * Sent when an ad view is about to present modal content
 */
- (void)nativeExpressAdViewWillShow:(BUNativeExpressAdView *)nativeExpressAdView;
/**
 * Sent when an ad view is clicked
 */
- (void)nativeExpressAdViewDidClick:(BUNativeExpressAdView *)nativeExpressAdView;
/**
Sent when a playerw playback status changed.
@param playerState : player state after changed
*/
- (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView stateDidChanged:(BUPlayerPlayState)playerState;
/**
 * Sent when a player finished
 * @param error : error of player
 */
- (void)nativeExpressAdViewPlayerDidPlayFinish:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *)error;
/**
 * Sent when a user clicked dislike reasons.
 * @param filterWords : the array of reasons why the user dislikes the ad
 */
- (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView dislikeWithReason:(NSArray<BUDislikeWords *> *)filterWords;
/**
 * Sent after an ad view is clicked, a ad landscape view will present modal content
 */
- (void)nativeExpressAdViewWillPresentScreen:(BUNativeExpressAdView *)nativeExpressAdView;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)nativeExpressAdViewDidCloseOtherController:(BUNativeExpressAdView *)nativeExpressAdView interactionType:(BUInteractionType)interactionType;
/**
 This method is called when the Ad view container is forced to be removed.
 @param nativeExpressAdView : Ad view container
 */
- (void)nativeExpressAdViewDidRemoved:(BUNativeExpressAdView *)nativeExpressAdView;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressBannerView.h
New file
@@ -0,0 +1,150 @@
//
//  BUNativeExpressBannerView.h
//  BUAdSDK
//
//  Created by xxx on 2019/5/17.
//  Copyright Â© 2019 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUMaterialMeta.h"
#import "BUMopubAdMarkUpDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@class BUNativeExpressBannerView;
@class BUDislikeWords;
@class BUSize;
@protocol BUNativeExpressBannerViewDelegate <NSObject>
@optional
/**
 This method is called when bannerAdView ad slot loaded successfully.
 @param bannerAdView : view for bannerAdView
 */
- (void)nativeExpressBannerAdViewDidLoad:(BUNativeExpressBannerView *)bannerAdView;
/**
 This method is called when bannerAdView ad slot failed to load.
 @param error : the reason of error
 */
- (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView didLoadFailWithError:(NSError *_Nullable)error;
/**
 This method is called when rendering a nativeExpressAdView successed.
 */
- (void)nativeExpressBannerAdViewRenderSuccess:(BUNativeExpressBannerView *)bannerAdView;
/**
 This method is called when a nativeExpressAdView failed to render.
 @param error : the reason of error
 */
- (void)nativeExpressBannerAdViewRenderFail:(BUNativeExpressBannerView *)bannerAdView error:(NSError * __nullable)error;
/**
 This method is called when bannerAdView ad slot showed new ad.
 */
- (void)nativeExpressBannerAdViewWillBecomVisible:(BUNativeExpressBannerView *)bannerAdView;
/**
 This method is called when bannerAdView is clicked.
 */
- (void)nativeExpressBannerAdViewDidClick:(BUNativeExpressBannerView *)bannerAdView;
/**
 This method is called when the user clicked dislike button and chose dislike reasons.
 @param filterwords : the array of reasons for dislike.
 */
- (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView dislikeWithReason:(NSArray<BUDislikeWords *> *_Nullable)filterwords;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)nativeExpressBannerAdViewDidCloseOtherController:(BUNativeExpressBannerView *)bannerAdView interactionType:(BUInteractionType)interactionType;
/**
 This method is called when the Ad view container is forced to be removed.
 @param bannerAdView : Express Banner Ad view container
 */
- (void)nativeExpressBannerAdViewDidRemoved:(BUNativeExpressBannerView *)bannerAdView;
@end
@interface BUNativeExpressBannerView : UIView <BUMopubAdMarkUpDelegate>
@property (nonatomic, weak, nullable) id<BUNativeExpressBannerViewDelegate> delegate;
/**
 The carousel interval, in seconds, is set in the range of 30~120s, and is passed during initialization. If it does not meet the requirements, it will not be in carousel ad.
 */
@property (nonatomic, assign, readonly) NSInteger interval;
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
/**
 Initializes express banner ad.
 @param slotID The unique identifier of banner ad.
 @param rootViewController The root controller where the banner is located.
 @param adsize Customize the size of the view. Please make sure that the width and height passed in are available.
 @return BUNativeExpressBannerView
 */
- (instancetype)initWithSlotID:(NSString *)slotID
            rootViewController:(UIViewController *)rootViewController
                        adSize:(CGSize)adsize;
/**
 Initializes carousel express banner ad.
 @param slotID The unique identifier of banner ad.
 @param rootViewController The root controller where the banner is located.
 @param adsize Customize the size of the view. Please make sure that the width and height passed in are available.
 @param interval The carousel interval, in seconds, is set in the range of 30~120s, and is passed during initialization. If it does not meet the requirements, it will not be in carousel ad.
 @return BUNativeExpressBannerView
 */
- (instancetype)initWithSlotID:(NSString *)slotID
            rootViewController:(UIViewController *)rootViewController
                        adSize:(CGSize)adsize
                      interval:(NSInteger)interval;
/**
 Initializes express banner ad.
 @param slot A object, through which you can pass in the banner unique identifier, ad type, and so on
 @param rootViewController The root controller where the banner is located.
 @param adsize Customize the size of the view. Please make sure that the width and height passed in are available.
 @return BUNativeExpressBannerView
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot
            rootViewController:(UIViewController *)rootViewController
                      adSize:(CGSize)adsize;
/**
 Initializes carousel express banner ad.
 @param slot A object, through which you can pass in the banner unique identifier, ad type, and so on
 @param rootViewController The root controller where the banner is located.
 @param adsize Customize the size of the view. Please make sure that the width and height passed in are available.
 @param interval The carousel interval, in seconds, is set in the range of 30~120s, and is passed during initialization. If it does not meet the requirements, it will not be in carousel ad.
 @return BUNativeExpressBannerView
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot
            rootViewController:(UIViewController *)rootViewController
                        adSize:(CGSize)adsize
                      interval:(NSInteger)interval;
- (void)loadAdData;
@end
@interface BUNativeExpressBannerView (Deprecated)
- (instancetype)initWithSlotID:(NSString *)slotID
            rootViewController:(UIViewController *)rootViewController
                        adSize:(CGSize)adsize
             IsSupportDeepLink:(BOOL)isSupportDeepLink DEPRECATED_MSG_ATTRIBUTE("Use initWithSlotID:rootViewController:adSize: instead.");
- (instancetype)initWithSlotID:(NSString *)slotID
            rootViewController:(UIViewController *)rootViewController
                        adSize:(CGSize)adsize
             IsSupportDeepLink:(BOOL)isSupportDeepLink
                      interval:(NSInteger)interval DEPRECATED_MSG_ATTRIBUTE("Use initWithSlotID:rootViewController:adSize:interval: instead.");
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressFullscreenVideoAd.h
New file
@@ -0,0 +1,149 @@
//
//  BUNativeExpressFullscreenVideoAd.h
//  BUAdSDK
//
//  Copyright Â© 2019 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUMaterialMeta.h"
#import "BUMopubAdMarkUpDelegate.h"
@class BUNativeExpressFullscreenVideoAd;
//define the type of native express video ad
typedef NS_ENUM(NSUInteger, BUNativeExpressFullScreenAdType) {
    BUNativeExpressFullScreenAdTypeEndcard              = 0,        // video + endcard
    BUNativeExpressFullScreenAdTypeVideoPlayable        = 1,        // video + playable
    BUNativeExpressFullScreenAdTypePurePlayable         = 2         // pure playable
};
NS_ASSUME_NONNULL_BEGIN
@protocol BUNativeExpressFullscreenVideoAdDelegate <NSObject>
@optional
/**
 This method is called when video ad material loaded successfully.
 */
- (void)nativeExpressFullscreenVideoAdDidLoad:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad materia failed to load.
 @param error : the reason of error
 */
- (void)nativeExpressFullscreenVideoAd:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error;
/**
 This method is called when rendering a nativeExpressAdView successed.
 It will happen when ad is show.
 */
- (void)nativeExpressFullscreenVideoAdViewRenderSuccess:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd;
/**
 This method is called when a nativeExpressAdView failed to render.
 @param error : the reason of error
 */
- (void)nativeExpressFullscreenVideoAdViewRenderFail:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error;
/**
 This method is called when video cached successfully.
 For a better user experience, it is recommended to display video ads at this time.
 And you can call [BUNativeExpressFullscreenVideoAd showAdFromRootViewController:].
 */
- (void)nativeExpressFullscreenVideoAdDidDownLoadVideo:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad slot will be showing.
 */
- (void)nativeExpressFullscreenVideoAdWillVisible:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad slot has been shown.
 */
- (void)nativeExpressFullscreenVideoAdDidVisible:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad is clicked.
 */
- (void)nativeExpressFullscreenVideoAdDidClick:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when the user clicked skip button.
 */
- (void)nativeExpressFullscreenVideoAdDidClickSkip:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad is about to close.
 */
- (void)nativeExpressFullscreenVideoAdWillClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad is closed.
 */
- (void)nativeExpressFullscreenVideoAdDidClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd;
/**
 This method is called when video ad play completed or an error occurred.
 @param error : the reason of error
 */
- (void)nativeExpressFullscreenVideoAdDidPlayFinish:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error;
/**
This method is used to get the type of nativeExpressFullScreenVideo ad
 */
- (void)nativeExpressFullscreenVideoAdCallback:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd withType:(BUNativeExpressFullScreenAdType) nativeExpressVideoAdType;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)nativeExpressFullscreenVideoAdDidCloseOtherController:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd interactionType:(BUInteractionType)interactionType;
@end
@interface BUNativeExpressFullscreenVideoAd : NSObject <BUMopubAdMarkUpDelegate>
@property (nonatomic, weak, nullable) id<BUNativeExpressFullscreenVideoAdDelegate> delegate;
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid __attribute__((deprecated("Use nativeExpressFullscreenVideoAdDidLoad: instead.")));
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
/**
 Initializes video ad with slot id.
 @param slotID : the unique identifier of video ad.
 @return BUFullscreenVideoAd
 */
- (instancetype)initWithSlotID:(NSString *)slotID;
/**
 Initializes video ad with slot.
 @param slot : A object, through which you can pass in the fullscreen unique identifier, ad type, and so on.
 @return BUNativeExpressFullscreenVideoAd
*/
- (instancetype)initWithSlot:(BUAdSlot *)slot;
/**
 Load video ad datas.
 */
- (void)loadAdData;
/**
 Display video ad.
 @param rootViewController : root view controller for displaying ad.
 @return : whether it is successfully displayed.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController;
/**
 Display video ad.
 @param rootViewController : root view controller for displaying ad.
 @param sceneDescirbe : optional. Identifies a custom description of the presentation scenario.
 @return : whether it is successfully displayed.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritSceneDescribe:(NSString *_Nullable)sceneDescirbe;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressInterstitialAd.h
New file
@@ -0,0 +1,110 @@
//
//  BUNativeExpressInterstitialAd.h
//  BUAdSDK
//
//  Created by xxx on 2019/5/16.
//  Copyright Â© 2019 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUMaterialMeta.h"
#import "BUMopubAdMarkUpDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@class BUSize;
@class BUNativeExpressInterstitialAd;
@protocol BUNativeExpresInterstitialAdDelegate <NSObject>
@optional
/**
 This method is called when interstitial ad material loaded successfully.
 */
- (void)nativeExpresInterstitialAdDidLoad:(BUNativeExpressInterstitialAd *)interstitialAd;
/**
 This method is called when interstitial ad material failed to load.
 @param error : the reason of error
 */
- (void)nativeExpresInterstitialAd:(BUNativeExpressInterstitialAd *)interstitialAd didFailWithError:(NSError * __nullable)error;
/**
 This method is called when rendering a nativeExpressAdView successed.
 */
- (void)nativeExpresInterstitialAdRenderSuccess:(BUNativeExpressInterstitialAd *)interstitialAd;
/**
 This method is called when a nativeExpressAdView failed to render.
 @param error : the reason of error
 */
- (void)nativeExpresInterstitialAdRenderFail:(BUNativeExpressInterstitialAd *)interstitialAd error:(NSError * __nullable)error;
/**
 This method is called when interstitial ad slot will be showing.
 */
- (void)nativeExpresInterstitialAdWillVisible:(BUNativeExpressInterstitialAd *)interstitialAd;
/**
 This method is called when interstitial ad is clicked.
 */
- (void)nativeExpresInterstitialAdDidClick:(BUNativeExpressInterstitialAd *)interstitialAd;
/**
 This method is called when interstitial ad is about to close.
 */
- (void)nativeExpresInterstitialAdWillClose:(BUNativeExpressInterstitialAd *)interstitialAd;
/**
 This method is called when interstitial ad is closed.
 */
- (void)nativeExpresInterstitialAdDidClose:(BUNativeExpressInterstitialAd *)interstitialAd;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)nativeExpresInterstitialAdDidCloseOtherController:(BUNativeExpressInterstitialAd *)interstitialAd interactionType:(BUInteractionType)interactionType;
@end
@interface BUNativeExpressInterstitialAd : NSObject <BUMopubAdMarkUpDelegate>
@property (nonatomic, weak, nullable) id<BUNativeExpresInterstitialAdDelegate> delegate;
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid;
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
/**
 Initializes interstitial ad.
 @param slotID : The unique identifier of interstitial ad.
 @param adsize : custom size of ad view.
 @return BUNativeExpressInterstitialAd
 */
- (instancetype)initWithSlotID:(NSString *)slotID adSize:(CGSize)adsize;
/**
 Initializes express intersitial ad.
 @param slot A object, through which you can pass in the interstitial unique identifier, ad type, and so on
 @param adsize Customize the size of the view. Please make sure that the width and height passed in are available.
 @return BUNativeExpressInterstitialAd
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot adSize:(CGSize)adsize;
/**
 Load interstitial ad datas.
 */
- (void)loadAdData;
/**
 Display interstitial ad.
 @param rootViewController : root view controller for displaying ad.
 @return : whether it is successfully displayed.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressRewardedVideoAd.h
New file
@@ -0,0 +1,168 @@
//
//  BUNativeExpressRewardedVideoAd.h
//  BUAdSDK
//
//  Copyright Â© 2019 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUAdSDKDefines.h"
#import "BUMaterialMeta.h"
#import "BUMopubAdMarkUpDelegate.h"
@class BUNativeExpressRewardedVideoAd;
@class BURewardedVideoModel;
NS_ASSUME_NONNULL_BEGIN
/// define the type of  native express rewarded video Ad
typedef NS_ENUM(NSUInteger, BUNativeExpressRewardedVideoAdType) {
    BUNativeExpressRewardedVideoAdTypeEndcard         = 0,  // video + endcard
    BUNativeExpressRewardedVideoAdTypeVideoPlayable   = 1,  // video + playable
    BUNativeExpressRewardedVideoAdTypePurePlayable    = 2,  // pure playable
};
@protocol BUNativeExpressRewardedVideoAdDelegate <NSObject>
@optional
/**
 This method is called when video ad material loaded successfully.
 */
- (void)nativeExpressRewardedVideoAdDidLoad:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad materia failed to load.
 @param error : the reason of error
 */
- (void)nativeExpressRewardedVideoAd:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error;
/**
  this methods is to tell delegate the type of native express rewarded video Ad
 */
- (void)nativeExpressRewardedVideoAdCallback:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd withType:(BUNativeExpressRewardedVideoAdType)nativeExpressVideoType;
/**
 This method is called when cached successfully.
 For a better user experience, it is recommended to display video ads at this time.
 And you can call [BUNativeExpressRewardedVideoAd showAdFromRootViewController:].
 */
- (void)nativeExpressRewardedVideoAdDidDownLoadVideo:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when rendering a nativeExpressAdView successed.
 It will happen when ad is show.
 */
- (void)nativeExpressRewardedVideoAdViewRenderSuccess:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when a nativeExpressAdView failed to render.
 @param error : the reason of error
 */
- (void)nativeExpressRewardedVideoAdViewRenderFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error;
/**
 This method is called when video ad slot will be showing.
 */
- (void)nativeExpressRewardedVideoAdWillVisible:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad slot has been shown.
 */
- (void)nativeExpressRewardedVideoAdDidVisible:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad is about to close.
 */
- (void)nativeExpressRewardedVideoAdWillClose:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad is closed.
 */
- (void)nativeExpressRewardedVideoAdDidClose:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad is clicked.
 */
- (void)nativeExpressRewardedVideoAdDidClick:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when the user clicked skip button.
 */
- (void)nativeExpressRewardedVideoAdDidClickSkip:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad play completed or an error occurred.
 @param error : the reason of error
 */
- (void)nativeExpressRewardedVideoAdDidPlayFinish:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error;
/**
 Server verification which is requested asynchronously is succeeded. now include two v erify methods:
      1. C2C need  server verify  2. S2S don't need server verify
 @param verify :return YES when return value is 2000.
 */
- (void)nativeExpressRewardedVideoAdServerRewardDidSucceed:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd verify:(BOOL)verify;
/**
 Server verification which is requested asynchronously is failed.
 Return value is not 2000.
 */
- (void)nativeExpressRewardedVideoAdServerRewardDidFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd  __attribute__((deprecated("Use nativeExpressRewardedVideoAdServerRewardDidFail: error: instead.")));
/**
  Server verification which is requested asynchronously is failed.
  @param rewardedVideoAd express rewardVideo Ad
  @param error request error info
 */
- (void)nativeExpressRewardedVideoAdServerRewardDidFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)nativeExpressRewardedVideoAdDidCloseOtherController:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd interactionType:(BUInteractionType)interactionType;
@end
@interface BUNativeExpressRewardedVideoAd : NSObject <BUMopubAdMarkUpDelegate>
@property (nonatomic, strong) BURewardedVideoModel *rewardedVideoModel;
@property (nonatomic, weak, nullable) id<BUNativeExpressRewardedVideoAdDelegate> delegate;
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
/**
 Whether material is effective.
 Setted to YES when data is not empty and has not been displayed.
 Repeated display is not billed.
 */
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid __attribute__((deprecated("Use nativeExpressRewardedVideoAdDidLoad: instead.")));
- (instancetype)initWithSlotID:(NSString *)slotID rewardedVideoModel:(BURewardedVideoModel *)model;
/**
 Initializes Rewarded video ad with ad slot and frame.
 @param slot A object, through which you can pass in the reward unique identifier, ad type, and so on.
 @param model Rewarded video model.
 @return BUNativeExpressRewardedVideoAd
*/
- (instancetype)initWithSlot:(BUAdSlot *)slot rewardedVideoModel:(BURewardedVideoModel *)model;
- (void)loadAdData;
/**
 Display video ad.
 @param rootViewController : root view controller for displaying ad.
 @return : whether it is successfully displayed.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController;
/**
 If ritSceneType is custom, you need to pass in the values for sceneDescirbe.
 @param ritSceneType  : optional. Identifies a custom description of the presentation scenario.
 @param sceneDescirbe : optional. Identify the scene of presentation.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritScene:(BURitSceneType)ritSceneType ritSceneDescribe:(NSString *_Nullable)sceneDescirbe;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUNativeExpressSplashView.h
New file
@@ -0,0 +1,137 @@
//
//  BUNativeExpressSplashView.h
//  BUAdSDK
//
//  Copyright Â© 2019 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUMaterialMeta.h"
#import "BUMopubAdMarkUpDelegate.h"
@class BUNativeExpressSplashView;
NS_ASSUME_NONNULL_BEGIN
@protocol BUNativeExpressSplashViewDelegate <NSObject>
/**
 This method is called when splash ad material loaded successfully.
 */
- (void)nativeExpressSplashViewDidLoad:(BUNativeExpressSplashView *)splashAdView;
/**
 This method is called when splash ad material failed to load.
 @param error : the reason of error
 */
- (void)nativeExpressSplashView:(BUNativeExpressSplashView *)splashAdView didFailWithError:(NSError * _Nullable)error;
/**
 This method is called when rendering a nativeExpressAdView successed.
 */
- (void)nativeExpressSplashViewRenderSuccess:(BUNativeExpressSplashView *)splashAdView;
/**
 This method is called when a nativeExpressAdView failed to render.
 @param error : the reason of error
 */
- (void)nativeExpressSplashViewRenderFail:(BUNativeExpressSplashView *)splashAdView error:(NSError * __nullable)error;
/**
 This method is called when nativeExpressSplashAdView will be showing.
 */
- (void)nativeExpressSplashViewWillVisible:(BUNativeExpressSplashView *)splashAdView;
/**
 This method is called when nativeExpressSplashAdView is clicked.
 */
- (void)nativeExpressSplashViewDidClick:(BUNativeExpressSplashView *)splashAdView;
/**
 This method is called when nativeExpressSplashAdView's skip button is clicked.
 */
- (void)nativeExpressSplashViewDidClickSkip:(BUNativeExpressSplashView *)splashAdView;
/**
 This method is called when nativeExpressSplashAdView countdown equals to zero
 */
- (void)nativeExpressSplashViewCountdownToZero:(BUNativeExpressSplashView *)splashAdView;
/**
 This method is called when nativeExpressSplashAdView closed.
 */
- (void)nativeExpressSplashViewDidClose:(BUNativeExpressSplashView *)splashAdView;
/**
 This method is called when when video ad play completed or an error occurred.
 */
- (void)nativeExpressSplashViewFinishPlayDidPlayFinish:(BUNativeExpressSplashView *)splashView didFailWithError:(NSError *)error;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)nativeExpressSplashViewDidCloseOtherController:(BUNativeExpressSplashView *)splashView interactionType:(BUInteractionType)interactionType;
@end
@interface BUNativeExpressSplashView : UIView <BUMopubAdMarkUpDelegate>
/**
 The delegate for receiving state change messages.
 */
@property (nonatomic, weak, nullable) id<BUNativeExpressSplashViewDelegate> delegate;
/**
 Maximum allowable load timeout, default 3s, unit s.
 */
@property (nonatomic, assign) NSTimeInterval tolerateTimeout;
/**
 Whether hide skip button, default NO.
 If you hide the skip button, you need to customize the countdown.
 */
@property (nonatomic, assign) BOOL hideSkipButton;
/**
 Whether the splash ad data has been loaded.
 */
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid;
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
/**
 Initializes native express splash ad with slot id and frame.
 @param slotID : the unique identifier of splash ad
 @param adSize : the adSize of native express splashAd view. It is recommended for the mobile phone screen.
 @param rootViewController : the root controller for present splash.
 @return BUNativeExpressSplashView
 */
- (instancetype)initWithSlotID:(NSString *)slotID adSize:(CGSize)adSize rootViewController:(UIViewController *)rootViewController;
/**
 Initializes Express Splash video ad with ad slot, adSize and rootViewController.
 @param slot A object, through which you can pass in the splash unique identifier, ad type, and so on.
 @param adSize the adSize of native express splashAd view. It is recommended for the mobile phone screen.
 @param rootViewController the root controller for present splash.
 @return BUNativeExpressSplashView
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot adSize:(CGSize)adSize rootViewController:(UIViewController *)rootViewController;
/**
 Load splash ad datas.
 Start the countdown(@tolerateTimeout) as soon as you request datas.
 */
- (void)loadAdData;
/**
 Remove splash view.
 Stop the countdown as soon as you call this method.
 ç§»é™¤å¼€å±è§†å›¾
 ä¸€æ—¦è°ƒç”¨è¿™ä¸ªæ–¹æ³•,倒计时将自动停止
 */
- (void)removeSplashView;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUPersonalizationPrompts.h
New file
@@ -0,0 +1,24 @@
//
//  BUPersonalizationPrompts.h
//  BUAdSDK
//
//  Created by bytedance on 2020/11/10.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface BUPersonalizationPrompts : NSObject <NSCoding>
/// personalization prompts's name
@property (nonatomic, copy) NSString *personalizationName;
/// personalization prompts's url
@property (nonatomic, copy) NSString *personalizationUrl;
/// personalization prompts valid or not
- (BOOL)validPersonalPrompts;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUPlayerPublicDefine.h
New file
@@ -0,0 +1,20 @@
//
//  BUPlayerPublicDefine.h
//  BUAdSDK
//
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#ifndef BUPlayerPublicDefine_h
#define BUPlayerPublicDefine_h
typedef NS_ENUM(NSInteger, BUPlayerPlayState) {
    BUPlayerStateFailed    = 0,
    BUPlayerStateBuffering = 1,
    BUPlayerStatePlaying   = 2,
    BUPlayerStateStopped   = 3,
    BUPlayerStatePause     = 4,
    BUPlayerStateDefalt    = 5
};
#endif /* BUPlayerPublicDefine_h */
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BURewardedVideoAd.h
New file
@@ -0,0 +1,149 @@
//
//  BURewardedVideoAd.h
//  BUAdSDK
//
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUAdSDKDefines.h"
#import "BUMopubAdMarkUpDelegate.h"
NS_ASSUME_NONNULL_BEGIN
/// define the type of rewarded video ad
typedef NS_ENUM(NSUInteger, BURewardedVideoAdType) {
    BURewardedVideoAdTypeEndcard        = 0,    // video + endcard
    BURewardedVideoAdTypeVideoPlayable  = 1,    // video + playable
    BURewardedVideoAdTypePurePlayable   = 2     // pure playable
};
@protocol BURewardedVideoAdDelegate;
@class BURewardedVideoModel;
@interface BURewardedVideoAd : NSObject <BUMopubAdMarkUpDelegate>
@property (nonatomic, strong) BURewardedVideoModel *rewardedVideoModel;
@property (nonatomic, weak, nullable) id<BURewardedVideoAdDelegate> delegate;
/**
 Whether material is effective.
 Setted to YES when data is not empty and has not been displayed.
 Repeated display is not billed.
 */
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid __attribute__((deprecated("Use rewardedVideoAdDidLoad: instead.")));
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
- (instancetype)initWithSlotID:(NSString *)slotID rewardedVideoModel:(BURewardedVideoModel *)model;
/**
 Initializes Rewarded video ad with ad slot and frame.
 @param slot A object, through which you can pass in the reward unique identifier, ad type, and so on.
 @param model Rewarded video model.
 @return BURewardedVideoAd
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot rewardedVideoModel:(BURewardedVideoModel *)model;
- (void)loadAdData;
/**
 Display video ad.
 @param rootViewController : root view controller for displaying ad.
 @return : whether it is successfully displayed.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController;
/**
 If ritSceneType is custom, you need to pass in the values for sceneDescirbe.
 @param ritSceneType  : optional. Identifies a custom description of the presentation scenario.
 @param sceneDescirbe : optional. Identify the scene of presentation.
 */
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritScene:(BURitSceneType)ritSceneType ritSceneDescribe:(NSString *_Nullable)sceneDescirbe;
@end
@protocol BURewardedVideoAdDelegate <NSObject>
@optional
/**
 This method is called when video ad material loaded successfully.
 */
- (void)rewardedVideoAdDidLoad:(BURewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad materia failed to load.
 @param error : the reason of error
 */
- (void)rewardedVideoAd:(BURewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error;
/**
 This method is called when cached successfully.
 */
- (void)rewardedVideoAdVideoDidLoad:(BURewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad slot will be showing.
 */
- (void)rewardedVideoAdWillVisible:(BURewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad slot has been shown.
 */
- (void)rewardedVideoAdDidVisible:(BURewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad is about to close.
 */
- (void)rewardedVideoAdWillClose:(BURewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad is closed.
 */
- (void)rewardedVideoAdDidClose:(BURewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad is clicked.
 */
- (void)rewardedVideoAdDidClick:(BURewardedVideoAd *)rewardedVideoAd;
/**
 This method is called when video ad play completed or an error occurred.
 @param error : the reason of error
 */
- (void)rewardedVideoAdDidPlayFinish:(BURewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error;
/**
 Server verification which is requested asynchronously is succeeded.
 @param verify :return YES when return value is 2000.
 */
- (void)rewardedVideoAdServerRewardDidSucceed:(BURewardedVideoAd *)rewardedVideoAd verify:(BOOL)verify;
/**
 Server verification which is requested asynchronously is failed.
 Return value is not 2000.
 */
- (void)rewardedVideoAdServerRewardDidFail:(BURewardedVideoAd *)rewardedVideoAd __attribute__((deprecated("Use rewardedVideoAdServerRewardDidFail: error: instead.")));
/**
  Server verification which is requested asynchronously is failed.
  @param rewardedVideoAd rewarded Video ad
  @param error request error info
 */
- (void)rewardedVideoAdServerRewardDidFail:(BURewardedVideoAd *)rewardedVideoAd error:(NSError *)error;
/**
 This method is called when the user clicked skip button.
 */
- (void)rewardedVideoAdDidClickSkip:(BURewardedVideoAd *)rewardedVideoAd;
/**
 this method is used to get type of rewarded video Ad
 */
- (void)rewardedVideoAdCallback:(BURewardedVideoAd *)rewardedVideoAd withType:(BURewardedVideoAdType)rewardedVideoAdType;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BURewardedVideoModel.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUSize.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUSplashAdView.h
New file
@@ -0,0 +1,135 @@
//
//  BUSplashAdView.h
//  BUAdSDK
//
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUMaterialMeta.h"
#import "BUSplashZoomOutView.h"
#import "BUMopubAdMarkUpDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@protocol BUSplashAdDelegate;
@interface BUSplashAdView : UIView <BUMopubAdMarkUpDelegate>
/**
The unique identifier of splash ad.
 */
@property (nonatomic, copy, readonly, nonnull) NSString *slotID;
/**
 Maximum allowable load timeout, default 3s, unit s.
 */
@property (nonatomic, assign) NSTimeInterval tolerateTimeout;
/**
 Whether hide skip button, default NO.
 If you hide the skip button, you need to customize the countdown.
 */
@property (nonatomic, assign) BOOL hideSkipButton;
/**
 The delegate for receiving state change messages.
 */
@property (nonatomic, weak, nullable) id<BUSplashAdDelegate> delegate;
/*
 required.
 Root view controller for handling ad actions.
 */
@property (nonatomic, weak) UIViewController *rootViewController;
/**
 Whether the splash ad data has been loaded.
 */
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid;
/// media configuration parameters.
@property (nonatomic, copy, readonly) NSDictionary *mediaExt;
/// When it is a zoom out advertisement, it has value.
@property (nonatomic, strong, readonly) BUSplashZoomOutView *zoomOutView;
/**
 Initializes splash ad with slot id and frame.
 @param slotID : the unique identifier of splash ad
 @param frame : the frame of splashAd view. It is recommended for the mobile phone screen.
 @return BUSplashAdView
 */
- (instancetype)initWithSlotID:(NSString *)slotID frame:(CGRect)frame;
/**
 Initializes splash ad with ad slot and frame.
 @param slot A object, through which you can pass in the splash unique identifier、ad type, and so on
 @param frame the frame of splashAd view. It is recommended for the mobile phone screen.
 @return BUSplashAdView
 */
- (instancetype)initWithSlot:(BUAdSlot *)slot frame:(CGRect)frame;
/**
 Load splash ad datas.
 Start the countdown(@tolerateTimeout) as soon as you request datas.
 */
- (void)loadAdData;
@end
@protocol BUSplashAdDelegate <NSObject>
@optional
/**
 This method is called when splash ad material loaded successfully.
 */
- (void)splashAdDidLoad:(BUSplashAdView *)splashAd;
/**
 This method is called when splash ad material failed to load.
 @param error : the reason of error
 */
- (void)splashAd:(BUSplashAdView *)splashAd didFailWithError:(NSError * _Nullable)error;
/**
 This method is called when splash ad slot will be showing.
 */
- (void)splashAdWillVisible:(BUSplashAdView *)splashAd;
/**
 This method is called when splash ad is clicked.
 */
- (void)splashAdDidClick:(BUSplashAdView *)splashAd;
/**
 This method is called when splash ad is closed.
 */
- (void)splashAdDidClose:(BUSplashAdView *)splashAd;
/**
 This method is called when splash ad is about to close.
 */
- (void)splashAdWillClose:(BUSplashAdView *)splashAd;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)splashAdDidCloseOtherController:(BUSplashAdView *)splashAd interactionType:(BUInteractionType)interactionType;
/**
 This method is called when spalashAd skip button  is clicked.
 */
- (void)splashAdDidClickSkip:(BUSplashAdView *)splashAd;
/**
 This method is called when spalashAd countdown equals to zero
 */
- (void)splashAdCountdownToZero:(BUSplashAdView *)splashAd;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUSplashZoomOutView.h
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUVideoAdDelegate.h
New file
@@ -0,0 +1,58 @@
//
//  BUVideoAdDelegate.h
//  BUAdSDK
//
//  Created by æŽç›› on 2018/8/3.
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BURewardedVideoAd.h"
/**
    ç”¨äºŽæ’屏视频 æ¿€åŠ±è§†é¢‘ æŽ¥å£ç»Ÿä¸€é…ç½®
 */
@protocol BUVideoAdDelegate <NSObject>
@property (nonatomic, assign) BOOL isRewardedVideo;
/**
 è§†é¢‘点击即将关闭
 */
- (void)videoAdWillClose;
/**
 è§†é¢‘点击关闭
 */
- (void)videoAdDidClose;
/**
 è§†é¢‘/落地页点击
 */
- (void)videoAdDidClick;
/**
 è§†é¢‘播放完成
 */
- (void)videoAdDidPlayFinishWithError:(NSError *)error;
@optional
@property (nonatomic, strong) BURewardedVideoModel *rewardedVideoModel;
/**
 è§†é¢‘点击跳过
 */
- (void)videoAdDidClickSkip;
/**
 æœåŠ¡å™¨æ ¡éªŒå¥–åŠ±æˆåŠŸå‘æ”¾.  2800进行了修改,包含了两种方式.
  1.C2C ä¸èµ°æœåŠ¡ç«¯éªŒè¯ï¼Œç›´æŽ¥æ ¹æ®æ—¶é—´å‘æ”¾å¥–åŠ±  2.S2S è€é€»è¾‘需要服务端验证
 */
- (void)videoAdServerRewardDidSucceedVerify:(BOOL)verify;
/**
 æœåŠ¡å™¨æ ¡éªŒå¥–åŠ±æŽ¥å£è¯·æ±‚å¤±è´¥
 */
- (void)videoAdServerRewardDidFailWithError:(NSError *)error;
@end
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUVideoAdReportor.h
New file
@@ -0,0 +1,65 @@
//
//  BUVideoAdReportor.h
//  BUAdSDK
//
//  Created by bytedance on 2020/8/3.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/// the reportor of video ad in feed, auto created by system if video ads in feed is customd.
@protocol BUVideoAdReportor <NSObject>
@required
/// report  start play video
- (void)startPlayVideo;
/// report did start play video
/// @param duration total duration of video, unit ms
- (void)didStartPlayVideoWithVideoDuration:(NSTimeInterval)duration;
/// report did start play video auto, designed by developer
/// @param duration total duration of video, unit ms
- (void)didAutoStartPlayWithVideoDuration:(NSTimeInterval)duration;
/// report did play to the end of video
- (void)didFinishVideo;
/// report did pause video
/// @param duration duration of video that user watched
- (void)didPauseVideoWithCurrentDuration:(NSTimeInterval)duration;
/// report did resume video from paused
/// @param duration duration of video that user watched
- (void)didResumeVideoWithCurrentDuration:(NSTimeInterval)duration;
/// report did break video playing, maybe change another video or disappear from screen and so on
/// @param duration duration of video that user watched
- (void)didBreakVideoWithCurrentDuration:(NSTimeInterval)duration;
/// report did click video view, auto implement by Pangle, developers need not call this method
/// @param duration duration of video that user watched
- (void)didClickVideoViewWithCurrentDuration:(NSTimeInterval)duration;
/// report sth. wrong with playing
/// @param error error
- (void)didPlayFailedWithError:(NSError *)error;
/// report sth. wrong with play start
/// @param error error
- (void)didPlayStartFailedWithError:(NSError *)error;
/// reprot did buffering video
- (void)didPlayBufferStart;
/// reprot did buffering video ended
- (void)didPlayBufferEnd;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/BUVideoAdView.h
New file
@@ -0,0 +1,130 @@
//
//  BUVideoAdView.h
//  BUAdSDK
//
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUPlayerPublicDefine.h"
#import "BUMaterialMeta.h"
@class BUMaterialMeta;
NS_ASSUME_NONNULL_BEGIN
/**
 Control TikTok Audience Network video player.
 */
@protocol BUVideoEngine <NSObject>
/**
 Get the already played time.
 */
- (CGFloat)currentPlayTime;
/**
 Set video play when you support CustomMode
 **/
- (void)play;
/**
 Set video pause when you support CustomMode
**/
- (void)pause;
@end
@protocol BUVideoAdViewDelegate;
@interface BUVideoAdView : UIView<BUVideoEngine>
@property (nonatomic, weak, nullable) id<BUVideoAdViewDelegate> delegate;
/**
required. Root view controller for handling ad actions.
 **/
@property (nonatomic, weak, readwrite) UIViewController *rootViewController;
/**
 Whether to allow pausing the video by clicking, default NO. Only for draw video(vertical video ads).
 **/
@property (nonatomic, assign) BOOL drawVideoClickEnable;
/**
AdType information.
*/
@property (nonatomic, assign) NSInteger AdType;
/**
 material information.
 */
@property (nonatomic, strong, readwrite, nullable) BUMaterialMeta *materialMeta;
/**
 Set your Video autoPlayMode when you support CustomMode
 if support CustomMode , default autoplay Video
 **/
@property (nonatomic, assign) BOOL supportAutoPlay;
- (instancetype)initWithMaterial:(BUMaterialMeta *)materialMeta;
/**
 Resume to the corresponding time.
 */
- (void)playerSeekToTime:(CGFloat)time;
/**
 Support configuration for pause button.
 @param playImg : the image of the button
 @param playSize : the size of the button. Set as cgsizezero to use default icon size.
 */
- (void)playerPlayIncon:(UIImage *)playImg playInconSize:(CGSize)playSize;
@end
@protocol BUVideoAdViewDelegate <NSObject>
@optional
/**
 This method is called when videoadview failed to play.
 @param error : the reason of error
 */
- (void)videoAdView:(BUVideoAdView *)videoAdView didLoadFailWithError:(NSError *_Nullable)error;
/**
 This method is called when videoadview ready to play.
 */
- (void)playerReadyToPlay:(BUVideoAdView *)videoAdView;
/**
 This method is called when videoadview playback status changed.
 @param playerState : player state after changed
 */
- (void)videoAdView:(BUVideoAdView *)videoAdView stateDidChanged:(BUPlayerPlayState)playerState;
/**
 This method is called when videoadview end of play.
 */
- (void)playerDidPlayFinish:(BUVideoAdView *)videoAdView;
/**
 This method is called when videoadview is clicked.
 */
- (void)videoAdViewDidClick:(BUVideoAdView *)videoAdView;
/**
 This method is called when videoadview's finish view is clicked.
 */
- (void)videoAdViewFinishViewDidClick:(BUVideoAdView *)videoAdView;
/**
 This method is called when another controller has been closed.
 @param interactionType : open appstore in app or open the webpage or view video ad details page.
 */
- (void)videoAdViewDidCloseOtherController:(BUVideoAdView *)videoAdView interactionType:(BUInteractionType)interactionType;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/PangleNativeBannerView.h
New file
@@ -0,0 +1,20 @@
//
//  PangleNativeBannerView.h
//  BUADDemo
//
//  Created by bytedance on 2020/4/24.
//  Copyright Â© 2020 Bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUNativeAd.h"
NS_ASSUME_NONNULL_BEGIN
static CGFloat const bottomHeight = 30;
@interface PangleNativeBannerView : UIView
@property (nonatomic, strong) BUNativeAd *nativeAd;
- (instancetype)initWithSize:(CGSize)size;
- (void)refreshUIWithAd:(BUNativeAd *_Nonnull)nativeAd;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/A/Headers/PangleNativeInterstitialView.h
New file
@@ -0,0 +1,29 @@
//
//  PangleNativeInterstitialView.h
//  BUDemo
//
//  Created by bytedance on 2020/4/24.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUNativeAd.h"
NS_ASSUME_NONNULL_BEGIN
@protocol PangleNativeInterstitialViewDelegate <NSObject>
- (void)nativeInterstitialAdWillClose:(BUNativeAd *)nativeAd;
- (void)nativeInterstitialAdDidClose:(BUNativeAd *)nativeAd;
@end
@interface PangleNativeInterstitialView : UIViewController
@property (nonatomic, getter=isAdValid, readonly) BOOL adValid;
- (void)refreshUIWithAd:(BUNativeAd *_Nonnull)nativeAd;
- (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController delegate:(id <PangleNativeInterstitialViewDelegate>)delegate;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUAdSDK.framework/Versions/Current
New file
@@ -0,0 +1 @@
A
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/BUCNAuxiliary
Binary files differ
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/BUCNAuxiliary
New file
@@ -0,0 +1 @@
Versions/Current/BUCNAuxiliary
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers
New file
@@ -0,0 +1 @@
Versions/Current/Headers
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers/BUCNAuxiliary.h
File was deleted
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers/BUCNAuxiliaryManager.h
File was deleted
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Headers/BUCNCommonHeader.h
File was deleted
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Info.plist
Binary files differ
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Modules/module.modulemap
File was deleted
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/BUCNAuxiliary
Binary files differ
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUAppleBacktracesLog.h
New file
@@ -0,0 +1,103 @@
//
//  HMDBUAppleBacktracesLog.h
//  HeimdallrBU
//
//  Created by è°¢ä¿Šé€¸ on 2019/3/18.
//
#import <Foundation/Foundation.h>
#import "HMDBUAsyncThread.h"
#import "HMDBUThreadBacktrace.h"
#import "HMDBULog.h"
NS_ASSUME_NONNULL_BEGIN
@interface HMDBUAppleBacktracesLog : NSObject
#pragma mark - deprecated API
+ (NSString *)getAllThreadsLogByKeyThread:(thread_t)keyThread
                             skippedDepth:(NSUInteger)skippedDepth
                                  logType:(HMDBULogType)type __attribute__((deprecated("已废弃,请使用New API")));
+ (NSString *)getAllThreadsLogBySkippedDepth:(NSUInteger)skippedDepth
                                     logType:(HMDBULogType)type __attribute__((deprecated("已废弃,请使用New API")));
+ (NSString *)getAllThreadsLogByKeyThread:(thread_t)keyThread
                             skippedDepth:(NSUInteger)skippedDepth
                                  logType:(HMDBULogType)type
                                exception:(NSString * _Nullable)exceptionField
                                   reason:(NSString * _Nullable)reasonField __attribute__((deprecated("已废弃,请使用New API")));
+ (NSString *)getMainThreadLogBySkippedDepth:(NSUInteger)skippedDepth
                                     logType:(HMDBULogType)type __attribute__((deprecated("已废弃,请使用New API")));
+ (NSString *)getCurrentThreadLogBySkippedDepth:(NSUInteger)skippedDepth
                                        logType:(HMDBULogType)type __attribute__((deprecated("已废弃,请使用New API")));
+ (NSString *)getThreadLog:(thread_t)thread
            BySkippedDepth:(NSUInteger)skippedDepth
                   logType:(HMDBULogType)type __attribute__((deprecated("已废弃,请使用New API")));
#pragma mark - New API
+ (thread_t)mainThread;
+ (thread_t)currentThread;
/**
 * å‚数说明:
 * @param keyThread æ ‡æ³¨ä¸ºå´©æºƒçš„线程,Slardar平台根据该线程堆栈进行聚合。
 *                  - ä¸»çº¿ç¨‹ï¼š[HMDBUAppleBacktracesLog mainThread]
 *                  - å½“前线程:[HMDBUAppleBacktracesLog currentThread]
 * @param skippedDepth å½“前调用的线程索要忽略的调用栈深度
 * @param maxThreadCount é™åˆ¶ç”Ÿæˆæ—¥å¿—的最大线程数
 *                      - 0表示不做限制
 *                      - è‹¥å½“前线程数大于设置最大线程数,取线程队列的前N个生成堆栈信息
 * @param suspend èŽ·å–çº¿ç¨‹å †æ ˆæ—¶æ˜¯å¦å¯¹çº¿ç¨‹è¿›è¡ŒæŒ‚èµ·
 *                - æŒ‚起线程获取的堆栈准确无误,但会损失部分性能
 *                - ä¸è¿›è¡ŒæŒ‚起可能会造成堆栈信息失真
 */
// ä»¥ä¸‹ä¸ºåŒæ­¥èŽ·å–log方法,堆栈获取为较耗操作,在主线程时调用,请使用下面的异步方法
+ (NSString * _Nullable)getAllThreadsLogByKeyThread:(thread_t)keyThread
                                     maxThreadCount:(NSUInteger)maxThreadCount
                                       skippedDepth:(NSUInteger)skippedDepth
                                            logType:(HMDBULogType)type
                                            suspend:(BOOL)suspend
                                          exception:(NSString * _Nullable)exception
                                             reason:(NSString * _Nullable)reason;
+ (NSString * _Nullable)getThreadLogByThread:(thread_t)keyThread
                                skippedDepth:(NSUInteger)skippedDepth
                                     logType:(HMDBULogType)type
                                     suspend:(BOOL)suspend
                                   exception:(NSString * _Nullable)exception
                                      reason:(NSString * _Nullable)reason;
// ä»¥ä¸‹ä¸ºå¼‚步方法,在主线程调用推荐使用异步方法避免耗时而卡死
+ (void)getAllThreadsLogByKeyThread:(thread_t)keyThread
                     maxThreadCount:(NSUInteger)maxThreadCount
                       skippedDepth:(NSUInteger)skippedDepth
                            logType:(HMDBULogType)type
                            suspend:(BOOL)suspend
                          exception:(NSString * _Nullable)exception
                             reason:(NSString * _Nullable)reason
                           callback:(void(^)(BOOL success, NSString *log))callback;
+ (void)getThreadLogByThread:(thread_t)keyThread
                skippedDepth:(NSUInteger)skippedDepth
                     logType:(HMDBULogType)type
                     suspend:(BOOL)suspend
                   exception:(NSString * _Nullable)exception
                      reason:(NSString * _Nullable)reason
                    callback:(void(^)(BOOL success, NSString *log))callback;
+ (NSString *_Nullable)logWithBacktraces:(NSArray <HMDBUThreadBacktrace *>*)backtraces
                                    type:(HMDBULogType)type
                               exception:(NSString * _Nullable)exceptionField
                                  reason:(NSString * _Nullable)reasonField;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUBacktraceLog.h
New file
@@ -0,0 +1,14 @@
//
//  HMDBUBacktraceLog.h
//  AppleCrashLog
//
//  Created by è°¢ä¿Šé€¸ on 8/3/2018.
//
#import <Foundation/Foundation.h>
#import "HMDBUThreadBacktrace.h"
@interface HMDBUBacktraceLog : NSObject
+ (NSString *)backtraceLogStringWithBacktraceInfo:(HMDBUThreadBacktrace*)backtraceInfo;
@end
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUEmbedAddressRange.h
New file
@@ -0,0 +1,25 @@
//
//  HMDBUEmbedAddressRange.h
//  HeimdallrBUEmbed
//
//  Created by xuminghao.eric on 2020/12/14.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface HMDBUEmbedAddressRange : NSObject
/**
 startAddress ç›´æŽ¥ä¼ å½“前加载进去的函数地址就好了
 endAddress ç›´æŽ¥ä¼ å½“前加载进去的函数地址就好了
 */
@property(nonatomic, assign)int64_t startAddress;
@property(nonatomic, assign)int64_t endAddress;
+ (instancetype)addressRangeWithStartAddress:(int64_t)startAddress endAddress:(int64_t)endAddress;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUHeaderLog.h
New file
@@ -0,0 +1,22 @@
//
//  HMDBUHeaderLog.h
//  HeimdallrBU
//
//  Created by è°¢ä¿Šé€¸ on 12/3/2018.
//
#import <Foundation/Foundation.h>
#import "HMDBULog.h"
#ifdef __cplusplus
extern "C" {
#endif
void hmdbu_setup_log_header(void); // åˆå§‹åŒ–header数据
char *hmdbu_log_header(HMDBULogType logType); // èŽ·å–å †æ ˆheader,必须先调用hmdbu_setup_log_header完成初始化
#ifdef __cplusplus
}  // extern "C"
#endif
@interface HMDBUHeaderLog : NSObject
+ (NSString *)hmdbuHeaderLogString:(HMDBULogType)logType;
@end
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBUImageLog.h
New file
@@ -0,0 +1,17 @@
//
//  HMDBUImageLog.h
//  HeimdallrBU
//
//  Created by è°¢ä¿Šé€¸ on 12/3/2018.
//
#import <Foundation/Foundation.h>
#import <mach/machine.h>
#import "HMDBUBinaryImage.h"
@interface HMDBUImageLog : NSObject
+ (NSString *)imageLogStringWithImageInfo:(HMDBUBinaryImage *)info;
+ (NSString *)binaryImagesLogStr;
+ (NSString *)binaryImagesLogStrWithValidImages:(NSMutableSet<NSString*>*)imageSet;
@end
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HMDBULog.h
New file
@@ -0,0 +1,49 @@
//
//  HMDBULog.h
//  HeimdallrBU
//
//  Created by è°¢ä¿Šé€¸ on 14/3/2018.
//
#import <Foundation/Foundation.h>
#define WatchDogIdentifier @"Heimdallr_WatchDog_Log"
#define OOMIdentifier @"Heimdallr_OOM_Log"
#define CrashIdentifier @"Heimdallr_Crash_Log"
#define ANRIdentifier @"Heimdallr_ANR_Log"
#define ExceptionIdentifier @"Heimdallr_Exception_Log"
#define ExceptionProtectIdentifier @"Heimdallr_ExceptionProtect_Log"
#define UserExceptionIdentifier @"Heimdallr_UserException_Log"
#define NetworkErrorIdentifier @"Heimdallr_Network_Log"
/// format æ ¼å¼
#if defined(__LP64__)
#define FMT_LONG_DIGITS "16"
#define FMT_RJ_SPACES "18"
#else
#define FMT_LONG_DIGITS "8"
#define FMT_RJ_SPACES "10"
#endif
#define FMT_PTR_SHORT        @"0x%" PRIxPTR
#define FMT_PTR_LONG         @"0x%0" FMT_LONG_DIGITS PRIxPTR
#define FMT_PTR_RJ           @"%#" FMT_RJ_SPACES PRIxPTR
#define FMT_OFFSET           @"%" PRIuPTR
#define FMT_TRACE_PREAMBLE       @"%-4d%-31s " FMT_PTR_LONG
#define FMT_TRACE_UNSYMBOLICATED FMT_PTR_SHORT @" + " FMT_OFFSET
#define FMT_TRACE_SYMBOLICATED   @"%@ + " FMT_OFFSET
#define HMDBUAppleRedactedText @"<redacted>"
#define kExpectedMajorVersion 3
typedef NS_ENUM(NSUInteger, HMDBULogType) {
    HMDBULogWatchDog,
    HMDBULogOOM,
    HMDBULogANR,
    HMDBULogCrash,
    HMDBULogException,
    HMDBULogExceptionProtect,
    HMDBULogUserException,
    HMDBULogNetworkError
};
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HeimdallrBUEmbed.h
New file
@@ -0,0 +1,21 @@
//
//  HeimdallrBUEmbed.h
//  HeimdallrBUEmbed
//
//  Created by xuminghao.eric on 2020/12/14.
//
#import <Foundation/Foundation.h>
#import "HeimdallrBUEmbedConfig.h"
NS_ASSUME_NONNULL_BEGIN
@interface HeimdallrBUEmbed : NSObject
+ (void)registerSDKWithConfig:(HeimdallrBUEmbedConfig *)config;
+ (void)start;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/A/Headers/HeimdallrBUEmbedConfig.h
New file
@@ -0,0 +1,23 @@
//
//  HeimdallrBUEmbedConfig.h
//  HeimdallrBUEmbed
//
//  Created by xuminghao.eric on 2020/12/14.
//
#import <Foundation/Foundation.h>
#import "HMDBUEmbedAddressRange.h"
NS_ASSUME_NONNULL_BEGIN
@interface HeimdallrBUEmbedConfig : NSObject
@property (nonatomic, copy) NSString *sdkID;
@property (nonatomic, strong) NSDictionary<NSString *, NSString *> *filter;
@property (nonatomic, strong) NSArray<HMDBUEmbedAddressRange *> *addressRanges;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUCNAuxiliary.framework/Versions/Current
New file
@@ -0,0 +1 @@
A
BuWanVideo2.0/CSJ/BUFoundation.framework/BUFoundation
Binary files differ
BuWanVideo2.0/CSJ/BUFoundation.framework/BUFoundation
New file
@@ -0,0 +1 @@
Versions/Current/BUFoundation
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers
New file
@@ -0,0 +1 @@
Versions/Current/Headers
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUBundleHelper.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUCommonMacros.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUFoundation.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUFoundationAddress.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUGeckoPreloadManager.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUJSBDefine.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUJSInjectorRule.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUReachability.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BURexxarEngineFactory.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUTimer.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUUIResponderHelper.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/BUWebViewApplication.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSArray+BUUtilities.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSDictionary+BUUtilities.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSJSONSerialization+BUSafeSerializaiton.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSString+BUAddtion.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/NSUserDefaults+BUCrypt.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIColor+BUTheme.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIImage+BUIcon.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIImage+BUTransform.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Headers/UIViewController+BUUtilities.h
File was deleted
BuWanVideo2.0/CSJ/BUFoundation.framework/Info.plist
Binary files differ
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/BUFoundation
Binary files differ
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUBase64.h
New file
@@ -0,0 +1,53 @@
//
//  Base64.h
//
//  Version 1.2
//
//  Created by Nick Lockwood on 12/01/2012.
//  Copyright (C) 2012 Charcoal Design
//
//  Distributed under the permissive zlib License
//  Get the latest version from here:
//
//  https://github.com/nicklockwood/Base64
//
//  This software is provided 'as-is', without any express or implied
//  warranty.  In no event will the authors be held liable for any damages
//  arising from the use of this software.
//
//  Permission is granted to anyone to use this software for any purpose,
//  including commercial applications, and to alter it and redistribute it
//  freely, subject to the following restrictions:
//
//  1. The origin of this software must not be misrepresented; you must not
//  claim that you wrote the original software. If you use this software
//  in a product, an acknowledgment in the product documentation would be
//  appreciated but is not required.
//
//  2. Altered source versions must be plainly marked as such, and must not be
//  misrepresented as being the original software.
//
//  3. This notice may not be removed or altered from any source distribution.
//
#import <Foundation/Foundation.h>
@interface NSData (BUBase64)
+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
- (NSString *)base64EncodedString;
@end
@interface NSString (BUBase64)
+ (NSString *)stringWithBase64EncodedString:(NSString *)string;
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
- (NSString *)base64EncodedString;
- (NSString *)base64DecodedString;
- (NSData *)base64DecodedData;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUBaseRequest.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUCacheManager.h
New file
@@ -0,0 +1,45 @@
//
//  BUCacheManager.h
//  BUAdSDK
//
//  Created by æŽç›› on 2018/9/19.
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
extern NSString *BUCacheConfigurationKey;
extern NSString *BUCacheFinishedErrorKey;
@class BUCacheConfiguration;
@interface BUCacheManager : NSObject
+ (instancetype)shared;
// è®¾ç½®ç¼“存目录
+ (void)setCacheDirectory:(NSString *)cacheDirectory;
// èŽ·å–ç¼“å­˜ç›®å½•
+ (NSString *)cacheDirectory;
/// èŽ·å–è§†é¢‘æœ¬åœ°ç¼“å­˜
/// @param url æœåŠ¡ç«¯è§†é¢‘åœ°å€
+ (NSString *)cachedFilePathForURL:(NSURL *)url;
/// èŽ·å–è§†é¢‘é…ç½®æ–‡ä»¶
/// @param url æœåŠ¡ç«¯è§†é¢‘åœ°å€
+ (BUCacheConfiguration *)cacheConfigurationForURL:(NSURL *)url;
/// åˆ é™¤æœ¬åœ°è¶…出缓存大小的缓存文件
/// å½“该文件正在缓存、或正在被播放器占用时不会被删除
/// å†…部使用异步线程删除,线程非阻塞
- (void)clearOverSizeCache;
- (void)cacheResourceUseBegin:(NSURL *)url;
- (void)cacheResourceUseEnd:(NSURL *)url;
- (void)clearSpecifiedResource:(NSURL *)url;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUCommonMacros.h
New file
@@ -0,0 +1,196 @@
//
//  BUCommonMacros.h
//  BUAdSDK
//
//  Created by å´”亚楠 on 2018/10/23.
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <libkern/OSAtomic.h>
#import <os/lock.h>
#import "BULogMacros.h"
FOUNDATION_EXPORT NSString * const BUSDKVersion;
/// æ ‡è®°æ˜¯å¦æ˜¯å¼€å‘状态,正式上线发版时置 0
#define DevEnv 0
/** String **/
#define BUEmptyString                                 (@"");
#define BUSafeString(__string)                        ((__string && [__string isKindOfClass:[NSString class]]) ? __string :@"")
#define BUSafeDictionary(__aDictionary)               ((__aDictionary && [__aDictionary isKindOfClass:[NSDictionary class]]) ? __aDictionary :@{})
/** VALID CHECKING**/
#define BUCheckValidString(__string)                (__string && [__string isKindOfClass:[NSString class]] && [__string length])
#define BUCheckValidNumber(__aNumber)               (__aNumber && [__aNumber isKindOfClass:[NSNumber class]])
#define BUCheckValidArray(__aArray)                 (__aArray && [__aArray isKindOfClass:[NSArray class]] && [__aArray count])
#define BUCheckValidDictionary(__aDictionary)       (__aDictionary && [__aDictionary isKindOfClass:[NSDictionary class]] && [__aDictionary count])
#define BUCheckValidDate(__aDate)                   (__aDate && [__aDate isKindOfClass:[NSDate class]])
/** Color String**/
#define BUColorString(__string)    [UIColor bu_colorWithHexString:(__string)]
/*********************************************************************************************************/
//强弱引用转换,用于解决代码块(block)与强引用对象之间的循环引用问题
#ifndef bu_weakify
#if __has_feature(objc_arc)
#define bu_weakify(object) __weak __typeof__(object) weak##object = object;
#else
#define bu_weakify(object) __block __typeof__(object) block##object = object;
#endif
#endif
#ifndef bu_strongify
#if __has_feature(objc_arc)
#define bu_strongify(object) __typeof__(object) object = weak##object;
#else
#define bu_strongify(object) __typeof__(object) object = block##object;
#endif
#endif
/*********************************************************************************************************/
#ifndef BUisEmptyString
#define BUisEmptyString(str) (!str || ![str isKindOfClass:[NSString class]] || str.length == 0)
#endif
#ifndef BUIsEmptyArray
#define BUIsEmptyArray(array) (!array || ![array isKindOfClass:[NSArray class]] || array.count == 0)
#endif
#ifndef BUIsEmptyDictionary
#define BUIsEmptyDictionary(dict) (!dict || ![dict isKindOfClass:[NSDictionary class]] || ((NSDictionary *)dict).count == 0)
#endif
#ifndef BUMinX
#define BUMinX(view) CGRectGetMinX(view.frame)
#endif
#ifndef BUMinY
#define BUMinY(view) CGRectGetMinY(view.frame)
#endif
#ifndef BUMaxX
#define BUMaxX(view) CGRectGetMaxX(view.frame)
#endif
#ifndef BUMaxY
#define BUMaxY(view) CGRectGetMaxY(view.frame)
#endif
#ifndef BUWidth
#define BUWidth(view) view.frame.size.width
#endif
#ifndef BUHeight
#define BUHeight(view) view.frame.size.height
#endif
#ifndef BUScreenWidth
#define BUScreenWidth [[UIScreen mainScreen] bounds].size.width
#endif
#ifndef BUScreenHeight
#define BUScreenHeight [[UIScreen mainScreen] bounds].size.height
#endif
#ifndef BUMINScreenSide
#define BUMINScreenSide                    MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)
#endif
#ifndef BUMAXScreenSide
#define BUMAXScreenSide                   MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)
#endif
#define BUIsNotchScreen bu_is_notch_screen()
#define BUiPhoneX BUIsNotchScreen
#define kBUDefaultNavigationBarHeight  (BUiPhoneX?88:64)      // å¯¼èˆªæ¡é«˜åº¦
#define kBUSafeTopMargin (BUiPhoneX?24:0)
#define kBUDefaultStautsBarHeight  (BUiPhoneX?44:20)      // çŠ¶æ€æ é«˜åº¦
#define BUOnePixel (1.0f/[[UIScreen mainScreen] scale])
///全局队列
#ifndef BUDispatchGetGlobalQueue
#define BUDispatchGetGlobalQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#endif
#ifndef BUDispatchGetHighQueue
#define BUDispatchGetHighQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
#endif
//单例
#define BU_SINGLETION(...)                                          \
+ (instancetype)sharedInstance NS_SWIFT_NAME(shared());
#define BU_DEF_SINGLETION(...)                                      \
+ (instancetype)sharedInstance                                      \
{                                                                   \
static dispatch_once_t once;                                        \
static id __singletion;                                             \
dispatch_once(&once,^{__singletion = [[self alloc] init];});        \
return __singletion;                                                \
}
FOUNDATION_EXPORT void bu_safe_dispatch_sync_main_queue(void (^block)(void));
FOUNDATION_EXPORT void bu_safe_dispatch_async_main_queue(void (^block)(void));
FOUNDATION_EXPORT id BU_JSONObjectByRemovingKeysWithNullValues(id JSONObject);
FOUNDATION_EXPORT BOOL bu_is_notch_screen(void);
FOUNDATION_EXPORT UIEdgeInsets portraitAdSafeInsets(void);
#pragma mark - é”
#define BU_USE_OS_UNFAIR_LOCK (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0)
#ifndef BU_LOCK_DECLARE
#if BU_USE_OS_UNFAIR_LOCK
#define BU_LOCK_DECLARE(lock) os_unfair_lock lock
#else
#define BU_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \
OSSpinLock lock##_deprecated;
#endif
#endif
#ifndef BU_LOCK_INIT
#if BU_USE_OS_UNFAIR_LOCK
#define BU_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT
#else
#define BU_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \
else lock##_deprecated = OS_SPINLOCK_INIT;
#endif
#endif
#ifndef BU_LOCK
#if BU_USE_OS_UNFAIR_LOCK
#define BU_LOCK(lock) os_unfair_lock_lock(&lock)
#else
#define BU_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \
else OSSpinLockLock(&lock##_deprecated);
#endif
#endif
#ifndef BU_UNLOCK
#if BU_USE_OS_UNFAIR_LOCK
#define BU_UNLOCK(lock) os_unfair_lock_unlock(&lock)
#else
#define BU_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \
else OSSpinLockUnlock(&lock##_deprecated);
#endif
#endif
@protocol BUDictionarify <NSObject>
@required
- (NSDictionary *)toDictionary;
@end
// å¯¹æžšä¸¾å€¼è¿›è¡Œæ—¥å¿—字符串转换, ä¾‹å¦‚对于一个枚举值   1表示激励视频广告的意思, å°†è¿”回:   æ¿€åŠ±è§†é¢‘å¹¿å‘Š(value:1)
FOUNDATION_EXPORT NSString *NSStringLogFromBUAdEnumItem(NSInteger enumItem, NSDictionary *dic, NSString *defaultValue);
// å¯¹æžšä¸¾å€¼è¿›è¡Œå­—符串转换   ä¾‹å¦‚对于一个枚举值   1表示rewarded_ad的字符串, å°†è¿”回:  rewarded_ad
FOUNDATION_EXPORT NSString *NSStringFromBUAdEnumItem(NSInteger enumItem, NSDictionary *dic, NSString *defaultValue);
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUConditionTracker.h
New file
@@ -0,0 +1,33 @@
//
//  BUConditionTracker.h
//  BUFoundation
//
//  Created by Willie on 2021/4/20.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef BOOL (^BUConditionBlock)(void);
typedef void (^BUActionBlock)(void);
/// æ¡ä»¶è½®è¯¢å™¨ï¼šæ¯ç§’轮询指定的条件,若条件满足则执行指定的行为
@interface BUConditionTracker : NSObject
/// é€šè¿‡æŒ‡å®šçš„æ¡ä»¶ block å’Œè¡Œä¸º block æ¥æž„建一个
/// @param condition æ¯ç§’轮询的条件,需要返回一个 BOOL å€¼
/// @param action å½“轮询条件满足时,需要执行的行为
/// @param retryCount è½®è¯¢æ¬¡æ•°ï¼Œå½“实际轮询次数超过指定次数后轮询自动停止,并释放条件和行为 block
- (instancetype)initWithConditon:(BUConditionBlock)condition
                          action:(BUActionBlock)action
                      retryCount:(NSInteger)retryCount;
/// å¼€å§‹è½®è¯¢
- (void)start;
/// åœæ­¢è½®è¯¢å¹¶é‡Šæ”¾èµ„源
- (void)stop;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUDynamicPlugin.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUEnvironment.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUFoundation.h
New file
@@ -0,0 +1,134 @@
//
//  BUFoundation.h
//  BUFoundation
//
//  Created by Siwant on 2019/8/26.
//  Copyright Â© 2019 Union. All rights reserved.
//
/// Public-Utils
#import <BUFoundation/BUCommonMacros.h>
#import <BUFoundation/BUEnvironment.h>
#import <BUFoundation/BUReachability.h>
#import <BUFoundation/BURouter.h>
#import <BUFoundation/BUScreenHelper.h>
#import <BUFoundation/BUThreadSafeDictionary.h>
#import <BUFoundation/BUThreadSafeMutableArray.h>
#import <BUFoundation/BUFoundationAddress.h>
#import <BUFoundation/BUUserAgentHelper.h>
#import <BUFoundation/BUBase64.h>
#import <BUFoundation/BUTimer.h>
#import <BUFoundation/BUConditionTracker.h>
/// Public-Category
#import <BUFoundation/UIViewController+BUUtilities.h>
#import <BUFoundation/NSArray+BUUtilities.h>
#import <BUFoundation/NSString+BUAddtion.h>
#import <BUFoundation/NSTimer+BUBlockSupport.h>
#import <BUFoundation/UIView+BUAdditions.h>
#import <BUFoundation/NSDictionary+BUUtilities.h>
#import <BUFoundation/NSPointerArray+BUSafely.h>
#import <BUFoundation/UIColor+BUTheme.h>
#import <BUFoundation/NSObject+BUSafeKVO.h>
#import <BUFoundation/NSUserDefaults+BUCrypt.h>
#import <BUFoundation/NSJSONSerialization+BUSafeSerializaiton.h>
#import <BUFoundation/NSObject+BUUtils.h>
#import <BUFoundation/NSKeyedArchiver+BUKeyedArchiver.h>
#import <BUFoundation/UIWindow+BUUtilities.h>
/// Public-Gif
#import <BUFoundation/BUGifImage.h>
#import <BUFoundation/BUGifImageView.h>
/// Service-BUPersistent
#import <BUFoundation/BUPersistence.h>
/// Service-JSBridge
#import <BUFoundation/BUDynamicPlugin.h>
#import <BUFoundation/BUStaticPlugin.h>
#import <BUFoundation/BUJSBForwarding.h>
#import <BUFoundation/BUJSBCommand.h>
#import <BUFoundation/BUJSBAuthorization.h>
#import <BUFoundation/BUJSBDefine.h>
#import <BUFoundation/BURexxarEngine.h>
#import <BUFoundation/BUWKWebView.h>
#import <BUFoundation/BUWebViewDefine.h>
#import <BUFoundation/BUJSInjector.h>
#import <BUFoundation/BUWebViewProgressView.h>
/// Service-Log
#import <BUFoundation/BULogMacros.h>
#import <BUFoundation/BULogManager.h>
/// a-n-u
#import <BUFoundation/BUImageUtility.h>
#import <BUFoundation/BUUIResponderHelper.h>
#import <BUFoundation/BUNetworkRequest.h>
#import <BUFoundation/BUTNCServiceManager.h>
#import <BUFoundation/BUBaseRequest.h>
/************************************ ThirdParty***********************************/
//  AFN
#import <BUFoundation/BU_AFURLSessionManager.h>
#import <BUFoundation/BU_AFURLResponseSerialization.h>
#import <BUFoundation/BU_AFURLRequestSerialization.h>
#import <BUFoundation/BU_AFSecurityPolicy.h>
#import <BUFoundation/BU_AFAutoPurgingImageCache.h>
#import <BUFoundation/BU_AFHTTPSessionManager.h>
//  SD
#import <BUFoundation/BU_SDWebImageManager.h>
#import <BUFoundation/UIImageView+BUWebCache.h>
#import <BUFoundation/BU_SDImageCache.h>
#import <BUFoundation/UIImageView+BUHighlightedWebCache.h>
#import <BUFoundation/UIColor+BUHexString.h>
#import <BUFoundation/BU_SDWebImageDownloaderOperation.h>
#import <BUFoundation/BU_SDImageFrame.h>
#import <BUFoundation/UIImage+BUMultiFormat.h>
#import <BUFoundation/BU_SDImageGIFCoder.h>
#import <BUFoundation/NSImage+BUCompatibility.h>
#import <BUFoundation/UIImage+BUForceDecode.h>
#import <BUFoundation/BU_SDAnimatedImageView+BUWebCache.h>
#import <BUFoundation/BU_SDImageGraphics.h>
#import <BUFoundation/UIView+BUWebCacheOperation.h>
#import <BUFoundation/BU_SDAnimatedImageRep.h>
#import <BUFoundation/BU_SDImageAPNGCoder.h>
#import <BUFoundation/UIImage+BUGIF.h>
#import <BUFoundation/UIView+BUWebCache.h>
#import <BUFoundation/BU_SDImageAPNGCoderInternal.h>
#import <BUFoundation/BU_SDWebImageTransition.h>
#import <BUFoundation/BU_SDImageCachesManager.h>
#import <BUFoundation/UIImage+BUMemoryCacheCost.h>
#import <BUFoundation/BU_SDImageGIFCoderInternal.h>
#import <BUFoundation/BU_SDInternalMacros.h>
#import <BUFoundation/BU_SDImageLoadersManager.h>
#import <BUFoundation/BU_SDImageCachesManagerOperation.h>
#import <BUFoundation/BU_SDImageCoderHelper.h>
#import <BUFoundation/NSButton+BUWebCache.h>
#import <BUFoundation/BU_SDWebImagePrefetcher.h>
#import <BUFoundation/BU_SDmetamacros.h>
#import <BUFoundation/BU_SDImageCodersManager.h>
#import <BUFoundation/UIImage+BUMetadata.h>
#import <BUFoundation/NSBezierPath+BURoundedCorners.h>
#import <BUFoundation/BU_SDWeakProxy.h>
#import <BUFoundation/BU_SDImageIOCoder.h>
#import <BUFoundation/BU_SDWebImageError.h>
#import <BUFoundation/UIButton+BUWebCache.h>
#import <BUFoundation/BU_SDImageAssetManager.h>
#import <BUFoundation/BU_SDAsyncBlockOperation.h>
#import <BUFoundation/BUZipArchive.h>
#import <BUFoundation/BUGeckoPreloadManager.h>
#import <BUFoundation/BU_ZFPlayer.h>
/************************************ ThirdParty***********************************/
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUFoundationAddress.h
New file
@@ -0,0 +1,21 @@
//
//  BUFoundationAddress.h
//  BUFoundation
//
//  Created by Siwant on 2020/2/5.
//  Copyright Â© 2020 Union. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface BUFoundationAddress : NSObject
+ (int64_t)bu_beginAddress;
+ (int64_t)bu_endAddress;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUGeckoPreloadManager.h
New file
@@ -0,0 +1,47 @@
//
//  BUGeckoPreloadManager.h
//  BUAdSDK
//
//  Created by wangyanlin on 2020/6/29.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^BUPreloadCompletion)(NSData * _Nullable data,NSDictionary * _Nullable respHeader);
typedef void (^BUPreloadTrackBlock)(NSObject *model,NSString *label,NSDictionary *parameter);
@interface BUGeckoPreloadManager : NSObject
@property (nonatomic, strong) NSMapTable *mapTable;
@property (nonatomic, strong) NSMutableDictionary *geckoDict;
@property (nonatomic, copy) BUPreloadTrackBlock trackBlock;
+ (instancetype)sharedInstance;
+ (void)setupSDKWithTerritory:(NSString *)territory
                     IESGeckoKitAppId:(NSString *)IESGeckoKitAppId
          IESGeckoKit_CACHE_DIRECTORY:(NSString *)IESGeckoKit_CACHE_DIRECTORY
                 IESGeckoKitAccessKey:(NSString *)IESGeckoKitAccessKey
                  IESGeckoKit_Domains:(NSArray *)IESGeckoKit_Domains
                             ZipBlock:(id)zipBlock;
//1.本地zip åŒ…已经被删除了,自动去下载
//2.如果zip需要更新,会自动更新
//3.本地有zip, å¹¶ä¸”不需要更新. ä¸åšå¤„理
+ (void)syncResourcesParamsWithChannel:(NSArray <id>*)materialArray hosts:(NSArray *)hosts;
+ (void)asyncGetDataWithInfo:(NSDictionary *)info completion:(BUPreloadCompletion)completion;
/**
* @brief è¿”回文件版本;如果文件未激活,则返回0
*/
+ (uint64_t)packageVersionForAccessKey:(NSString *)accessKey channel:(NSString *)channel;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUGifImage.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUGifImageView.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUImageUtility.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBAuthorization.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBCommand.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBDefine.h
New file
@@ -0,0 +1,76 @@
//
//  BUJSBDefine.h
//  BURexxar
//
//  Created by muhuai on 2017/5/5.
//  Copyright Â© 2017å¹´ muhuai. All rights reserved.
//
#import <Foundation/Foundation.h>
//#import "BURexxarEngine.h"
#define BU_EXPORT_HANDLER(NAME) - (void)NAME##WithParam:(NSDictionary *)param callback:(BUJSBResponse)callback webView:(UIView<BURexxarEngine> *)webview controller:(UIViewController *)controller;
#define _BU_HANDLER_SET(NAME, HANDLERS) \
- (NSSet<NSString *> *)NAME { \
if (![HANDLERS isKindOfClass:[NSArray class]]) {\
return nil;\
}\
return [NSSet setWithArray:HANDLERS];\
}
#define ARRAY(...) [NSArray arrayWithObjects: (id []){ __VA_ARGS__ } count: sizeof((id []){ __VA_ARGS__ }) / sizeof(id)]
#define BU_PROTECTED_HANDLER(...) \
_BU_HANDLER_SET(protectedHandlerSet, ARRAY(__VA_ARGS__))
#define BU_PRIVATE_HANDLER(...) \
_BU_HANDLER_SET(privateHandlerSet, ARRAY(__VA_ARGS__))
#define BU_CALLBACK_SUCCESS \
if (callback) {\
callback(BUJSBMsgSuccess, @{@"code": @"1"});\
}\
#define BU_CALLBACK_FAILED \
if (callback) {\
callback(BUJSBMsgFailed, @{@"code": @"0"});\
}\
#define BU_CALLBACK_FAILED_MSG(msg) \
if (callback) {\
callback(BUJSBMsgFailed, @{@"code": @"0", @"msg": [NSString stringWithFormat:msg]? :@""});\
}\
#define BU_CALLBACK_WITH_MSG(status, msg) \
if (callback) {\
callback(status, @{@"code": status == BUJSBMsgSuccess? @"1": @"0", @"msg": [NSString stringWithFormat:msg]? [NSString stringWithFormat:msg] :@""});\
}\
typedef NS_ENUM(NSUInteger, BUJSBInstanceType) {
    BUJSBInstanceTypeNormal, //每次调用都是不同实例(默认, æŽ¨è)
    BUJSBInstanceTypeGlobal, //全局单例, éœ€è¦å®žçް +(instance)sharedPlugin;
    BUJSBInstanceTypeWebView, //对同一个webview复用一个实例
};
typedef NS_ENUM(NSUInteger, BUJSBAuthType){
    BUJSBAuthPublic, // æ‰€æœ‰å‡å¯è°ƒç”¨(默认)
    BUJSBAuthProtected, //内部domain,及外部授权可调用
    BUJSBAuthPrivate // ä»…内部domain,appinfo不可见
};
typedef enum : NSUInteger {
    BUJSBMsgSuccess,
    BUJSBMsgFailed,
    BUJSBMsgParamError,
    BUJSBMsgNoHandler,
    BUJSBMsgNoPermission
} BUJSBMsg;
typedef NS_ENUM(NSInteger, BUJSBResultCode){
    BUJSBResultCodeError = -2,      // jsb结果错误cod回传
    BUJSBResultCodeSuccess = 200,   // jsb结果成功cod回传
};
typedef void(^BUJSBResponse)(BUJSBMsg, NSDictionary *);
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSBForwarding.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUJSInjector.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BULogMacros.h
New file
@@ -0,0 +1,36 @@
//
//  BULogMacros.h
//  BUFoundation
//
//  Created by Rush.D.Xzj on 2021/2/2.
//
#import <Foundation/Foundation.h>
#import "BULogManager.h"
/** LOG **/
#define BU_Log_Foundation(frmt, ...) BU_LOG_MAYBE(BUFoundationLog, BU_LOG_ENABLED, frmt, ##__VA_ARGS__)
#define BU_LOG_MAYBE(BULogTypeString, flg, frmt, ...)                       \
do {                                                      \
if(flg) [BULogManager debugLogWithFormat:@"[PangleUnion-%@]-[debug]-[%@]%@", BUSDKVersion, BULogTypeString, [NSString stringWithFormat:frmt,##__VA_ARGS__]];                       \
} while(0)
#define BU_LogErrorD(BULogType, frmt, ...) BU_LogBaseD(error, BULogType, frmt, ##__VA_ARGS__)
#define BU_LogWaringD(BULogType, frmt, ...) BU_LogBaseD(warning, BULogType, frmt, ##__VA_ARGS__)
#define BU_LogInfoD(BULogType, frmt, ...) BU_LogBaseD(info, BULogType, frmt, ##__VA_ARGS__)
#define BU_LogDebugD(BULogType, frmt, ...) BU_LogBaseD(debug, BULogType, frmt, ##__VA_ARGS__)
#define BU_LogVerboseD(BULogType, frmt, ...) BU_LogBaseD(verbose, BULogType, frmt, ##__VA_ARGS__)
#define BU_LogInternalD(BULogType, frmt, ...) BU_LogBaseD(internal, BULogType, frmt, ##__VA_ARGS__)
#define BU_LogBaseD(level, BULogType, frmt, ...) [BULogManager level##LogWithFormat:@"[PangleUnion-%@]-[%s]-[%@]%@", BUSDKVersion, #level, BULogType, [NSString stringWithFormat:frmt, ##__VA_ARGS__]];
FOUNDATION_EXPORT NSString * const BUFoundationLog;
FOUNDATION_EXPORT BOOL BU_LOG_ENABLED;
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BULogManager.h
New file
@@ -0,0 +1,37 @@
//
//  BULogManager.h
//  BUAdSDK
//
//  Created by bytedance on 2020/6/9.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
// è¿™é‡Œè·Ÿ BUAdSDKLogLevel å¯¹é½
typedef NS_ENUM(NSInteger, BULogManagerLevel) {
    BULogManagerLevelNone,
    BULogManagerLevelError,
    BULogManagerLevelWarning,
    BULogManagerLevelInfo,
    BULogManagerLevelDebug,
    BULogManagerLevelVerbose,
};
NS_ASSUME_NONNULL_BEGIN
@interface BULogManager : NSObject
@property (nonatomic, assign) BULogManagerLevel level;
+ (void)errorLogWithFormat:(NSString *)format, ...;
+ (void)warningLogWithFormat:(NSString *)format, ...;
+ (void)infoLogWithFormat:(NSString *)format, ...;
+ (void)debugLogWithFormat:(NSString *)format, ...;
+ (void)verboseLogWithFormat:(NSString *)format, ...;
+ (void)internalLogWithFormat:(NSString *)format, ...;
+ (instancetype)sharedInstance;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUNetworkRequest.h
New file
@@ -0,0 +1,52 @@
//
//  BUAdNetworkRequest.h
//  BUFoundation
//
//  Created by bytedance on 2020/12/15.
//
#import "BUBaseRequest.h"
#import "BUTNCServiceManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface BUNetworkRequest : BUBaseRequest
@property (nonatomic,copy  ) NSString *buRequestUrl;
@property (nonatomic,strong) NSDictionary *parameter;
@property (nonatomic,assign) BURequestMethod method;
@property (nonatomic,assign) BURequestSerializerType buRequestSerializerType;
@property (nonatomic,assign) BUResponseSerializerType buResponseSerializerType;
- (instancetype)initWithUrl:(NSString * _Nullable)url
                     method:(BURequestMethod)method
                  parameter:(NSDictionary * _Nullable)parameter;
+ (instancetype)requestWithURL:(NSString *)url
                        method:(BURequestMethod)method
                     parameter:(NSDictionary *)paraDic
         completionWithSuccess:(BURequestCompletionBlock  _Nullable)success
                       failure:(BURequestCompletionBlock _Nullable)failure;
+ (instancetype)requestWithURL:(NSString *)url
                     parameter:(NSDictionary *)paraDic
         completionWithSuccess:(BURequestCompletionBlock _Nullable)success
                       failure:(BURequestCompletionBlock _Nullable)failure;
@end
@interface BUNetworkRequest (TNC)
// ä½¿ç”¨TNC服务的标识,自定义,唯一即可
- (NSString *)TNCServiceKey;
// è¯·æ±‚失败回调,如果需要TNC,请使用`failureCompletionBlockWithTNC`替换`failureCompletionBlock`的实现
- (BURequestCompletionBlock)failureCompletionBlockWithTNC;
// è¯·æ±‚成功回调,如果需要TNC,请使用`successCompletionBlockWithTNC`替换`successCompletionBlock`的实现
- (BURequestCompletionBlock)successCompletionBlockWithTNC;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPersistence.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayer.h
New file
@@ -0,0 +1,155 @@
//
//  BUPlayer.h
//  BUAdSDK
//
//  Created by hlw on 2017/12/21.
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "BUPlayerDefine.h"
#import "BUPlayerInternalDefine.h"
#import "BUPlayerSettingsProtocol.h"
@class BUPlayerItem;
@interface BUPlayer : NSObject<BUPlayerSettingsProtocol>
@property (nonatomic, weak) id<BUVideoPlayerDelegate> delegate;
/**
 * æ’­æ”¾å†…容视图
 */
@property (nonatomic, strong, readonly) UIView *view;
/**
 * æ’­æ”¾å™¨çŠ¶æ€
 * æ”¯æŒKVO
 */
@property (nonatomic, assign, readonly) BUVideoPlayerState state;
/// æ’­æ”¾å™¨æ’­æ”¾æ¨¡å¼æ”¹å˜
@property (nonatomic, assign, readonly) BUVideoPlayerDecoeMode decodeMode;
/**
 * æ’­æ”¾èµ„源总时长
 */
@property (nonatomic, assign, readonly) NSTimeInterval duration;
/**
 * å½“前可播放时长
 */
@property (nonatomic, assign, readonly) NSTimeInterval playableDuration;
/**
 * å®žé™…观看时长
 */
@property (nonatomic, assign, readonly) NSTimeInterval watchedDuration;
/**
 * å½“前播放时间
 */
@property (nonatomic, assign, readonly) CGFloat currentPlayTime;
/// å½“前播放链接
@property (nonatomic, strong, readonly) NSURL *currentPlayURL;
/**
 * å½“前播放资源Item
 */
@property (nonatomic, strong, readonly) BUPlayerItem *currentPlayerItem;
/**
 * æ’­æ”¾å™¨æŽ§åˆ¶å±‚容器,默认视图支持部分定制或完全自定义
 * é»˜è®¤æ˜¾ç¤ºæŽ§åˆ¶å±‚全部元素,可以定制部分视图元素显示/隐藏
 * è‹¥å®Œå…¨è‡ªå®šä¹‰,需先隐藏全部默认视图元素 å†åœ¨å®¹å™¨ä¸Šæ·»åŠ è‡ªå®šä¹‰è§†å›¾
 */
@property (nonatomic, strong, readonly) UIView<BUPlayerControlViewProtocol> *controlContainer;
/**
 * æ’­æ”¾å†…容视图填充方式
 * é»˜è®¤ï¼šç­‰æ¯”例填充,直到一个维度到达区域边界
 */
@property (nonatomic, assign) BUPlayerLayerGravity playerLayerGravity;
/**
 * æ’­æ”¾è§†å›¾ä¸Šæ‰‹åŠ¿æ“ä½œé€‰é¡¹å¼€å…³
 * é»˜è®¤å…¨å¼€
 */
@property (nonatomic, assign) BUPlayerGestureOption option;
/**
 * é™éŸ³è®¾ç½®
 */
@property (nonatomic, assign) BOOL mute;
/**
 * å½“前是否全屏显示
 */
@property (nonatomic, assign, readonly) BOOL isFullScreen;
/** è®¾ç½®è‡ªå®šä¹‰ControlView */
@property (nonatomic, strong) UIView *controlView;
/**
 * æ”¯æŒè‡ªåŠ¨è½¬å±,默认NO
 */
@property (nonatomic, assign) BOOL shouldAutoRotate;
/**
* jsb changeVideoState æš‚停视频后,视频过一秒会继续开始播放.因为 timer ä¼šè°ƒç”¨ checkToPlayOrPause.
* æ‰€ä»¥ç”¨å±žæ€§è¿›è¡Œæ ‡è®°
* å½±å“èŒƒå›´: æ¨¡æ¿/非模板 çš„æ¿€åŠ±å…¨å±è§†é¢‘
*/
@property (nonatomic, assign) BOOL isJSBPauseVideo;
+ (instancetype)playerWithPlayerItem:(BUPlayerItem *)item;
- (void)replaceCurrentItemWithPlayerItem:(BUPlayerItem *)item;
@end
@interface BUPlayer (BUPlayerControl)
/**
 * æ’­æ”¾
 */
- (void)play;
/**
 * æš‚停
 */
- (void)pause;
/**
 * é‡æ’­
 */
- (void)replay;
/**
 * åœæ­¢
 */
- (void)stop;
/**
 * è·³åˆ°æŒ‡å®šæ—¶é—´æ’­æ”¾
 */
- (void)seekToTime:(NSTimeInterval)time completion:(void(^)(BOOL success))completion;
/**
 * å…¨å±/竖屏 åˆ‡æ¢æ˜¾ç¤º
 */
- (void)changeOrientationScreen;
/**
 * å¤„于后台模式
 */
- (BOOL)isEnterBackground;
@end
@interface BUPlayer (BUTrack)
@property (nonatomic, strong) NSString *startTimestamp;
@property (nonatomic, strong) NSString *endTimestamp;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerDefine.h
New file
@@ -0,0 +1,82 @@
//
//  BUPlayerDefine.h
//  BUAdSDK
//
//  Created by carl on 2017/12/24.
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
 * playerLayer的填充模式
 */
typedef NS_ENUM(NSInteger, BUPlayerLayerGravity) {
    BUPlayerLayerGravityResize,           // éžå‡åŒ€æ¨¡å¼ã€‚两个维度完全填充至整个视图区域
    BUPlayerLayerGravityResizeAspect,     // ç­‰æ¯”例填充,直到一个维度到达区域边界
    BUPlayerLayerGravityResizeAspectFill  // ç­‰æ¯”例填充,直到填充满整个视图区域,其中一个维度的部分区域会被裁剪
};
/**
 * æ‰‹åŠ¿äº¤äº’æ“ä½œ
 */
typedef NS_OPTIONS(NSInteger, BUPlayerGestureOption) {
    BUPlayerGestureOptionNone              = 0,
    BUPlayerGestureOptionVolumeEnabled     = 1 << 0,
    BUPlayerGestureOptionBrightnessEnabled = 1 << 1,
    BUPlayerGestureOptionFastSkipEnabled   = 1 << 2,
    BUPlayerGestureOptionSigleTapEnabled   = 1 << 3,
    BUPlayerGestureOptionDoubleTapEnabled  = 1 << 4,
};
/**
 * é»˜è®¤çš„æŽ§åˆ¶è§†å›¾æˆ–完成视图的元素
 */
typedef NS_OPTIONS(NSInteger, BUPlayerDefaultControlElement) {
    BUPlayerControlElementNone     = 0,
    BUPlayerControlElementTop      = 1 << 0,
    BUPlayerControlElementBottom   = 1 << 1,
    BUPlayerControlElementActivity = 1 << 2,
    BUPlayerControlElementFailHint = 1 << 3,
    BUPlayerControlElementProgress = 1 << 4,
    BUPlayerControlElementPlay     = 1 << 5,
    BUPlayerControlElementReplay   = 1 << 6,
};
typedef NSString * BUPlayerUIControlImage;
typedef NSString * BUPlayerUIControlLocalizedString;
#define BUPlayerUIControlImage_LeftBack       @"bu_leftback"
#define BUPlayerUIControlImage_TopShadow      @"bu_topShadow"
#define BUPlayerUIControlImage_BottomShadow   @"bu_bottomShadow"
#define BUPlayerUIControlImage_BottomPlay     @"bu_bottomPlay"
#define BUPlayerUIControlImage_BottomPause    @"bu_bottomPause"
#define BUPlayerUIControlImage_FullClose      @"bu_fullClose"
#define BUPlayerUIControlImage_SliderDot      @"bu_sliderDot"
#define BUPlayerUIControlImage_FullScreen     @"bu_fullScreen"
#define BUPlayerUIControlImage_ShrinkScreen   @"bu_shrinkScreen"
#define BUPlayerUIControlImage_Replay         @"bu_replay"
#define BUPlayerUIControlImage_Play           @"bu_play"
#define BUPlayerUIControlImage_Pause          @"bu_pause"
#define BUPlayerUIControlImage_FastForward    @"bu_fastForward"
#define BUPlayerUIControlImage_FastBackward   @"bu_fastBackward"
#define BUPlayerUIControlLocalizedString_Close @"bu_LoStr_Close"
@protocol BUPlayerControlViewProtocol <NSObject>
- (instancetype)initWithContrlResourceBundle:(NSBundle *)bundle
                                      images:(NSDictionary <BUPlayerUIControlImage, NSString *> *)images
                            localizedStrings:(NSDictionary <BUPlayerUIControlLocalizedString, NSString *>*)localizedStrings;
/**
 * è®¾ç½®é»˜è®¤æŽ§åˆ¶è§†å›¾æˆ–完成视图的元素组合方式
 * é»˜è®¤æ˜¾ç¤ºå…¨éƒ¨
 */
- (void)setPlayerDefaultControlElement:(BUPlayerDefaultControlElement)element;
/**
 * èŽ·å–æ’­æ”¾å®Œæˆè§†å›¾å®¹å™¨
 * è‹¥éœ€è‡ªå®šä¹‰å¯å…ˆç§»é™¤BUPlayerControlElementReplay,再添加自定义视图
 */
- (UIView *)finishedContainer;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerInternalDefine.h
New file
@@ -0,0 +1,70 @@
//
//  BUPlayerInternalDefine.h
//  BUFoundation
//
//  Created by bytedance on 2020/12/17.
//
#ifndef BUPlayerInternalDefine_h
#define BUPlayerInternalDefine_h
typedef NS_ENUM(NSInteger, BUVideoPlayerState) {
    BUVideoPlayerStateFailed    = 0,
    BUVideoPlayerStateBuffering = 1,
    BUVideoPlayerStatePlaying   = 2,
    BUVideoPlayerStateStopped   = 3,
    BUVideoPlayerStatePause     = 4,
    BUVideoPlayerStateDefault    = 5
};
typedef NS_ENUM(NSUInteger, BUVideoPlayerDecoeMode) {
    BUVideoPlayerDecoeMode_H265_Local = 0,
    BUVideoPlayerDecoeMode_H265_Cache = 1,
    BUVideoPlayerDecoeMode_H265_Remote = 2,
    BUVideoPlayerDecoeMode_H264_Local = 3,
    BUVideoPlayerDecoeMode_H264_Cache = 4,
    BUVideoPlayerDecoeMode_H264_Remote = 5,
    BUVideoPlayerDecoeMode_Last = 5,
};
@class BUPlayer;
@protocol BUVideoPlayerDelegate <NSObject>
@optional
/**
 This method is called when the player status changes.
 */
- (void)player:(BUPlayer *)player stateDidChanged:(BUVideoPlayerState)playerState;
/// æ’­æ”¾å™¨æ’­æ”¾æ¨¡å¼æ”¹å˜ï¼Œå½“播放失败时会逐级降级
/// @param player æ’­æ”¾å™¨æ’­æ”¾æ¨¡å¼æ”¹å˜
/// @param democeMode æ’­æ”¾æ¨¡å¼
- (void)player:(BUPlayer *)player decodeModeChanged:(BUVideoPlayerDecoeMode)democeMode;
/**
 This method is called when the player is ready.
 */
- (void)playerReadyToPlay:(BUPlayer *)player;
/**
 This method is called when the player plays completion or occurrs error.
 */
- (void)playerDidPlayFinish:(BUPlayer *)player error:(NSError *)error;
/**
 This method is called when the player is clicked.
 */
- (void)player:(BUPlayer *)player recognizeTapGesture:(UITapGestureRecognizer *)gesture;
/**
 This method is called when the view is clicked during ad play.
 */
- (void)playerTouchesBegan:(BUPlayer *)player;
@end
#endif /* BUPlayerInternalDefine_h */
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerItem.h
New file
@@ -0,0 +1,53 @@
//
//  BUPlayerItem.h
//  BUAdSDK
//
//  Created by hlw on 2017/12/21.
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface BUPlayerItem : NSObject
/// è§†é¢‘标题
@property (nonatomic, copy) NSString *title;
/// è§†é¢‘URL - H.264 - è¿œç¨‹
@property (nonatomic, strong) NSURL *videoURL_H264_Remote;
/// è§†é¢‘URL - H.264 - æœ¬åœ° å…¼å®¹æ–¹æ¡ˆï¼Œæ¿€åŠ±è§†é¢‘ç”±ä¸Šå±‚æŽ§åˆ¶
@property (nonatomic, strong) NSURL *videoURL_H264_Local;
/// è§†é¢‘URL - HEVC - è¿œç¨‹
@property (nonatomic, strong) NSURL *videoURL_H265_Remote;
/// è§†é¢‘URL - HEVC - æœ¬åœ°
@property (nonatomic, strong) NSURL *videoURL_H265_Local;
/// å…è®¸ä½¿ç”¨ H265 è¿›è¡Œæ’­æ”¾
@property (nonatomic, assign) BOOL enableH265;
/// H265 ä¸‹å…è®¸é™çº§æ’­æ”¾
@property (nonatomic, assign) BOOL enableH265DowngradePlay;
/// H264 ä¸‹å…è®¸é™çº§æ’­æ”¾
@property (nonatomic, assign) BOOL enableH264DowngradePlay;
/// å…è®¸ä½¿ç”¨è¾¹ä¸‹è¾¹æ’­
@property (nonatomic, assign) BOOL enableCache;
/// è§†é¢‘封面网络图片url
@property (nonatomic, copy) NSString *placeholderImageURLString;
///  é»˜è®¤å›¾çš„展示形式
@property (nonatomic, assign) UIViewContentMode placeholderImageContentMode;
/// ä»Žxx秒开始播放视频(默认0)
@property (nonatomic, assign) NSInteger seekTime;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUPlayerSettingsProtocol.h
New file
@@ -0,0 +1,26 @@
//
//  BUPlayerSettingsProtocol.h
//  BUFoundation
//
//  Created by bytedance on 2020/12/17.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol BUPlayerSettingsProtocol <NSObject>
@optional
+ (NSString *)videoCachePath;
+ (NSBundle *)playerResourceBundle;
+ (NSDictionary *)playerControlViewImages;
+ (NSDictionary *)playerControlLocalizedString;
+ (void)audioSessionSetting;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUReachability.h
New file
@@ -0,0 +1,186 @@
/*
 File: BUReachability.h
 Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
 Version: 3.5
 Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
 Inc. ("Apple") in consideration of your agreement to the following
 terms, and your use, installation, modification or redistribution of
 this Apple software constitutes acceptance of these terms.  If you do
 not agree with these terms, please do not use, install, modify or
 redistribute this Apple software.
 In consideration of your agreement to abide by the following terms, and
 subject to these terms, Apple grants you a personal, non-exclusive
 license, under Apple's copyrights in this original Apple software (the
 "Apple Software"), to use, reproduce, modify and redistribute the Apple
 Software, with or without modifications, in source and/or binary forms;
 provided that if you redistribute the Apple Software in its entirety and
 without modifications, you must retain this notice and the following
 text and disclaimers in all such redistributions of the Apple Software.
 Neither the name, trademarks, service marks or logos of Apple Inc. may
 be used to endorse or promote products derived from the Apple Software
 without specific prior written permission from Apple.  Except as
 expressly stated in this notice, no other rights or licenses, express or
 implied, are granted by Apple herein, including but not limited to any
 patent rights that may be infringed by your derivative works or by other
 works in which the Apple Software may be incorporated.
 The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 Copyright (C) 2014 Apple Inc. All Rights Reserved.
 */
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>
typedef NS_ENUM(NSInteger, BUNetWorkTypeCode) {
    // åˆå§‹çŠ¶æ€ï¼Œæœªè¿žæŽ¥
    BUNetWorkTypeCode_None = -1,
    // æœªçŸ¥
    BUNetWorkTypeCode_Unknown = 0,
    BUNetWorkTypeCode_Mobile = 1,
    BUNetWorkTypeCode_2G = 2,
    BUNetWorkTypeCode_3G = 3,
    BUNetWorkTypeCode_Wifi = 4,
    BUNetWorkTypeCode_4G = 5,
    BUNetWorkTypeCode_5G = 6,
};
typedef NS_ENUM(NSInteger) {
    // ç¨‹åºæ— æ³•判断出 App çš„网络权限设置
    kBUNetworkAuthorizationStatusCantDetermined = 0,
    // App æœªå¼€å¯èœ‚窝数据网络权限
    kBUNetworkAuthorizationStatusCellNotPermitted,
    // App æœªå¼€å¯æ— çº¿å±€åŸŸç½‘与蜂窝移动网络权限,此项仅可能在国行 iPhone æ‰‹æœºä¸Šå‡ºçް
    kBUNetworkAuthorizationStatusWLANAndCellNotPermitted,
} kBUNetworkAuthorizationStatus;
extern NSString *kBUReachabilityChangedNotification;
// æ˜¯å¦å¼€å¯ â€œç½‘络状态检测” çš„优化,需要外部调用方以 [[NSUserDefaults standardUserDefaults] setBool:forKey:] æ–¹å¼å†™å…¥
extern NSString * const BUReachabilityDetectOptimizeKey;
@interface BUReachability : NSObject
/**
 åˆ¤æ–­æŒ‡å®šåŸŸåçš„连通性
 @param hostName åŸŸå
 @return BUReachability对象
 */
+ (instancetype)reachabilityWithHostName:(NSString *)hostName;
/**
 åˆ¤æ–­æŒ‡å®šIP地址的连通性
 @param hostAddress IP地址
 @return BUReachability对象
 */
+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;
/**
 åˆ¤æ–­ç½‘络默认连接的连通性(应用连接到指定host主机时除外)
 @return BUReachability对象
 */
+ (instancetype)reachabilityForInternetConnection;
/**
 å¼€å§‹åœ¨å½“前runloop监听连通性通知
 @return æ˜¯å¦æˆåŠŸå¼€å§‹ç›‘å¬
 */
- (BOOL)startNotifier;
/**
 ç»“束监听连通性通知
 */
- (void)stopNotifier;
/**
 å½“前连通性状态
 @return NetworkStatus枚举值
 */
- (BUNetWorkTypeCode)currentReachabilityStatus;
/**
 æ˜¯å¦éœ€è¦è¿žæŽ¥ã€‚如WWAN需要首先建立一个可用连接才能被激活。WiFi可能需要一个VPN连接等
 @return æ˜¯å¦éœ€è¦è¿žæŽ¥
 */
- (BOOL)connectionRequired;
/**
 èŽ·å– App å½“前的网络权限设置状态
 å› è‹¹æžœå°šæœªæä¾›ç½‘络权限判断的 API,此方法目前只是在网络 NotReachable æ—¶æ£€æŸ¥ç³»ç»Ÿè¿žæŽ¥çŠ¶æ€ï¼Œ
 åˆ©ç”¨æŽ’除法推断出 App å½“前没有 èœ‚窝数据网络权限 æˆ–者 WIFI及蜂窝数据网络权限,排除原理参见
 https://wiki.bytedance.net/pages/viewpage.action?pageId=107808003
 åœ¨å…¶å®ƒæƒ…况下(例如网络 Reachable æˆ–者飞行模式)均返回 CantDetermined,上层业务调用方需注意
 @return å‚见 kBUNetworkAuthorizationStatus å®šä¹‰
 */
- (kBUNetworkAuthorizationStatus)currentNetworkAuthorizationStatus;
@end
@interface BUReachability (Cellular)
/**
 2G网络是否连通
 @return æ˜¯å¦è¿žé€š
 */
+ (BOOL)is2GConnected;
/**
 3G网络是否连通
 @return æ˜¯å¦è¿žé€š
 */
+ (BOOL)is3GConnected;
/**
 4G网络是否连通
 @return æ˜¯å¦è¿žé€š
 */
+ (BOOL)is4GConnected;
/**
 2017.5.22添加
 å€Ÿé‰´å¾®ä¿¡æ–¹å¼åˆ¤æ–­å½“前网络是否连通
 @return ç½‘络是否可以联调
 */
+ (BOOL)isNetworkConnected;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BURexxarEngine.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BURouter.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUScreenHelper.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUStaticPlugin.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUTNCRequestParam.h
New file
@@ -0,0 +1,16 @@
//
// Created by bytedance on 2020/12/16.
//
#import <Foundation/Foundation.h>
#import "BUCommonMacros.h"
@interface BUTNCRequestParam : NSObject <BUDictionarify>
@property (nonatomic, copy) NSString *version;
@property (nonatomic, copy) NSString *deviceDid;
@property (nonatomic, copy) NSString *ssAppID;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUTNCServiceManager.h
New file
@@ -0,0 +1,31 @@
//
// Created by bytedance on 2020/12/15.
//
#import <Foundation/Foundation.h>
#import "BUTNCRequestParam.h"
@class BUNetworkRequest;
@interface BUTNCServiceConfig : NSObject
@property (nonatomic, copy, readonly) NSString *appKey;
@property(nonatomic, copy, readonly) NSString *tncPath;
@property(nonatomic, copy, readonly) NSArray<NSString *> *tncDomains;
@property(nonatomic, copy, readonly) BUTNCRequestParam *(^tncRequestParam)(void);
@end
__attribute__((objc_subclassing_restricted))
@interface BUTNCServiceManager : NSObject
+ (void)registerTNCServiceWithAppKey:(NSString *)appKey tncDomains:(NSArray<NSString *> *)tncDomains tncPath:(NSString *)tncPath requestParam:(BUTNCRequestParam * (^)(void))param;
+ (void)unregisterTNCServiceWithAppKey:(NSString *)appKey;
+ (NSString *)TNCUrlWithBaseUrl:(NSString *)baseUrl forRequest:(BUNetworkRequest *)request;
+ (void)refreshTNCDomainsWithAppKey:(NSString *)appKey;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUThreadSafeDictionary.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUThreadSafeMutableArray.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUTimer.h
New file
@@ -0,0 +1,32 @@
//
//  BUTimer.h
//  BUAdSDK
//
//  Created by æŽç›› on 2018/6/20.
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface BUTimer : NSObject
@property (nonatomic, copy) NSString *runLoopMode;
+ (BUTimer *)timerWithTimeInterval:(NSTimeInterval)seconds
                            target:(id)target
                          selector:(SEL)aSelector
                           repeats:(BOOL)repeats;
- (BOOL)isValid;
- (void)invalidate;
- (BOOL)isScheduled;
- (BOOL)scheduleNow;
- (BOOL)pause;
- (BOOL)resume;
- (NSTimeInterval)initialTimeInterval;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUUIResponderHelper.h
New file
@@ -0,0 +1,38 @@
//
//  BUUIResponderHelper.h
//  BUSDKProject
//
//  Created by ranny_90 on 2017/5/20.
//  Copyright Â© 2017å¹´ ranny_90. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface BUUIResponderHelper : NSObject
// èŽ·å–å½“å‰åº”ç”¨çš„å¹¿ä¹‰mainWindow
+ (nullable UIWindow *)mainWindow __attribute__((deprecated("Use bu_mainWindow in UIWindow+BUUtilities instead.")));
// å¹¿ä¹‰mainWindow的大小(兼容iOS7)
+ (CGSize)windowSize __attribute__((deprecated("Use bu_windowSize in UIWindow+BUUtilities instead.")));
// èŽ·å–å¹¿ä¹‰mainWindow的rootViewController
+ (nullable UIViewController*)mainWindowRootViewController __attribute__((deprecated("Use bu_mainWindowRootViewController in UIViewController+BUUtilities instead.")));
// èŽ·å–æŒ‡å®šUIResponder的链下游第一个ViewController对象
+ (nullable UIViewController*)nextViewControllerFor:(UIResponder* _Nullable)responder __attribute__((deprecated("Use bu_nextViewControllerFor: in UIViewController+BUUtilities instead.")));
// èŽ·å–æŒ‡å®šUIResponder的链下游第一个UINavigationController对象
+ (nullable UINavigationController*)nextNavigationControllerFor:(UIResponder* _Nullable)responder __attribute__((deprecated("Use bu_nextNavigationControllerFor: in UIViewController+BUUtilities instead.")));
/** æŸ¥æ‰¾å½“前显示的ViewController*/
+ (UIViewController *)topViewController __attribute__((deprecated("Use bu_topViewController in UIViewController+BUUtilities instead.")));
+ (UIViewController *)recursiveFindCurrentShowViewControllerFromViewController:(UIViewController *)fromVC __attribute__((deprecated("Use bu_recursiveFindCurrentShowViewControllerFromViewController: in UIViewController+BUUtilities instead.")));
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUUserAgentHelper.h
New file
@@ -0,0 +1,18 @@
//
//  BUUserAgentHelper.h
//  BUAdSDK
//
//  Created by cuiyanan on 2019/9/3.
//  Copyright Â© 2019 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
#import "BUCommonMacros.h"
@interface BUUserAgentHelper : NSObject
BU_SINGLETION(BUUserAgentHelper);
- (NSString *)userAgent;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUVideoPrefetchManager.h
New file
@@ -0,0 +1,44 @@
//
//  BUVideoPrefetchManager.h
//  BUAdSDK
//
//  Created by æŽç›› on 2018/9/20.
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BUPlayerSettingsProtocol.h"
typedef void (^prefetchVideoCancelBlock)(NSInteger preloadSize);
@interface BUVideoPrefetchManager : NSObject<BUPlayerSettingsProtocol>
+ (instancetype)sharedInstance;
/// é¢„加载视频
/// @param videoUrl è§†é¢‘ URL
/// @param storgeName è§†é¢‘文件存储名称
/// @param prefetchSize é¢„加载大小
/// @param prefetchStartBlock é¢„加载开始回调
/// @param prefetchFinshBlock é¢„加载结束回调
- (void)prefetchWithVideoUrl:(NSURL *)videoUrl
                  storgeName:(NSString *)storgeName
               prefetchSize:(NSUInteger)prefetchSize
          prefetchStartBlock:(void(^)(void))prefetchStartBlock
          prefetchFinshBlock:(void(^)(BOOL, NSInteger, NSError *, NSString *))prefetchFinshBlock
         prefetchCancelBlock:(prefetchVideoCancelBlock)prefetchCancelBlock;
/// åˆ¤æ–­url是否正在下载
/// @param videoURL è§†é¢‘ URL
- (BOOL)prefetchUrlInQueue:(NSURL *)videoURL;
/// å–消预加载,播放时应先取消预加载。
/// @param videoURL è§†é¢‘ URL
- (void)cancelPrefetch:(NSURL *)videoURL;
/// æŸ¥è¯¢è§†é¢‘预加载大小
/// @param videoUrl è§†é¢‘ URL
- (NSInteger)queryPrefetchSizeWithVideoUrl:(NSURL *)videoUrl;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUWKWebView.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUWebViewDefine.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUWebViewProgressView.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUZipArchive.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BUZipCommon.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFAutoPurgingImageCache.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFHTTPSessionManager.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFSecurityPolicy.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFURLRequestSerialization.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFURLResponseSerialization.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_AFURLSessionManager.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImage.h
New file
@@ -0,0 +1,107 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import "BU_SDImageCoder.h"
/**
 This is the protocol for BU_SDAnimatedImage class only but not for <BU_SDAnimatedImageCoder>. If you want to provide a custom animated image class with full advanced function, you can conform to this instead of the base protocol.
 */
@protocol BU_SDAnimatedImage <BU_SDAnimatedImageProvider>
@required
/**
 Initializes and returns the image object with the specified data, scale factor and possible animation decoding options.
 @note We use this to create animated image instance for normal animation decoding.
 @param data The data object containing the image data.
 @param scale The scale factor to assume when interpreting the image data. Applying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the `size` property.
 @param options A dictionary containing any animation decoding options.
 @return An initialized object
 */
- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale options:(nullable SDImageCoderOptions *)options;
/**
 Initializes the image with an animated coder. You can use the coder to decode the image frame later.
 @note We use this with animated coder which conforms to `SDProgressiveImageCoder` for progressive animation decoding.
 @param animatedCoder An animated coder which conform `<BU_SDAnimatedImageCoder>` protocol
 @param scale The scale factor to assume when interpreting the image data. Applying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the `size` property.
 @return An initialized object
 */
- (nullable instancetype)initWithAnimatedCoder:(nonnull id<BU_SDAnimatedImageCoder>)animatedCoder scale:(CGFloat)scale;
@optional
// These methods are used for optional advanced feature, like image frame preloading.
/**
 Pre-load all animated image frame into memory. Then later frame image request can directly return the frame for index without decoding.
 This method may be called on background thread.
 @note If one image instance is shared by lots of imageViews, the CPU performance for large animated image will drop down because the request frame index will be random (not in order) and the decoder should take extra effort to keep it re-entrant. You can use this to reduce CPU usage if need. Attention this will consume more memory usage.
 */
- (void)preloadAllFrames;
/**
 Unload all animated image frame from memory if are already pre-loaded. Then later frame image request need decoding. You can use this to free up the memory usage if need.
 */
- (void)unloadAllFrames;
/**
 Returns a Boolean value indicating whether all animated image frames are already pre-loaded into memory.
 */
@property (nonatomic, assign, readonly, getter=isAllFramesLoaded) BOOL allFramesLoaded;
@end
/**
 The image class which supports animating on `SDAnimatedImageView`. You can also use it on normal UIImageView/NSImageView.
 */
@interface BU_SDAnimatedImage : UIImage <BU_SDAnimatedImage>
// This class override these methods from UIImage(NSImage), and it supports NSSecureCoding.
// You should use these methods to create a new animated image. Use other methods just call super instead.
+ (nullable instancetype)imageNamed:(nonnull NSString *)name; // Cache in memory, no Asset Catalog support
#if __has_include(<UIKit/UITraitCollection.h>)
+ (nullable instancetype)imageNamed:(nonnull NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection; // Cache in memory, no Asset Catalog support
#else
+ (nullable instancetype)imageNamed:(nonnull NSString *)name inBundle:(nullable NSBundle *)bundle; // Cache in memory, no Asset Catalog support
#endif
+ (nullable instancetype)imageWithContentsOfFile:(nonnull NSString *)path;
+ (nullable instancetype)imageWithData:(nonnull NSData *)data;
+ (nullable instancetype)imageWithData:(nonnull NSData *)data scale:(CGFloat)scale;
- (nullable instancetype)initWithContentsOfFile:(nonnull NSString *)path;
- (nullable instancetype)initWithData:(nonnull NSData *)data;
- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale;
/**
 Current animated image format.
 */
@property (nonatomic, assign, readonly) BU_SDImageFormat animatedImageFormat;
/**
 Current animated image data, you can use this to grab the compressed format data and create another animated image instance.
 If this image instance is an animated image created by using animated image coder (which means using the API listed above or using `initWithAnimatedCoder:scale:`), this property is non-nil.
 */
@property (nonatomic, copy, readonly, nullable) NSData *animatedImageData;
/**
 The scale factor of the image.
 @note For UIKit, this just call super instead.
 @note For AppKit, `NSImage` can contains multiple image representations with different scales. However, this class does not do that from the design. We processs the scale like UIKit. This wil actually be calculated from image size and pixel size.
 */
@property (nonatomic, readonly) CGFloat scale;
// By default, animated image frames are returned by decoding just in time without keeping into memory. But you can choose to preload them into memory as well, See the decsription in `BU_SDAnimatedImage` protocol.
// After preloaded, there is no huge difference on performance between this and UIImage's `animatedImageWithImages:duration:`. But UIImage's animation have some issues such like blanking and pausing during segue when using in `UIImageView`. It's recommend to use only if need.
- (void)preloadAllFrames;
- (void)unloadAllFrames;
@property (nonatomic, assign, readonly, getter=isAllFramesLoaded) BOOL allFramesLoaded;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImageRep.h
New file
@@ -0,0 +1,22 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_MAC
/**
 A subclass of `NSBitmapImageRep` to fix that GIF loop count issue because `NSBitmapImageRep` will reset `NSImageCurrentFrameDuration` by using `kCGImagePropertyGIFDelayTime` but not `kCGImagePropertyGIFUnclampedDelayTime`.
 Built in GIF coder use this instead of `NSBitmapImageRep` for better GIF rendering. If you do not want this, only enable `SDImageIOCoder`, which just call `NSImage` API and actually use `NSBitmapImageRep` for GIF image.
 This also support APNG format using `SDImageAPNGCoder`. Which provide full alpha-channel support and the correct duration match the `kBUCGImagePropertyAPNGUnclampedDelayTime`.
 */
@interface BU_SDAnimatedImageRep : NSBitmapImageRep
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImageView+BUWebCache.h
New file
@@ -0,0 +1,168 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDAnimatedImageView.h"
#if SD_UIKIT || SD_MAC
#import "BU_SDWebImageManager.h"
/**
 Integrates SDWebImage async downloading and caching of remote images with SDAnimatedImageView.
 */
@interface BU_SDAnimatedImageView (BUWebCache)
/**
 * Set the imageView `image` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url The url for the image.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;
/**
 * Set the imageView `image` with an `url` and a placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @see sdBu_setImageWithURL:placeholderImage:options:
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;
/**
 * Set the imageView `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options NS_REFINED_FOR_SWIFT;
/**
 * Set the imageView `image` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context;
/**
 * Set the imageView `image` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the imageView `image` with an `url`, placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;
/**
 * Set the imageView `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the imageView `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the imageView `image` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAnimatedImageView.h
New file
@@ -0,0 +1,84 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_UIKIT || SD_MAC
#import "BU_SDAnimatedImage.h"
/**
 A drop-in replacement for UIImageView/NSImageView, you can use this for animated image rendering.
 Call `setImage:` with `UIImage(NSImage)` which conform to `BU_SDAnimatedImage` protocol will start animated image rendering. Call with normal UIImage(NSImage) will back to normal UIImageView(NSImageView) rendering
 For UIKit: use `-startAnimating`, `-stopAnimating` to control animating. `isAnimating` to check animation state.
 For AppKit: use `-setAnimates:` to control animating, `animates` to check animation state. This view is layer-backed.
 */
@interface BU_SDAnimatedImageView : UIImageView
/**
 Current display frame image.
 */
@property (nonatomic, strong, readonly, nullable) UIImage *currentFrame;
/**
 Current frame index, zero based. This value is KVO Compliance.
 */
@property (nonatomic, assign, readonly) NSUInteger currentFrameIndex;
/**
 Current loop count since its latest animating. This value is KVO Compliance.
 */
@property (nonatomic, assign, readonly) NSUInteger currentLoopCount;
/**
 YES to choose `animationRepeatCount` property for animation loop count. No to use animated image's `animatedImageLoopCount` instead.
 Default is NO.
 */
@property (nonatomic, assign) BOOL shouldCustomLoopCount;
/**
 Total loop count for animated image rendering. Default is animated image's loop count.
 If you need to set custom loop count, set `shouldCustomLoopCount` to YES and change this value.
 This class override UIImageView's `animationRepeatCount` property on iOS, use this property as well.
 */
@property (nonatomic, assign) NSInteger animationRepeatCount;
/**
 Provide a max buffer size by bytes. This is used to adjust frame buffer count and can be useful when the decoding cost is expensive (such as Animated WebP software decoding). Default is 0.
 `0` means automatically adjust by calculating current memory usage.
 `1` means without any buffer cache, each of frames will be decoded and then be freed after rendering. (Lowest Memory and Highest CPU)
 `NSUIntegerMax` means cache all the buffer. (Lowest CPU and Highest Memory)
 */
@property (nonatomic, assign) NSUInteger maxBufferSize;
/**
 Whehter or not to enable incremental image load for animated image. This is for the animated image which `sdBu_isIncremental` is YES (See `UIImage+BUMetadata.h`). If enable, animated image rendering will stop at the last frame available currently, and continue when another `setImage:` trigger, where the new animated image's `animatedImageData` should be updated from the previous one. If the `sdBu_isIncremental` is NO. The incremental image load stop.
 @note If you are confused about this description, open Chrome browser to view some large GIF images with low network speed to see the animation behavior.
 @note The best practice to use incremental load is using `initWithAnimatedCoder:scale:` in `BU_SDAnimatedImage` with animated coder which conform to `SDProgressiveImageCoder` as well. Then call incremental update and incremental decode method to produce the image.
 Default is YES. Set to NO to only render the static poster for incremental animated image.
 */
@property (nonatomic, assign) BOOL shouldIncrementalLoad;
/**
 Whether or not to clear the frame buffer cache when animation stopped. See `maxBufferSize`
 This is useful when you want to limit the memory usage during frequently visibility changes (such as image view inside a list view, then push and pop)
 Default is NO.
 */
@property (nonatomic, assign) BOOL clearBufferWhenStopped;
/**
 Whether or not to reset the current frame index when animation stopped.
 For some of use case, you may want to reset the frame index to 0 when stop, but some other want to keep the current frame index.
 Default is NO.
 */
@property (nonatomic, assign) BOOL resetFrameIndexWhenStopped;
#if SD_UIKIT
/**
 You can specify a runloop mode to let it rendering.
 Default is NSRunLoopCommonModes on multi-core iOS device, NSDefaultRunLoopMode on single-core iOS device
 */
@property (nonatomic, copy, nonnull) NSRunLoopMode runLoopMode;
#endif
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDAsyncBlockOperation.h
New file
@@ -0,0 +1,20 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
@class BU_SDAsyncBlockOperation;
typedef void (^SDAsyncBlock)(BU_SDAsyncBlockOperation * __nonnull asyncOperation);
@interface BU_SDAsyncBlockOperation : NSOperation
- (nonnull instancetype)initWithBlock:(nonnull SDAsyncBlock)block;
+ (nonnull instancetype)blockOperationWithBlock:(nonnull SDAsyncBlock)block;
- (void)complete;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDDiskCache.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageAPNGCoder.h
New file
@@ -0,0 +1,19 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDImageCoder.h"
/**
 Built in coder using ImageIO that supports APNG encoding/decoding
 */
@interface BU_SDImageAPNGCoder : NSObject <BU_SDProgressiveImageCoder, BU_SDAnimatedImageCoder>
@property (nonatomic, class, readonly, nonnull) BU_SDImageAPNGCoder *sharedCoder;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageAPNGCoderInternal.h
New file
@@ -0,0 +1,17 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import "BU_SDImageAPNGCoder.h"
@interface BU_SDImageAPNGCoder ()
- (float)sdBu_frameDurationAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source;
- (NSUInteger)sdBu_imageLoopCountWithSource:(nonnull CGImageSourceRef)source;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageAssetManager.h
New file
@@ -0,0 +1,23 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
// Apple parse the Asset Catalog compiled file(`Assets.car`) by CoreUI.framework, however it's a private framework and there are no other ways to directly get the data. So we just process the normal bundle files :)
@interface BU_SDImageAssetManager : NSObject
@property (nonatomic, strong, nonnull) NSMapTable<NSString *, UIImage *> *imageTable;
+ (nonnull instancetype)sharedAssetManager;
- (nullable NSString *)getPathForName:(nonnull NSString *)name bundle:(nonnull NSBundle *)bundle preferredScale:(nonnull CGFloat *)scale;
- (nullable UIImage *)imageForName:(nonnull NSString *)name;
- (void)storeImage:(nonnull UIImage *)image forName:(nonnull NSString *)name;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCache.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCacheConfig.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCacheDefine.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCachesManager.h
New file
@@ -0,0 +1,81 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDImageCacheDefine.h"
/// Policy for cache operation
typedef NS_ENUM(NSUInteger, SDImageCachesManagerOperationPolicy) {
    SDImageCachesManagerOperationPolicySerial, // process all caches serially (from the highest priority to the lowest priority cache by order)
    SDImageCachesManagerOperationPolicyConcurrent, // process all caches concurrently
    SDImageCachesManagerOperationPolicyHighestOnly, // process the highest priority cache only
    SDImageCachesManagerOperationPolicyLowestOnly // process the lowest priority cache only
};
/**
 A caches manager to manage multiple caches.
 */
@interface BU_SDImageCachesManager : NSObject <BU_SDImageCache>
/**
 Returns the global shared caches manager instance. By default we will set [`SDImageCache.sharedImageCache`] into the caches array.
 */
@property (nonatomic, class, readonly, nonnull) BU_SDImageCachesManager *sharedManager;
// These are op policy for cache manager.
/**
 Operation policy for query op.
 Defaults to `Serial`, means query all caches serially (one completion called then next begin) until one cache query success (`image` != nil).
 */
@property (nonatomic, assign) SDImageCachesManagerOperationPolicy queryOperationPolicy;
/**
 Operation policy for store op.
 Defaults to `HighestOnly`, means store to the highest priority cache only.
 */
@property (nonatomic, assign) SDImageCachesManagerOperationPolicy storeOperationPolicy;
/**
 Operation policy for remove op.
 Defaults to `Concurrent`, means remove all caches concurrently.
 */
@property (nonatomic, assign) SDImageCachesManagerOperationPolicy removeOperationPolicy;
/**
 Operation policy for contains op.
 Defaults to `Serial`, means check all caches serially (one completion called then next begin) until one cache check success (`containsCacheType` != None).
 */
@property (nonatomic, assign) SDImageCachesManagerOperationPolicy containsOperationPolicy;
/**
 Operation policy for clear op.
 Defaults to `Concurrent`, means clear all caches concurrently.
 */
@property (nonatomic, assign) SDImageCachesManagerOperationPolicy clearOperationPolicy;
/**
 All caches in caches manager. The caches array is a priority queue, which means the later added cache will have the highest priority
 */
@property (nonatomic, copy, nullable) NSArray<id<BU_SDImageCache>> *caches;
/**
 Add a new cache to the end of caches array. Which has the highest priority.
 @param cache cache
 */
- (void)addCache:(nonnull id<BU_SDImageCache>)cache;
/**
 Remove a cache in the caches array.
 @param cache cache
 */
- (void)removeCache:(nonnull id<BU_SDImageCache>)cache;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCachesManagerOperation.h
New file
@@ -0,0 +1,21 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
// This is used for operation management, but not for operation queue execute
@interface BU_SDImageCachesManagerOperation : NSOperation
@property (nonatomic, assign, readonly) NSUInteger pendingCount;
- (void)beginWithTotalCount:(NSUInteger)totalCount;
- (void)completeOne;
- (void)done;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCoder.h
New file
@@ -0,0 +1,234 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
#import "NSData+BUImageContentType.h"
typedef NSString * SDImageCoderOption NS_STRING_ENUM;
typedef NSDictionary<SDImageCoderOption, id> SDImageCoderOptions;
typedef NSMutableDictionary<SDImageCoderOption, id> SDImageCoderMutableOptions;
#pragma mark - Coder Options
// These options are for image decoding
/**
 A Boolean value indicating whether to decode the first frame only for animated image during decoding. (NSNumber). If not provide, decode animated image if need.
 @note works for `SDImageCoder`.
 */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodeFirstFrameOnly;
/**
 A CGFloat value which is greater than or equal to 1.0. This value specify the image scale factor for decoding. If not provide, use 1.0. (NSNumber)
 @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `<BU_SDAnimatedImageCoder>`.
 */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodeScaleFactor;
// These options are for image encoding
/**
 A Boolean value indicating whether to encode the first frame only for animated image during encoding. (NSNumber). If not provide, encode animated image if need.
 @note works for `SDImageCoder`.
 */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderEncodeFirstFrameOnly;
/**
 A double value between 0.0-1.0 indicating the encode compression quality to produce the image data. 1.0 resulting in no compression and 0.0 resulting in the maximum compression possible. If not provide, use 1.0. (NSNumber)
 @note works for `SDImageCoder`
 */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderEncodeCompressionQuality;
/**
 A SDWebImageContext object which hold the original context options from top-level API. (SDWebImageContext)
 This option is ignored for all built-in coders and take no effect.
 But this may be useful for some custom coders, because some business logic may dependent on things other than image or image data inforamtion only.
 See `SDWebImageContext` for more detailed information.
 */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderWebImageContext;
/**
 A Boolean value indicating whether to keep the original aspect ratio when generating thumbnail images (or bitmap images from vector format).
 Defaults to YES.
 @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `<BU_SDAnimatedImageCoder>`.
 */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodePreserveAspectRatio;
/**
 A CGSize value indicating whether or not to generate the thumbnail images (or bitmap images from vector format). When this value is provided, the decoder will generate a thumbnail image which pixel size is smaller than or equal to (depends the `.preserveAspectRatio`) the value size.
 Defaults to CGSizeZero, which means no thumbnail generation at all.
 @note Supports for animated image as well.
 @note When you pass `.preserveAspectRatio == NO`, the thumbnail image is stretched to match each dimension. When `.preserveAspectRatio == YES`, the thumbnail image's width is limited to pixel size's width, the thumbnail image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both.
 @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `<BU_SDAnimatedImageCoder>`.
 */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodeThumbnailPixelSize;
#pragma mark - Coder
/**
 This is the image coder protocol to provide custom image decoding/encoding.
 These methods are all required to implement.
 @note Pay attention that these methods are not called from main queue.
 */
@protocol BU_SDImageCoder <NSObject>
@required
#pragma mark - Decoding
/**
 Returns YES if this coder can decode some data. Otherwise, the data should be passed to another coder.
 @param data The image data so we can look at it
 @return YES if this coder can decode the data, NO otherwise
 */
- (BOOL)canDecodeFromData:(nullable NSData *)data;
/**
 Decode the image data to image.
 @note This protocol may supports decode animated image frames. You can use `+[SDImageCoderHelper animatedImageWithFrames:]` to produce an animated image with frames.
 @param data The image data to be decoded
 @param options A dictionary containing any decoding options. Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for image. Pass @{BU_SDImageCoderDecodeFirstFrameOnly: @(YES)} to decode the first frame only.
 @return The decoded image from data
 */
- (nullable UIImage *)decodedImageWithData:(nullable NSData *)data
                                   options:(nullable SDImageCoderOptions *)options;
#pragma mark - Encoding
/**
 Returns YES if this coder can encode some image. Otherwise, it should be passed to another coder.
 For custom coder which introduce new image format, you'd better define a new `BU_SDImageFormat` using like this. If you're creating public coder plugin for new image format, also update `https://github.com/rs/SDWebImage/wiki/Coder-Plugin-List` to avoid same value been defined twice.
 * @code
 static const BU_SDImageFormat BU_SDImageFormatHEIF = 10;
 * @endcode
 @param format The image format
 @return YES if this coder can encode the image, NO otherwise
 */
- (BOOL)canEncodeToFormat:(BU_SDImageFormat)format NS_SWIFT_NAME(canEncode(to:));
/**
 Encode the image to image data.
 @note This protocol may supports encode animated image frames. You can use `+[SDImageCoderHelper framesFromAnimatedImage:]` to assemble an animated image with frames.
 @param image The image to be encoded
 @param format The image format to encode, you should note `BU_SDImageFormatUndefined` format is also  possible
 @param options A dictionary containing any encoding options. Pass @{BU_SDImageCoderEncodeCompressionQuality: @(1)} to specify compression quality.
 @return The encoded image data
 */
- (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image
                                   format:(BU_SDImageFormat)format
                                  options:(nullable SDImageCoderOptions *)options;
@end
#pragma mark - Progressive Coder
/**
 This is the image coder protocol to provide custom progressive image decoding.
 These methods are all required to implement.
 @note Pay attention that these methods are not called from main queue.
 */
@protocol BU_SDProgressiveImageCoder <BU_SDImageCoder>
@required
/**
 Returns YES if this coder can incremental decode some data. Otherwise, it should be passed to another coder.
 @param data The image data so we can look at it
 @return YES if this coder can decode the data, NO otherwise
 */
- (BOOL)canIncrementalDecodeFromData:(nullable NSData *)data;
/**
 Because incremental decoding need to keep the decoded context, we will alloc a new instance with the same class for each download operation to avoid conflicts
 This init method should not return nil
 @param options A dictionary containing any progressive decoding options (instance-level). Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive animated image (each frames should use the same scale).
 @return A new instance to do incremental decoding for the specify image format
 */
- (nonnull instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options;
/**
 Update the incremental decoding when new image data available
 @param data The image data has been downloaded so far
 @param finished Whether the download has finished
 */
- (void)updateIncrementalData:(nullable NSData *)data finished:(BOOL)finished;
/**
 Incremental decode the current image data to image.
 @note Due to the performance issue for progressive decoding and the integration for image view. This method may only return the first frame image even if the image data is animated image. If you want progressive animated image decoding, conform to `<BU_SDAnimatedImageCoder>` protocol as well and use `animatedImageFrameAtIndex:` instead.
 @param options A dictionary containing any progressive decoding options. Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive image
 @return The decoded image from current data
 */
- (nullable UIImage *)incrementalDecodedImageWithOptions:(nullable SDImageCoderOptions *)options;
@end
#pragma mark - Animated Image Provider
/**
 This is the animated image protocol to provide the basic function for animated image rendering. It's adopted by `BU_SDAnimatedImage` and `<BU_SDAnimatedImageCoder>`
 */
@protocol BU_SDAnimatedImageProvider <NSObject>
@required
/**
 The original animated image data for current image. If current image is not an animated format, return nil.
 We may use this method to grab back the original image data if need, such as NSCoding or compare.
 @return The animated image data
 */
@property (nonatomic, copy, readonly, nullable) NSData *animatedImageData;
/**
 Total animated frame count.
 If the frame count is less than 1, then the methods below will be ignored.
 @return Total animated frame count.
 */
@property (nonatomic, assign, readonly) NSUInteger animatedImageFrameCount;
/**
 Animation loop count, 0 means infinite looping.
 @return Animation loop count
 */
@property (nonatomic, assign, readonly) NSUInteger animatedImageLoopCount;
/**
 Returns the frame image from a specified index.
 @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's not recommend to store the images into array because it's memory consuming)
 @param index Frame index (zero based).
 @return Frame's image
 */
- (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index;
/**
 Returns the frames's duration from a specified index.
 @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's recommend to store the durations into array because it's not memory-consuming)
 @param index Frame index (zero based).
 @return Frame's duration
 */
- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index;
@end
#pragma mark - Animated Coder
/**
 This is the animated image coder protocol for custom animated image class like  `BU_SDAnimatedImage`. Through it inherit from `SDImageCoder`. We currentlly only use the method `canDecodeFromData:` to detect the proper coder for specify animated image format.
 */
@protocol BU_SDAnimatedImageCoder <BU_SDImageCoder, BU_SDAnimatedImageProvider>
@required
/**
 Because animated image coder should keep the original data, we will alloc a new instance with the same class for the specify animated image data
 The init method should return nil if it can't decode the specify animated image data to produce any frame.
 After the instance created, we may call methods in `BU_SDAnimatedImageProvider` to produce animated image frame.
 @param data The animated image data to be decode
 @param options A dictionary containing any animated decoding options (instance-level). Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for animated image (each frames should use the same scale).
 @return A new instance to do animated decoding for specify image data
 */
- (nullable instancetype)initWithAnimatedImageData:(nullable NSData *)data options:(nullable SDImageCoderOptions *)options;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCoderHelper.h
New file
@@ -0,0 +1,110 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <ImageIO/ImageIO.h>
#import "BU_SDWebImageCompat.h"
#import "BU_SDImageFrame.h"
/**
 Provide some common helper methods for building the image decoder/encoder.
 */
@interface BU_SDImageCoderHelper : NSObject
/**
 Return an animated image with frames array.
 For UIKit, this will apply the patch and then create animated UIImage. The patch is because that `+[UIImage animatedImageWithImages:duration:]` just use the average of duration for each image. So it will not work if different frame has different duration. Therefore we repeat the specify frame for specify times to let it work.
 For AppKit, NSImage does not support animates other than GIF. This will try to encode the frames to GIF format and then create an animated NSImage for rendering. Attention the animated image may loss some detail if the input frames contain full alpha channel because GIF only supports 1 bit alpha channel. (For 1 pixel, either transparent or not)
 @param frames The frames array. If no frames or frames is empty, return nil
 @return A animated image for rendering on UIImageView(UIKit) or NSImageView(AppKit)
 */
+ (UIImage * _Nullable)animatedImageWithFrames:(NSArray<BU_SDImageFrame *> * _Nullable)frames;
/**
 Return frames array from an animated image.
 For UIKit, this will unapply the patch for the description above and then create frames array. This will also work for normal animated UIImage.
 For AppKit, NSImage does not support animates other than GIF. This will try to decode the GIF imageRep and then create frames array.
 @param animatedImage A animated image. If it's not animated, return nil
 @return The frames array
 */
+ (NSArray<BU_SDImageFrame *> * _Nullable)framesFromAnimatedImage:(UIImage * _Nullable)animatedImage NS_SWIFT_NAME(frames(from:));
/**
 Return the shared device-dependent RGB color space. This follows The Get Rule.
 On iOS, it's created with deviceRGB (if available, use sRGB).
 On macOS, it's from the screen colorspace (if failed, use deviceRGB)
 Because it's shared, you should not retain or release this object.
 @return The device-dependent RGB color space
 */
+ (CGColorSpaceRef _Nonnull)colorSpaceGetDeviceRGB CF_RETURNS_NOT_RETAINED;
/**
 Check whether CGImage contains alpha channel.
 @param cgImage The CGImage
 @return Return YES if CGImage contains alpha channel, otherwise return NO
 */
+ (BOOL)CGImageContainsAlpha:(_Nonnull CGImageRef)cgImage;
/**
 Create a decoded CGImage by the provided CGImage. This follows The Create Rule and you are response to call release after usage.
 It will detect whether image contains alpha channel, then create a new bitmap context with the same size of image, and draw it. This can ensure that the image do not need extra decoding after been set to the imageView.
 @note This actually call `CGImageCreateDecoded:orientation:` with the Up orientation.
 @param cgImage The CGImage
 @return A new created decoded image
 */
+ (CGImageRef _Nullable)CGImageCreateDecoded:(_Nonnull CGImageRef)cgImage CF_RETURNS_RETAINED;
/**
 Create a decoded CGImage by the provided CGImage and orientation. This follows The Create Rule and you are response to call release after usage.
 It will detect whether image contains alpha channel, then create a new bitmap context with the same size of image, and draw it. This can ensure that the image do not need extra decoding after been set to the imageView.
 @param cgImage The CGImage
 @param orientation The EXIF image orientation.
 @return A new created decoded image
 */
+ (CGImageRef _Nullable)CGImageCreateDecoded:(_Nonnull CGImageRef)cgImage orientation:(CGImagePropertyOrientation)orientation CF_RETURNS_RETAINED;
/**
 Return the decoded image by the provided image. This one unlike `CGImageCreateDecoded:`, will not decode the image which contains alpha channel or animated image
 @param image The image to be decoded
 @return The decoded image
 */
+ (UIImage * _Nullable)decodedImageWithImage:(UIImage * _Nullable)image;
/**
 Return the decoded and probably scaled down image by the provided image. If the image is large than the limit size, will try to scale down. Or just works as `decodedImageWithImage:`
 @param image The image to be decoded and scaled down
 @param bytes The limit bytes size. Provide 0 to use the build-in limit.
 @return The decoded and probably scaled down image
 */
+ (UIImage * _Nullable)decodedAndScaledDownImageWithImage:(UIImage * _Nullable)image limitBytes:(NSUInteger)bytes;
#if SD_UIKIT || SD_WATCH
/**
 Convert an EXIF image orientation to an iOS one.
 @param exifOrientation EXIF orientation
 @return iOS orientation
 */
+ (UIImageOrientation)imageOrientationFromEXIFOrientation:(CGImagePropertyOrientation)exifOrientation NS_SWIFT_NAME(imageOrientation(from:));
/**
 Convert an iOS orientation to an EXIF image orientation.
 @param imageOrientation iOS orientation
 @return EXIF orientation
 */
+ (CGImagePropertyOrientation)exifOrientationFromImageOrientation:(UIImageOrientation)imageOrientation;
#endif
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageCodersManager.h
New file
@@ -0,0 +1,58 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDImageCoder.h"
/**
 Global object holding the array of coders, so that we avoid passing them from object to object.
 Uses a priority queue behind scenes, which means the latest added coders have the highest priority.
 This is done so when encoding/decoding something, we go through the list and ask each coder if they can handle the current data.
 That way, users can add their custom coders while preserving our existing prebuilt ones
 Note: the `coders` getter will return the coders in their reversed order
 Example:
 - by default we internally set coders = `IOCoder`, `GIFCoder`, `APNGCoder`
 - calling `coders` will return `@[IOCoder, GIFCoder, APNGCoder]`
 - call `[addCoder:[MyCrazyCoder new]]`
 - calling `coders` now returns `@[IOCoder, GIFCoder, APNGCoder, MyCrazyCoder]`
 Coders
 ------
 A coder must conform to the `SDImageCoder` protocol or even to `SDProgressiveImageCoder` if it supports progressive decoding
 Conformance is important because that way, they will implement `canDecodeFromData` or `canEncodeToFormat`
 Those methods are called on each coder in the array (using the priority order) until one of them returns YES.
 That means that coder can decode that data / encode to that format
 */
@interface BU_SDImageCodersManager : NSObject <BU_SDImageCoder>
/**
 Returns the global shared coders manager instance.
 */
@property (nonatomic, class, readonly, nonnull) BU_SDImageCodersManager *sharedManager;
/**
 All coders in coders manager. The coders array is a priority queue, which means the later added coder will have the highest priority
 */
@property (nonatomic, copy, nullable) NSArray<id<BU_SDImageCoder>> *coders;
/**
 Add a new coder to the end of coders array. Which has the highest priority.
 @param coder coder
 */
- (void)addCoder:(nonnull id<BU_SDImageCoder>)coder;
/**
 Remove a coder in the coders array.
 @param coder coder
 */
- (void)removeCoder:(nonnull id<BU_SDImageCoder>)coder;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageFrame.h
New file
@@ -0,0 +1,36 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
/**
 This class is used for creating animated images via `animatedImageWithFrames` in `SDImageCoderHelper`.
 @note If you need to specify animated images loop count, use `sdBu_imageLoopCount` property in `UIImage+BUMetadata.h`.
 */
@interface BU_SDImageFrame : NSObject
/**
 The image of current frame. You should not set an animated image.
 */
@property (nonatomic, strong, readonly, nonnull) UIImage *image;
/**
 The duration of current frame to be displayed. The number is seconds but not milliseconds. You should not set this to zero.
 */
@property (nonatomic, readonly, assign) NSTimeInterval duration;
/**
 Create a frame instance with specify image and duration
 @param image current frame's image
 @param duration current frame's duration
 @return frame instance
 */
+ (instancetype _Nonnull)frameWithImage:(UIImage * _Nonnull)image duration:(NSTimeInterval)duration;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageGIFCoder.h
New file
@@ -0,0 +1,22 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDImageCoder.h"
/**
 Built in coder using ImageIO that supports animated GIF encoding/decoding
 @note `SDImageIOCoder` supports GIF but only as static (will use the 1st frame).
 @note Use `SDImageGIFCoder` for fully animated GIFs. For `UIImageView`, it will produce animated `UIImage`(`NSImage` on macOS) for rendering. For `SDAnimatedImageView`, it will use `BU_SDAnimatedImage` for rendering.
 @note The recommended approach for animated GIFs is using `BU_SDAnimatedImage` with `SDAnimatedImageView`. It's more performant than `UIImageView` for GIF displaying(especially on memory usage)
 */
@interface BU_SDImageGIFCoder : NSObject <BU_SDProgressiveImageCoder, BU_SDAnimatedImageCoder>
@property (nonatomic, class, readonly, nonnull) BU_SDImageGIFCoder *sharedCoder;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageGIFCoderInternal.h
New file
@@ -0,0 +1,16 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import "BU_SDImageGIFCoder.h"
@interface BU_SDImageGIFCoder ()
- (float)sdBu_frameDurationAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageGraphics.h
New file
@@ -0,0 +1,27 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import <CoreGraphics/CoreGraphics.h>
/**
 These following graphics context method are provided to easily write cross-platform(AppKit/UIKit) code.
 For UIKit, these methods just call the same method in `UIGraphics.h`. See the documentation for usage.
 For AppKit, these methods use `NSGraphicsContext` to create image context and match the behavior like UIKit.
 */
/// Returns the current graphics context.
FOUNDATION_EXPORT CGContextRef __nullable BU_SDGraphicsGetCurrentContext(void) CF_RETURNS_NOT_RETAINED;
/// Creates a bitmap-based graphics context and makes it the current context.
FOUNDATION_EXPORT void BU_SDGraphicsBeginImageContext(CGSize size);
/// Creates a bitmap-based graphics context with the specified options.
FOUNDATION_EXPORT void BU_BU_SDGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);
/// Removes the current bitmap-based graphics context from the top of the stack.
FOUNDATION_EXPORT void BU_SDGraphicsEndImageContext(void);
/// Returns an image based on the contents of the current bitmap-based graphics context.
FOUNDATION_EXPORT UIImage * __nullable BU_SDGraphicsGetImageFromCurrentImageContext(void);
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageIOCoder.h
New file
@@ -0,0 +1,30 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDImageCoder.h"
/**
 Built in coder that supports PNG, JPEG, TIFF, includes support for progressive decoding.
 GIF
 Also supports static GIF (meaning will only handle the 1st frame).
 For a full GIF support, we recommend `SDAnimatedImageView` to keep both CPU and memory balanced.
 HEIC
 This coder also supports HEIC format because ImageIO supports it natively. But it depends on the system capabilities, so it won't work on all devices, see: https://devstreaming-cdn.apple.com/videos/wwdc/2017/511tj33587vdhds/511/511_working_with_heif_and_hevc.pdf
 Decode(Software): !Simulator && (iOS 11 || tvOS 11 || macOS 10.13)
 Decode(Hardware): !Simulator && ((iOS 11 && A9Chip) || (macOS 10.13 && 6thGenerationIntelCPU))
 Encode(Software): macOS 10.13
 Encode(Hardware): !Simulator && ((iOS 11 && A10FusionChip) || (macOS 10.13 && 6thGenerationIntelCPU))
 */
@interface BU_SDImageIOCoder : NSObject <BU_SDProgressiveImageCoder>
@property (nonatomic, class, readonly, nonnull) BU_SDImageIOCoder *sharedCoder;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageLoader.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageLoadersManager.h
New file
@@ -0,0 +1,40 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDImageLoader.h"
/**
 A loaders manager to manage multiple loaders
 */
@interface BU_SDImageLoadersManager : NSObject <BU_SDImageLoader>
/**
 Returns the global shared loaders manager instance. By default we will set [`SDWebImageDownloader.sharedDownloader`] into the loaders array.
 */
@property (nonatomic, class, readonly, nonnull) BU_SDImageLoadersManager *sharedManager;
/**
 All image loaders in manager. The loaders array is a priority queue, which means the later added loader will have the highest priority
 */
@property (nonatomic, copy, nullable) NSArray<id<BU_SDImageLoader>>* loaders;
/**
 Add a new image loader to the end of loaders array. Which has the highest priority.
 @param loader loader
 */
- (void)addLoader:(nonnull id<BU_SDImageLoader>)loader;
/**
 Remove a image loader in the loaders array.
 @param loader loader
 */
- (void)removeLoader:(nonnull id<BU_SDImageLoader>)loader;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDImageTransformer.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDInternalMacros.h
New file
@@ -0,0 +1,65 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDmetamacros.h"
#ifndef SD_LOCK
#define SD_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#endif
#ifndef SD_UNLOCK
#define SD_UNLOCK(lock) dispatch_semaphore_signal(lock);
#endif
#ifndef SD_OPTIONS_CONTAINS
#define SD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value))
#endif
#ifndef weakify
#define weakify(...) \
sd_keywordify \
metamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__)
#endif
#ifndef strongify
#define strongify(...) \
sd_keywordify \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
metamacro_foreach(sd_strongify_,, __VA_ARGS__) \
_Pragma("clang diagnostic pop")
#endif
#define sd_weakify_(INDEX, CONTEXT, VAR) \
CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
#define sd_strongify_(INDEX, VAR) \
__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);
#if DEBUG
#define sd_keywordify autoreleasepool {}
#else
#define sd_keywordify try {} @catch (...) {}
#endif
#ifndef onExit
#define onExit \
sd_keywordify \
__strong bu_sd_cleanupBlock_t metamacro_concat(sd_exitBlock_, __LINE__) __attribute__((cleanup(bu_sd_executeCleanupBlock), unused)) = ^
#endif
typedef void (^bu_sd_cleanupBlock_t)(void);
#if defined(__cplusplus)
extern "C" {
#endif
    void bu_sd_executeCleanupBlock (__strong bu_sd_cleanupBlock_t *block);
#if defined(__cplusplus)
}
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDMemoryCache.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWeakProxy.h
New file
@@ -0,0 +1,19 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
@interface BU_SDWeakProxy : NSProxy
@property (nonatomic, weak, readonly, nullable) id target;
- (nonnull instancetype)initWithTarget:(nonnull id)target;
+ (nonnull instancetype)proxyWithTarget:(nonnull id)target;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageCacheKeyFilter.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageCacheSerializer.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageCompat.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDefine.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloader.h
New file
@@ -0,0 +1,290 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
#import "BU_SDWebImageDefine.h"
#import "BU_SDWebImageOperation.h"
#import "BU_SDWebImageDownloaderConfig.h"
#import "BU_SDWebImageDownloaderRequestModifier.h"
#import "BU_SDImageLoader.h"
/// Downloader options
typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
    /**
     * Put the download in the low queue priority and task priority.
     */
    SDWebImageDownloaderLowPriority = 1 << 0,
    /**
     * This flag enables progressive download, the image is displayed progressively during download as a browser would do.
     */
    SDWebImageDownloaderProgressiveLoad = 1 << 1,
    /**
     * By default, request prevent the use of NSURLCache. With this flag, NSURLCache
     * is used with default policies.
     */
    SDWebImageDownloaderUseNSURLCache = 1 << 2,
    /**
     * Call completion block with nil image/imageData if the image was read from NSURLCache
     * And the error code is `SDWebImageErrorCacheNotModified`
     * This flag should be combined with `SDWebImageDownloaderUseNSURLCache`.
     */
    SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,
    /**
     * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for
     * extra time in background to let the request finish. If the background task expires the operation will be cancelled.
     */
    SDWebImageDownloaderContinueInBackground = 1 << 4,
    /**
     * Handles cookies stored in NSHTTPCookieStore by setting
     * NSMutableURLRequest.HTTPShouldHandleCookies = YES;
     */
    SDWebImageDownloaderHandleCookies = 1 << 5,
    /**
     * Enable to allow untrusted SSL certificates.
     * Useful for testing purposes. Use with caution in production.
     */
    SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,
    /**
     * Put the download in the high queue priority and task priority.
     */
    SDWebImageDownloaderHighPriority = 1 << 7,
    /**
     * By default, images are decoded respecting their original size. On iOS, this flag will scale down the
     * images to a size compatible with the constrained memory of devices.
     * This flag take no effect if `SDWebImageDownloaderAvoidDecodeImage` is set. And it will be ignored if `SDWebImageDownloaderProgressiveLoad` is set.
     */
    SDWebImageDownloaderScaleDownLargeImages = 1 << 8,
    /**
     * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation.
     * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image.
     */
    SDWebImageDownloaderAvoidDecodeImage = 1 << 9,
    /**
     * By default, we decode the animated image. This flag can force decode the first frame only and produece the static image.
     */
    SDWebImageDownloaderDecodeFirstFrameOnly = 1 << 10,
    /**
     * By default, for `BU_SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. This flag actually trigger `preloadAllAnimatedImageFrames = YES` after image load from network
     */
    SDWebImageDownloaderPreloadAllFrames = 1 << 11,
    /**
     * By default, when you use `BU_SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `BU_SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available, to behave as a fallback solution.
     * Using this option, can ensure we always produce image with your provided class. If failed, a error with code `SDWebImageErrorBadImageData` will been used.
     * Note this options is not compatible with `SDWebImageDownloaderDecodeFirstFrameOnly`, which always produce a UIImage/NSImage.
     */
    SDWebImageDownloaderMatchAnimatedImageClass = 1 << 12,
};
FOUNDATION_EXPORT NSNotificationName _Nonnull const BU_SDWebImageDownloadStartNotification;
FOUNDATION_EXPORT NSNotificationName _Nonnull const BU_SDWebImageDownloadReceiveResponseNotification;
FOUNDATION_EXPORT NSNotificationName _Nonnull const BU_SDWebImageDownloadStopNotification;
FOUNDATION_EXPORT NSNotificationName _Nonnull const BU_SDWebImageDownloadFinishNotification;
typedef SDImageLoaderProgressBlock SDWebImageDownloaderProgressBlock;
typedef SDImageLoaderCompletedBlock SDWebImageDownloaderCompletedBlock;
/**
 *  A token associated with each download. Can be used to cancel a download
 */
@interface BU_SDWebImageDownloadToken : NSObject <BU_SDWebImageOperation>
/**
 Cancel the current download.
 */
- (void)cancel;
/**
 The download's URL.
 */
@property (nonatomic, strong, nullable, readonly) NSURL *url;
/**
 The download's request.
 */
@property (nonatomic, strong, nullable, readonly) NSURLRequest *request;
/**
 The download's response.
 */
@property (nonatomic, strong, nullable, readonly) NSURLResponse *response;
@end
/**
 * Asynchronous downloader dedicated and optimized for image loading.
 */
@interface BU_SDWebImageDownloader : NSObject
/**
 * Downloader Config object - storing all kind of settings.
 * Most config properties support dynamic changes during download, except something like `sessionConfiguration`, see `BU_SDWebImageDownloaderConfig` for more detail.
 */
@property (nonatomic, copy, readonly, nonnull) BU_SDWebImageDownloaderConfig *config;
/**
 * Set the request modifier to modify the original download request before image load.
 * This request modifier method will be called for each downloading image request. Return the original request means no modication. Return nil will cancel the download request.
 * Defaults to nil, means does not modify the original download request.
 * @note If you want to modify single request, consider using `BU_SDWebImageContextDownloadRequestModifier` context option.
 */
@property (nonatomic, strong, nullable) id<SDWebImageDownloaderRequestModifier> requestModifier;
/**
 * The configuration in use by the internal NSURLSession. If you want to provide a custom sessionConfiguration, use `BU_SDWebImageDownloaderConfig.sessionConfiguration` and create a new downloader instance.
 @note This is immutable according to NSURLSession's documentation. Mutating this object directly has no effect.
 */
@property (nonatomic, readonly, nonnull) NSURLSessionConfiguration *sessionConfiguration;
/**
 * Gets/Sets the download queue suspension state.
 */
@property (nonatomic, assign, getter=isSuspended) BOOL suspended;
/**
 * Shows the current amount of downloads that still need to be downloaded
 */
@property (nonatomic, assign, readonly) NSUInteger currentDownloadCount;
/**
 *  Returns the global shared downloader instance. Which use the `BU_SDWebImageDownloaderConfig.defaultDownloaderConfig` config.
 */
@property (nonatomic, class, readonly, nonnull) BU_SDWebImageDownloader *sharedDownloader;
/**
 Creates an instance of a downloader with specified downloader config.
 You can specify session configuration, timeout or operation class through downloader config.
 @param config The downloader config. If you specify nil, the `defaultDownloaderConfig` will be used.
 @return new instance of downloader class
 */
- (nonnull instancetype)initWithConfig:(nullable BU_SDWebImageDownloaderConfig *)config NS_DESIGNATED_INITIALIZER;
/**
 * Set a value for a HTTP header to be appended to each download HTTP request.
 *
 * @param value The value for the header field. Use `nil` value to remove the header field.
 * @param field The name of the header field to set.
 */
- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field;
/**
 * Returns the value of the specified HTTP header field.
 *
 * @return The value associated with the header field field, or `nil` if there is no corresponding header field.
 */
- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field;
/**
 * Creates a SDWebImageDownloader async downloader instance with a given URL
 *
 * The delegate will be informed when the image is finish downloaded or an error has happen.
 *
 * @see SDWebImageDownloaderDelegate
 *
 * @param url            The URL to the image to download
 * @param completedBlock A block called once the download is completed.
 *                       If the download succeeded, the image parameter is set, in case of error,
 *                       error parameter is set with the error. The last parameter is always YES
 *                       if SDWebImageDownloaderProgressiveDownload isn't use. With the
 *                       SDWebImageDownloaderProgressiveDownload option, this block is called
 *                       repeatedly with the partial image object and the finished argument set to NO
 *                       before to be called a last time with the full image and finished argument
 *                       set to YES. In case of error, the finished argument is always YES.
 *
 * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation
 */
- (nullable BU_SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;
/**
 * Creates a SDWebImageDownloader async downloader instance with a given URL
 *
 * The delegate will be informed when the image is finish downloaded or an error has happen.
 *
 * @see SDWebImageDownloaderDelegate
 *
 * @param url            The URL to the image to download
 * @param options        The options to be used for this download
 * @param progressBlock  A block called repeatedly while the image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called once the download is completed.
 *                       If the download succeeded, the image parameter is set, in case of error,
 *                       error parameter is set with the error. The last parameter is always YES
 *                       if SDWebImageDownloaderProgressiveLoad isn't use. With the
 *                       SDWebImageDownloaderProgressiveLoad option, this block is called
 *                       repeatedly with the partial image object and the finished argument set to NO
 *                       before to be called a last time with the full image and finished argument
 *                       set to YES. In case of error, the finished argument is always YES.
 *
 * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation
 */
- (nullable BU_SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
                                                   options:(SDWebImageDownloaderOptions)options
                                                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;
/**
 * Creates a SDWebImageDownloader async downloader instance with a given URL
 *
 * The delegate will be informed when the image is finish downloaded or an error has happen.
 *
 * @see SDWebImageDownloaderDelegate
 *
 * @param url            The URL to the image to download
 * @param options        The options to be used for this download
 * @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called repeatedly while the image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called once the download is completed.
 *
 * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation
 */
- (nullable BU_SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
                                                   options:(SDWebImageDownloaderOptions)options
                                                   context:(nullable SDWebImageContext *)context
                                                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;
/**
 * Cancels all download operations in the queue
 */
- (void)cancelAllDownloads;
/**
 * Invalidates the managed session, optionally canceling pending operations.
 * @note If you use custom downloader instead of the shared downloader, you need call this method when you do not use it to avoid memory leak
 * @param cancelPendingOperations Whether or not to cancel pending operations.
 * @note Calling this method on the shared downloader has no effect.
 */
- (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations;
@end
/**
 SDWebImageDownloader is the built-in image loader conform to `SDImageLoader`. Which provide the HTTP/HTTPS/FTP download, or local file URL using NSURLSession.
 However, this downloader class itself also support customization for advanced users. You can specify `operationClass` in download config to custom download operation, See `SDWebImageDownloaderOperation`.
 If you want to provide some image loader which beyond network or local file, consider to create your own custom class conform to `SDImageLoader`.
 */
@interface BU_SDWebImageDownloader (SDImageLoader) <BU_SDImageLoader>
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloaderConfig.h
New file
@@ -0,0 +1,98 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
/// Operation execution order
typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
    /**
     * Default value. All download operations will execute in queue style (first-in-first-out).
     */
    SDWebImageDownloaderFIFOExecutionOrder,
    /**
     * All download operations will execute in stack style (last-in-first-out).
     */
    SDWebImageDownloaderLIFOExecutionOrder
};
/**
 The class contains all the config for image downloader
 @note This class conform to NSCopying, make sure to add the property in `copyWithZone:` as well.
 */
@interface BU_SDWebImageDownloaderConfig : NSObject <NSCopying>
/**
 Gets the default downloader config used for shared instance or initialization when it does not provide any downloader config. Such as `SDWebImageDownloader.sharedDownloader`.
 @note You can modify the property on default downloader config, which can be used for later created downloader instance. The already created downloader instance does not get affected.
 */
@property (nonatomic, class, readonly, nonnull) BU_SDWebImageDownloaderConfig *defaultDownloaderConfig;
/**
 * The maximum number of concurrent downloads.
 * Defaults to 6.
 */
@property (nonatomic, assign) NSInteger maxConcurrentDownloads;
/**
 * The timeout value (in seconds) for each download operation.
 * Defaults to 15.0.
 */
@property (nonatomic, assign) NSTimeInterval downloadTimeout;
/**
 * The minimum interval about progress percent during network downloading. Which means the next progress callback and current progress callback's progress percent difference should be larger or equal to this value. However, the final finish download progress callback does not get effected.
 * The value should be 0.0-1.0.
 * @note If you're using progressive decoding feature, this will also effect the image refresh rate.
 * @note This value may enhance the performance if you don't want progress callback too frequently.
 * Defaults to 0, which means each time we receive the new data from URLSession, we callback the progressBlock immediately.
 */
@property (nonatomic, assign) double minimumProgressInterval;
/**
 * The custom session configuration in use by NSURLSession. If you don't provide one, we will use `defaultSessionConfiguration` instead.
 * Defatuls to nil.
 * @note This property does not support dynamic changes, means it's immutable after the downloader instance initialized.
 */
@property (nonatomic, strong, nullable) NSURLSessionConfiguration *sessionConfiguration;
/**
 * Gets/Sets a subclass of `SDWebImageDownloaderOperation` as the default
 * `NSOperation` to be used each time SDWebImage constructs a request
 * operation to download an image.
 * Defaults to nil.
 * @note Passing `NSOperation<SDWebImageDownloaderOperation>` to set as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`.
 */
@property (nonatomic, assign, nullable) Class operationClass;
/**
 * Changes download operations execution order.
 * Defaults to `SDWebImageDownloaderFIFOExecutionOrder`.
 */
@property (nonatomic, assign) SDWebImageDownloaderExecutionOrder executionOrder;
/**
 * Set the default URL credential to be set for request operations.
 * Defaults to nil.
 */
@property (nonatomic, copy, nullable) NSURLCredential *urlCredential;
/**
 * Set username using for HTTP Basic authentication.
 * Defaults to nil.
 */
@property (nonatomic, copy, nullable) NSString *username;
/**
 * Set password using for HTTP Basic authentication.
 * Defautls to nil.
 */
@property (nonatomic, copy, nullable) NSString *password;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloaderOperation.h
New file
@@ -0,0 +1,146 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageDownloader.h"
#import "BU_SDWebImageOperation.h"
/**
 Describes a downloader operation. If one wants to use a custom downloader op, it needs to inherit from `NSOperation` and conform to this protocol
 For the description about these methods, see `SDWebImageDownloaderOperation`
 @note If your custom operation class does not use `NSURLSession` at all, do not implement the optional methods and session delegate methods.
 */
@protocol SDWebImageDownloaderOperation <NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
@required
- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request
                              inSession:(nullable NSURLSession *)session
                                options:(SDWebImageDownloaderOptions)options;
- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request
                              inSession:(nullable NSURLSession *)session
                                options:(SDWebImageDownloaderOptions)options
                                context:(nullable SDWebImageContext *)context;
- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                            completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;
- (BOOL)cancel:(nullable id)token;
@property (strong, nonatomic, readonly, nullable) NSURLRequest *request;
@property (strong, nonatomic, readonly, nullable) NSURLResponse *response;
@optional
@property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask;
@property (strong, nonatomic, nullable) NSURLCredential *credential;
@property (assign, nonatomic) double minimumProgressInterval;
@end
/**
 The download operation class for SDWebImageDownloader.
 */
@interface BU_SDWebImageDownloaderOperation : NSOperation <SDWebImageDownloaderOperation>
/**
 * The request used by the operation's task.
 */
@property (strong, nonatomic, readonly, nullable) NSURLRequest *request;
/**
 * The response returned by the operation's task.
 */
@property (strong, nonatomic, readonly, nullable) NSURLResponse *response;
/**
 * The operation's task
 */
@property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask;
/**
 * The credential used for authentication challenges in `-URLSession:task:didReceiveChallenge:completionHandler:`.
 *
 * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.
 */
@property (strong, nonatomic, nullable) NSURLCredential *credential;
/**
 * The minimum interval about progress percent during network downloading. Which means the next progress callback and current progress callback's progress percent difference should be larger or equal to this value. However, the final finish download progress callback does not get effected.
 * The value should be 0.0-1.0.
 * @note If you're using progressive decoding feature, this will also effect the image refresh rate.
 * @note This value may enhance the performance if you don't want progress callback too frequently.
 * Defaults to 0, which means each time we receive the new data from URLSession, we callback the progressBlock immediately.
 */
@property (assign, nonatomic) double minimumProgressInterval;
/**
 * The options for the receiver.
 */
@property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options;
/**
 * The context for the receiver.
 */
@property (copy, nonatomic, readonly, nullable) SDWebImageContext *context;
/**
 *  Initializes a `SDWebImageDownloaderOperation` object
 *
 *  @see SDWebImageDownloaderOperation
 *
 *  @param request        the URL request
 *  @param session        the URL session in which this operation will run
 *  @param options        downloader options
 *
 *  @return the initialized instance
 */
- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request
                              inSession:(nullable NSURLSession *)session
                                options:(SDWebImageDownloaderOptions)options;
/**
 *  Initializes a `SDWebImageDownloaderOperation` object
 *
 *  @see SDWebImageDownloaderOperation
 *
 *  @param request        the URL request
 *  @param session        the URL session in which this operation will run
 *  @param options        downloader options
 *  @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 *
 *  @return the initialized instance
 */
- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request
                              inSession:(nullable NSURLSession *)session
                                options:(SDWebImageDownloaderOptions)options
                                context:(nullable SDWebImageContext *)context NS_DESIGNATED_INITIALIZER;
/**
 *  Adds handlers for progress and completion. Returns a tokent that can be passed to -cancel: to cancel this set of
 *  callbacks.
 *
 *  @param progressBlock  the block executed when a new chunk of data arrives.
 *                        @note the progress block is executed on a background queue
 *  @param completedBlock the block executed when the download is done.
 *                        @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue
 *
 *  @return the token to use to cancel this set of handlers
 */
- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                            completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;
/**
 *  Cancels a set of callbacks. Once all callbacks are canceled, the operation is cancelled.
 *
 *  @param token the token representing a set of callbacks to cancel
 *
 *  @return YES if the operation was stopped because this was the last token to be canceled. NO otherwise.
 */
- (BOOL)cancel:(nullable id)token;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageDownloaderRequestModifier.h
New file
@@ -0,0 +1,32 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
typedef NSURLRequest * _Nullable (^SDWebImageDownloaderRequestModifierBlock)(NSURLRequest * _Nonnull request);
/**
 This is the protocol for downloader request modifier.
 We can use a block to specify the downloader request modifier. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options.
 */
@protocol SDWebImageDownloaderRequestModifier <NSObject>
- (nullable NSURLRequest *)modifiedRequestWithRequest:(nonnull NSURLRequest *)request;
@end
/**
 A downloader request modifier class with block.
 */
@interface BU_SDWebImageDownloaderRequestModifier : NSObject <SDWebImageDownloaderRequestModifier>
- (nonnull instancetype)initWithBlock:(nonnull SDWebImageDownloaderRequestModifierBlock)block;
+ (nonnull instancetype)requestModifierWithBlock:(nonnull SDWebImageDownloaderRequestModifierBlock)block;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageError.h
New file
@@ -0,0 +1,25 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 * (c) Jamie Pinkham
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
FOUNDATION_EXPORT NSErrorDomain const _Nonnull BU_SDWebImageErrorDomain;
/// The HTTP status code for invalid download response (NSNumber *)
FOUNDATION_EXPORT NSErrorUserInfoKey const _Nonnull BU_SDWebImageErrorDownloadStatusCodeKey;
/// SDWebImage error domain and codes
typedef NS_ERROR_ENUM(BU_SDWebImageErrorDomain, SDWebImageError) {
    SDWebImageErrorInvalidURL = 1000, // The URL is invalid, such as nil URL or corrupted URL
    SDWebImageErrorBadImageData = 1001, // The image data can not be decoded to image, or the image data is empty
    SDWebImageErrorCacheNotModified = 1002, // The remote location specify that the cached image is not modified, such as the HTTP response 304 code. It's useful for `SDWebImageRefreshCached`
    SDWebImageErrorInvalidDownloadOperation = 2000, // The image download operation is invalid, such as nil operation or unexpected error occur when operation initialized
    SDWebImageErrorInvalidDownloadStatusCode = 2001, // The image download response a invalid status code. You can check the status code in error's userInfo under `BU_SDWebImageErrorDownloadStatusCodeKey`
    SDWebImageErrorCancelled = 2002, // The image loading operation is cancelled before finished, during either async disk cache query, or waiting before actual network request. For actual network request error, check `NSURLErrorDomain` error domain and code.
};
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageIndicator.h
New file
@@ -0,0 +1,115 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_UIKIT || SD_MAC
/**
 A protocol to custom the indicator during the image loading.
 All of these methods are called from main queue.
 */
@protocol SDWebImageIndicator <NSObject>
@required
/**
 The view associate to the indicator.
 @return The indicator view
 */
@property (nonatomic, strong, readonly, nonnull) UIView *indicatorView;
/**
 Start the animating for indicator.
 */
- (void)startAnimatingIndicator;
/**
 Stop the animating for indicator.
 */
- (void)stopAnimatingIndicator;
@optional
/**
 Update the loading progress (0-1.0) for indicator. Optional
 @param progress The progress, value between 0 and 1.0
 */
- (void)updateIndicatorProgress:(double)progress;
@end
#pragma mark - Activity Indicator
/**
 Activity indicator class.
 for UIKit(macOS), it use a `UIActivityIndicatorView`.
 for AppKit(macOS), it use a `NSProgressIndicator` with the spinning style.
 */
@interface BU_SDWebImageActivityIndicator : NSObject <SDWebImageIndicator>
#if SD_UIKIT
@property (nonatomic, strong, readonly, nonnull) UIActivityIndicatorView *indicatorView;
#else
@property (nonatomic, strong, readonly, nonnull) NSProgressIndicator *indicatorView;
#endif
@end
/**
 Convenience way to use activity indicator.
 */
@interface BU_SDWebImageActivityIndicator (Conveniences)
/// These indicator use the fixed color without dark mode support
/// gray-style activity indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageActivityIndicator *grayIndicator;
/// large gray-style activity indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageActivityIndicator *grayLargeIndicator;
/// white-style activity indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageActivityIndicator *whiteIndicator;
/// large white-style activity indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageActivityIndicator *whiteLargeIndicator;
/// These indicator use the system style, supports dark mode if available (iOS 13+/macOS 10.14+)
/// large activity indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageActivityIndicator *largeIndicator;
/// medium activity indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageActivityIndicator *mediumIndicator;
@end
#pragma mark - Progress Indicator
/**
 Progress indicator class.
 for UIKit(macOS), it use a `UIProgressView`.
 for AppKit(macOS), it use a `NSProgressIndicator` with the bar style.
 */
@interface BU_SDWebImageProgressIndicator : NSObject <SDWebImageIndicator>
#if SD_UIKIT
@property (nonatomic, strong, readonly, nonnull) UIProgressView *indicatorView;
#else
@property (nonatomic, strong, readonly, nonnull) NSProgressIndicator *indicatorView;
#endif
@end
/**
 Convenience way to create progress indicator. Remember to specify the indicator width or use layout constraint if need.
 */
@interface BU_SDWebImageProgressIndicator (Conveniences)
/// default-style progress indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageProgressIndicator *defaultIndicator;
/// bar-style progress indicator
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageProgressIndicator *barIndicator API_UNAVAILABLE(macos, tvos);
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageManager.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageOperation.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageOptionsProcessor.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImagePrefetcher.h
New file
@@ -0,0 +1,143 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageManager.h"
@class BU_SDWebImagePrefetcher;
/**
 A token represents a list of URLs, can be used to cancel the download.
 */
@interface BU_SDWebImagePrefetchToken : NSObject <BU_SDWebImageOperation>
/**
 * Cancel the current prefetching.
 */
- (void)cancel;
/**
 list of URLs of current prefetching.
 */
@property (nonatomic, copy, readonly, nullable) NSArray<NSURL *> *urls;
@end
/**
 The prefetcher delegate protocol
 */
@protocol BU_SDWebImagePrefetcherDelegate <NSObject>
@optional
/**
 * Called when an image was prefetched. Which means it's called when one URL from any of prefetching finished.
 *
 * @param imagePrefetcher The current image prefetcher
 * @param imageURL        The image url that was prefetched
 * @param finishedCount   The total number of images that were prefetched (successful or not)
 * @param totalCount      The total number of images that were to be prefetched
 */
- (void)imagePrefetcher:(nonnull BU_SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(nullable NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount;
/**
 * Called when all images are prefetched. Which means it's called when all URLs from all of prefetching finished.
 * @param imagePrefetcher The current image prefetcher
 * @param totalCount      The total number of images that were prefetched (whether successful or not)
 * @param skippedCount    The total number of images that were skipped
 */
- (void)imagePrefetcher:(nonnull BU_SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount;
@end
typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls);
typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls);
/**
 * Prefetch some URLs in the cache for future use. Images are downloaded in low priority.
 */
@interface BU_SDWebImagePrefetcher : NSObject
/**
 * The web image manager used by prefetcher to prefetch images.
 * @note You can specify a standalone manager and downloader with custom configuration suitable for image prefetching. Such as `currentDownloadCount` or `downloadTimeout`.
 */
@property (strong, nonatomic, readonly, nonnull) BU_SDWebImageManager *manager;
/**
 * Maximum number of URLs to prefetch at the same time. Defaults to 3.
 */
@property (nonatomic, assign) NSUInteger maxConcurrentPrefetchCount;
/**
 * The options for prefetcher. Defaults to SDWebImageLowPriority.
 */
@property (nonatomic, assign) BU_SDWebImageOptions options;
/**
 * The context for prefetcher. Defaults to nil.
 */
@property (nonatomic, copy, nullable) SDWebImageContext *context;
/**
 * Queue options for prefetcher when call the progressBlock, completionBlock and delegate methods. Defaults to Main Queue.
 * @note The call is asynchronously to avoid blocking target queue.
 * @note The delegate queue should be set before any prefetching start and may not be changed during prefetching to avoid thread-safe problem.
 */
@property (strong, nonatomic, nonnull) dispatch_queue_t delegateQueue;
/**
 * The delegate for the prefetcher. Defatuls to nil.
 */
@property (weak, nonatomic, nullable) id <BU_SDWebImagePrefetcherDelegate> delegate;
/**
 * Returns the global shared image prefetcher instance. It use a standalone manager which is different from shared manager.
 */
@property (nonatomic, class, readonly, nonnull) BU_SDWebImagePrefetcher *sharedImagePrefetcher;
/**
 * Allows you to instantiate a prefetcher with any arbitrary image manager.
 */
- (nonnull instancetype)initWithImageManager:(nonnull BU_SDWebImageManager *)manager NS_DESIGNATED_INITIALIZER;
/**
 * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching. It based on the image manager so the image may from the cache and network according to the `options` property.
 * Prefetching is seperate to each other, which means the progressBlock and completionBlock you provide is bind to the prefetching for the list of urls.
 * Attention that call this will not cancel previous fetched urls. You should keep the token return by this to cancel or cancel all the prefetch.
 *
 * @param urls list of URLs to prefetch
 * @return the token to cancel the current prefetching.
 */
- (nullable BU_SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray<NSURL *> *)urls;
/**
 * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching. It based on the image manager so the image may from the cache and network according to the `options` property.
 * Prefetching is seperate to each other, which means the progressBlock and completionBlock you provide is bind to the prefetching for the list of urls.
 * Attention that call this will not cancel previous fetched urls. You should keep the token return by this to cancel or cancel all the prefetch.
 *
 * @param urls            list of URLs to prefetch
 * @param progressBlock   block to be called when progress updates;
 *                        first parameter is the number of completed (successful or not) requests,
 *                        second parameter is the total number of images originally requested to be prefetched
 * @param completionBlock block to be called when the current prefetching is completed
 *                        first param is the number of completed (successful or not) requests,
 *                        second parameter is the number of skipped requests
 * @return the token to cancel the current prefetching.
 */
- (nullable BU_SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray<NSURL *> *)urls
                                          progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock
                                         completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock;
/**
 * Remove and cancel all the prefeching for the prefetcher.
 */
- (void)cancelPrefetching;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDWebImageTransition.h
New file
@@ -0,0 +1,89 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_UIKIT || SD_MAC
#import "BU_SDImageCache.h"
#if SD_UIKIT
typedef UIViewAnimationOptions SDWebImageAnimationOptions;
#else
typedef NS_OPTIONS(NSUInteger, SDWebImageAnimationOptions) {
    SDWebImageAnimationOptionAllowsImplicitAnimation = 1 << 0, // specify `allowsImplicitAnimation` for the `NSAnimationContext`
};
#endif
typedef void (^SDWebImageTransitionPreparesBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image, NSData * _Nullable imageData, BU_SDImageCacheType cacheType, NSURL * _Nullable imageURL);
typedef void (^SDWebImageTransitionAnimationsBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image);
typedef void (^SDWebImageTransitionCompletionBlock)(BOOL finished);
/**
 This class is used to provide a transition animation after the view category load image finished. Use this on `sdBu_imageTransition` in UIView+BU_WebCache.h
 for UIKit(iOS & tvOS), we use `+[UIView transitionWithView:duration:options:animations:completion]` for transition animation.
 for AppKit(macOS), we use `+[NSAnimationContext runAnimationGroup:completionHandler:]` for transition animation. You can call `+[NSAnimationContext currentContext]` to grab the context during animations block.
 @note These transition are provided for basic usage. If you need complicated animation, consider to directly use Core Animation or use `SDWebImageAvoidAutoSetImage` and implement your own after image load finished.
 */
@interface BU_SDWebImageTransition : NSObject
/**
 By default, we set the image to the view at the beginning of the animtions. You can disable this and provide custom set image process
 */
@property (nonatomic, assign) BOOL avoidAutoSetImage;
/**
 The duration of the transition animation, measured in seconds. Defaults to 0.5.
 */
@property (nonatomic, assign) NSTimeInterval duration;
/**
 The timing function used for all animations within this transition animation (macOS).
 */
@property (nonatomic, strong, nullable) CAMediaTimingFunction *timingFunction API_UNAVAILABLE(ios, tvos, watchos);
/**
 A mask of options indicating how you want to perform the animations.
 */
@property (nonatomic, assign) SDWebImageAnimationOptions animationOptions;
/**
 A block object to be executed before the animation sequence starts.
 */
@property (nonatomic, copy, nullable) SDWebImageTransitionPreparesBlock prepares;
/**
 A block object that contains the changes you want to make to the specified view.
 */
@property (nonatomic, copy, nullable) SDWebImageTransitionAnimationsBlock animations;
/**
 A block object to be executed when the animation sequence ends.
 */
@property (nonatomic, copy, nullable) SDWebImageTransitionCompletionBlock completion;
@end
/**
 Convenience way to create transition. Remember to specify the duration if needed.
 for UIKit, these transition just use the correspond `animationOptions`. By default we enable `UIViewAnimationOptionAllowUserInteraction` to allow user interaction during transition.
 for AppKit, these transition use Core Animation in `animations`. So your view must be layer-backed. Set `wantsLayer = YES` before you apply it.
 */
@interface BU_SDWebImageTransition (Conveniences)
/// Fade transition.
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageTransition *fadeTransition;
/// Flip from left transition.
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageTransition *flipFromLeftTransition;
/// Flip from right transition.
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageTransition *flipFromRightTransition;
/// Flip from top transition.
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageTransition *flipFromTopTransition;
/// Flip from bottom transition.
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageTransition *flipFromBottomTransition;
/// Curl up transition.
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageTransition *curlUpTransition;
/// Curl down transition.
@property (nonatomic, class, nonnull, readonly) BU_SDWebImageTransition *curlDownTransition;
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_SDmetamacros.h
New file
@@ -0,0 +1,667 @@
/**
 * Macros for metaprogramming
 * ExtendedC
 *
 * Copyright (C) 2012 Justin Spahr-Summers
 * Released under the MIT license
 */
#ifndef EXTC_METAMACROS_H
#define EXTC_METAMACROS_H
/**
 * Executes one or more expressions (which may have a void type, such as a call
 * to a function that returns no value) and always returns true.
 */
#define metamacro_exprify(...) \
    ((__VA_ARGS__), true)
/**
 * Returns a string representation of VALUE after full macro expansion.
 */
#define metamacro_stringify(VALUE) \
        metamacro_stringify_(VALUE)
/**
 * Returns A and B concatenated after full macro expansion.
 */
#define metamacro_concat(A, B) \
        metamacro_concat_(A, B)
/**
 * Returns the Nth variadic argument (starting from zero). At least
 * N + 1 variadic arguments must be given. N must be between zero and twenty,
 * inclusive.
 */
#define metamacro_at(N, ...) \
        metamacro_concat(metamacro_at, N)(__VA_ARGS__)
/**
 * Returns the number of arguments (up to twenty) provided to the macro. At
 * least one argument must be provided.
 *
 * Inspired by P99: http://p99.gforge.inria.fr
 */
#define metamacro_argcount(...) \
        metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
/**
 * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is
 * given. Only the index and current argument will thus be passed to MACRO.
 */
#define metamacro_foreach(MACRO, SEP, ...) \
        metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)
/**
 * For each consecutive variadic argument (up to twenty), MACRO is passed the
 * zero-based index of the current argument, CONTEXT, and then the argument
 * itself. The results of adjoining invocations of MACRO are then separated by
 * SEP.
 *
 * Inspired by P99: http://p99.gforge.inria.fr
 */
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
        metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
/**
 * Identical to #metamacro_foreach_cxt. This can be used when the former would
 * fail due to recursive macro expansion.
 */
#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \
        metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
/**
 * In consecutive order, appends each variadic argument (up to twenty) onto
 * BASE. The resulting concatenations are then separated by SEP.
 *
 * This is primarily useful to manipulate a list of macro invocations into instead
 * invoking a different, possibly related macro.
 */
#define metamacro_foreach_concat(BASE, SEP, ...) \
        metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__)
/**
 * Iterates COUNT times, each time invoking MACRO with the current index
 * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO
 * are then separated by SEP.
 *
 * COUNT must be an integer between zero and twenty, inclusive.
 */
#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \
        metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT)
/**
 * Returns the first argument given. At least one argument must be provided.
 *
 * This is useful when implementing a variadic macro, where you may have only
 * one variadic argument, but no way to retrieve it (for example, because \c ...
 * always needs to match at least one argument).
 *
 * @code
#define varmacro(...) \
    metamacro_head(__VA_ARGS__)
 * @endcode
 */
#define metamacro_head(...) \
        metamacro_head_(__VA_ARGS__, 0)
/**
 * Returns every argument except the first. At least two arguments must be
 * provided.
 */
#define metamacro_tail(...) \
        metamacro_tail_(__VA_ARGS__)
/**
 * Returns the first N (up to twenty) variadic arguments as a new argument list.
 * At least N variadic arguments must be provided.
 */
#define metamacro_take(N, ...) \
        metamacro_concat(metamacro_take, N)(__VA_ARGS__)
/**
 * Removes the first N (up to twenty) variadic arguments from the given argument
 * list. At least N variadic arguments must be provided.
 */
#define metamacro_drop(N, ...) \
        metamacro_concat(metamacro_drop, N)(__VA_ARGS__)
/**
 * Decrements VAL, which must be a number between zero and twenty, inclusive.
 *
 * This is primarily useful when dealing with indexes and counts in
 * metaprogramming.
 */
#define metamacro_dec(VAL) \
        metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
/**
 * Increments VAL, which must be a number between zero and twenty, inclusive.
 *
 * This is primarily useful when dealing with indexes and counts in
 * metaprogramming.
 */
#define metamacro_inc(VAL) \
        metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
/**
 * If A is equal to B, the next argument list is expanded; otherwise, the
 * argument list after that is expanded. A and B must be numbers between zero
 * and twenty, inclusive. Additionally, B must be greater than or equal to A.
 *
 * @code
// expands to true
metamacro_if_eq(0, 0)(true)(false)
// expands to false
metamacro_if_eq(0, 1)(true)(false)
 * @endcode
 *
 * This is primarily useful when dealing with indexes and counts in
 * metaprogramming.
 */
#define metamacro_if_eq(A, B) \
        metamacro_concat(metamacro_if_eq, A)(B)
/**
 * Identical to #metamacro_if_eq. This can be used when the former would fail
 * due to recursive macro expansion.
 */
#define metamacro_if_eq_recursive(A, B) \
        metamacro_concat(metamacro_if_eq_recursive, A)(B)
/**
 * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and
 * twenty, inclusive.
 *
 * For the purposes of this test, zero is considered even.
 */
#define metamacro_is_even(N) \
        metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
/**
 * Returns the logical NOT of B, which must be the number zero or one.
 */
#define metamacro_not(B) \
        metamacro_at(B, 1, 0)
// IMPLEMENTATION DETAILS FOLLOW!
// Do not write code that depends on anything below this line.
#define metamacro_stringify_(VALUE) # VALUE
#define metamacro_concat_(A, B) A ## B
#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)
#define metamacro_head_(FIRST, ...) FIRST
#define metamacro_tail_(FIRST, ...) __VA_ARGS__
#define metamacro_consume_(...)
#define metamacro_expand_(...) __VA_ARGS__
// implemented from scratch so that metamacro_concat() doesn't end up nesting
#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG)
#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG
// metamacro_at expansions
#define metamacro_at0(...) metamacro_head(__VA_ARGS__)
#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__)
// metamacro_foreach_cxt expansions
#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT)
#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
    metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \
    SEP \
    MACRO(1, CONTEXT, _1)
#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
    metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
    SEP \
    MACRO(2, CONTEXT, _2)
#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
    metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
    SEP \
    MACRO(3, CONTEXT, _3)
#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
    metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
    SEP \
    MACRO(4, CONTEXT, _4)
#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
    metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
    SEP \
    MACRO(5, CONTEXT, _5)
#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
    metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
    SEP \
    MACRO(6, CONTEXT, _6)
#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
    metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
    SEP \
    MACRO(7, CONTEXT, _7)
#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
    metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
    SEP \
    MACRO(8, CONTEXT, _8)
#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
    metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
    SEP \
    MACRO(9, CONTEXT, _9)
#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
    metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
    SEP \
    MACRO(10, CONTEXT, _10)
#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
    metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
    SEP \
    MACRO(11, CONTEXT, _11)
#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
    metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
    SEP \
    MACRO(12, CONTEXT, _12)
#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
    metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
    SEP \
    MACRO(13, CONTEXT, _13)
#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
    metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
    SEP \
    MACRO(14, CONTEXT, _14)
#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
    metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
    SEP \
    MACRO(15, CONTEXT, _15)
#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
    metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
    SEP \
    MACRO(16, CONTEXT, _16)
#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
    metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
    SEP \
    MACRO(17, CONTEXT, _17)
#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
    metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
    SEP \
    MACRO(18, CONTEXT, _18)
#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \
    metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
    SEP \
    MACRO(19, CONTEXT, _19)
// metamacro_foreach_cxt_recursive expansions
#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT)
#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
    metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \
    SEP \
    MACRO(1, CONTEXT, _1)
#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
    metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
    SEP \
    MACRO(2, CONTEXT, _2)
#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
    metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
    SEP \
    MACRO(3, CONTEXT, _3)
#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
    metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
    SEP \
    MACRO(4, CONTEXT, _4)
#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
    metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
    SEP \
    MACRO(5, CONTEXT, _5)
#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
    metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
    SEP \
    MACRO(6, CONTEXT, _6)
#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
    metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
    SEP \
    MACRO(7, CONTEXT, _7)
#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
    metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
    SEP \
    MACRO(8, CONTEXT, _8)
#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
    metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
    SEP \
    MACRO(9, CONTEXT, _9)
#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
    metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
    SEP \
    MACRO(10, CONTEXT, _10)
#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
    metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
    SEP \
    MACRO(11, CONTEXT, _11)
#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
    metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
    SEP \
    MACRO(12, CONTEXT, _12)
#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
    metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
    SEP \
    MACRO(13, CONTEXT, _13)
#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
    metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
    SEP \
    MACRO(14, CONTEXT, _14)
#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
    metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
    SEP \
    MACRO(15, CONTEXT, _15)
#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
    metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
    SEP \
    MACRO(16, CONTEXT, _16)
#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
    metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
    SEP \
    MACRO(17, CONTEXT, _17)
#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
    metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
    SEP \
    MACRO(18, CONTEXT, _18)
#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \
    metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
    SEP \
    MACRO(19, CONTEXT, _19)
// metamacro_for_cxt expansions
#define metamacro_for_cxt0(MACRO, SEP, CONTEXT)
#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT)
#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt1(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(1, CONTEXT)
#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(2, CONTEXT)
#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(3, CONTEXT)
#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(4, CONTEXT)
#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(5, CONTEXT)
#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(6, CONTEXT)
#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(7, CONTEXT)
#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(8, CONTEXT)
#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(9, CONTEXT)
#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(10, CONTEXT)
#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(11, CONTEXT)
#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(12, CONTEXT)
#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(13, CONTEXT)
#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(14, CONTEXT)
#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(15, CONTEXT)
#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(16, CONTEXT)
#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(17, CONTEXT)
#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(18, CONTEXT)
#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \
    metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
    SEP \
    MACRO(19, CONTEXT)
// metamacro_if_eq expansions
#define metamacro_if_eq0(VALUE) \
    metamacro_concat(metamacro_if_eq0_, VALUE)
#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_
#define metamacro_if_eq0_1(...) metamacro_expand_
#define metamacro_if_eq0_2(...) metamacro_expand_
#define metamacro_if_eq0_3(...) metamacro_expand_
#define metamacro_if_eq0_4(...) metamacro_expand_
#define metamacro_if_eq0_5(...) metamacro_expand_
#define metamacro_if_eq0_6(...) metamacro_expand_
#define metamacro_if_eq0_7(...) metamacro_expand_
#define metamacro_if_eq0_8(...) metamacro_expand_
#define metamacro_if_eq0_9(...) metamacro_expand_
#define metamacro_if_eq0_10(...) metamacro_expand_
#define metamacro_if_eq0_11(...) metamacro_expand_
#define metamacro_if_eq0_12(...) metamacro_expand_
#define metamacro_if_eq0_13(...) metamacro_expand_
#define metamacro_if_eq0_14(...) metamacro_expand_
#define metamacro_if_eq0_15(...) metamacro_expand_
#define metamacro_if_eq0_16(...) metamacro_expand_
#define metamacro_if_eq0_17(...) metamacro_expand_
#define metamacro_if_eq0_18(...) metamacro_expand_
#define metamacro_if_eq0_19(...) metamacro_expand_
#define metamacro_if_eq0_20(...) metamacro_expand_
#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE))
#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE))
#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE))
#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE))
#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE))
#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE))
#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE))
#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE))
#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE))
#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE))
#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE))
#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE))
#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE))
#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE))
#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE))
#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE))
#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE))
#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE))
#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE))
#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE))
// metamacro_if_eq_recursive expansions
#define metamacro_if_eq_recursive0(VALUE) \
    metamacro_concat(metamacro_if_eq_recursive0_, VALUE)
#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_
#define metamacro_if_eq_recursive0_1(...) metamacro_expand_
#define metamacro_if_eq_recursive0_2(...) metamacro_expand_
#define metamacro_if_eq_recursive0_3(...) metamacro_expand_
#define metamacro_if_eq_recursive0_4(...) metamacro_expand_
#define metamacro_if_eq_recursive0_5(...) metamacro_expand_
#define metamacro_if_eq_recursive0_6(...) metamacro_expand_
#define metamacro_if_eq_recursive0_7(...) metamacro_expand_
#define metamacro_if_eq_recursive0_8(...) metamacro_expand_
#define metamacro_if_eq_recursive0_9(...) metamacro_expand_
#define metamacro_if_eq_recursive0_10(...) metamacro_expand_
#define metamacro_if_eq_recursive0_11(...) metamacro_expand_
#define metamacro_if_eq_recursive0_12(...) metamacro_expand_
#define metamacro_if_eq_recursive0_13(...) metamacro_expand_
#define metamacro_if_eq_recursive0_14(...) metamacro_expand_
#define metamacro_if_eq_recursive0_15(...) metamacro_expand_
#define metamacro_if_eq_recursive0_16(...) metamacro_expand_
#define metamacro_if_eq_recursive0_17(...) metamacro_expand_
#define metamacro_if_eq_recursive0_18(...) metamacro_expand_
#define metamacro_if_eq_recursive0_19(...) metamacro_expand_
#define metamacro_if_eq_recursive0_20(...) metamacro_expand_
#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE))
#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE))
// metamacro_take expansions
#define metamacro_take0(...)
#define metamacro_take1(...) metamacro_head(__VA_ARGS__)
#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__))
#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__))
#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__))
#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__))
#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__))
#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__))
#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__))
#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__))
#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__))
#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__))
#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__))
#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__))
#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__))
#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__))
#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__))
#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__))
#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__))
#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__))
#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__))
// metamacro_drop expansions
#define metamacro_drop0(...) __VA_ARGS__
#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__)
#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__))
#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__))
#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__))
#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__))
#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__))
#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__))
#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__))
#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__))
#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__))
#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__))
#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__))
#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__))
#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__))
#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__))
#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__))
#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__))
#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__))
#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__))
#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__))
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_ZFPlayer.h
New file
@@ -0,0 +1,32 @@
//
//  ZFPlayer.h
//
// 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 "BUPlayer.h"
#import "BUPlayerDefine.h"
#import "UIImageView+BU_ZFCache.h"
#import "BU_ZFPlayerControlView.h"
#import "BUPlayerInternalDefine.h"
#import "BUPlayerSettingsProtocol.h"
#import "BUPlayerItem.h"
#import "BUVideoPrefetchManager.h"
#import "BUCacheManager.h"
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/BU_ZFPlayerControlView.h
New file
@@ -0,0 +1,31 @@
//
//  ZFPlayerControlView.h
//
// 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 "BUPlayerDefine.h"
@interface BU_ZFPlayerControlView : UIView <BUPlayerControlViewProtocol>
- (void)hideControlView;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSArray+BUUtilities.h
New file
@@ -0,0 +1,29 @@
//
//  NSMutableArray+Utilities.h
//  BUAdSDK
//
//  Created by æŽç›› on 2018/2/28.
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSMutableArray (BU_Utilities)
- (void)bu_safeAddObject:(id)object;
- (void)bu_safeAddNilObject;
- (void)bu_safeInsertObject:(id)object atIndex:(NSUInteger)index;
- (void)bu_safeInsertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes;
- (void)bu_safeRemoveObject:(id)object;
- (nullable id)bu_objectAtIndexSafely:(NSUInteger)index;
- (void)bu_removeObjectAtIndexSafely:(NSUInteger)index;
@end
@interface NSArray(BU_JSONValue)
- (nullable NSString *)bu_JSONRepresentation:(NSError **)error;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSBezierPath+BURoundedCorners.h
New file
@@ -0,0 +1,24 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_MAC
#import "UIImage+BUTransform.h"
@interface NSBezierPath (RoundedCorners)
/**
 Convenience way to create a bezier path with the specify rounding corners on macOS. Same as the one on `UIBezierPath`.
 */
+ (nonnull instancetype)sdBu_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(BU_SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius;
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSButton+BUWebCache.h
New file
@@ -0,0 +1,340 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_MAC
#import "BU_SDWebImageManager.h"
/**
 * Integrates SDWebImage async downloading and caching of remote images with NSButton.
 */
@interface NSButton (WebCache)
#pragma mark - Image
/**
 * Get the current image URL.
 */
@property (nonatomic, strong, readonly, nullable) NSURL *sdBu_currentImageURL;
/**
 * Set the button `image` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url The url for the image.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url` and a placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @see sdBu_setImageWithURL:placeholderImage:options:
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context;
/**
 * Set the button `image` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `image` with an `url`, placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
#pragma mark - Alternate Image
/**
 * Get the current alternateImage URL.
 */
@property (nonatomic, strong, readonly, nullable) NSURL *sdBu_currentAlternateImageURL;
/**
 * Set the button `alternateImage` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url The url for the alternateImage.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;
/**
 * Set the button `alternateImage` with an `url` and a placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the alternateImage.
 * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes.
 * @see sdBu_setAlternateImageWithURL:placeholderImage:options:
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                   placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;
/**
 * Set the button `alternateImage` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the alternateImage.
 * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes.
 * @param options     The options to use when downloading the alternateImage. @see BU_SDWebImageOptions for the possible values.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                   placeholderImage:(nullable UIImage *)placeholder
                            options:(BU_SDWebImageOptions)options NS_REFINED_FOR_SWIFT;
/**
 * Set the button `alternateImage` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the alternateImage.
 * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes.
 * @param options     The options to use when downloading the alternateImage. @see BU_SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                   placeholderImage:(nullable UIImage *)placeholder
                            options:(BU_SDWebImageOptions)options
                            context:(nullable SDWebImageContext *)context;
/**
 * Set the button `alternateImage` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the alternateImage.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the alternateImage was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original alternateImage url.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                          completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `alternateImage` with an `url`, placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the alternateImage.
 * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the alternateImage was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original alternateImage url.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                   placeholderImage:(nullable UIImage *)placeholder
                          completed:(nullable BU_SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;
/**
 * Set the button `alternateImage` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the alternateImage.
 * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.
 * @param options        The options to use when downloading the alternateImage. @see BU_SDWebImageOptions for the possible values.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the alternateImage was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original alternateImage url.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                   placeholderImage:(nullable UIImage *)placeholder
                            options:(BU_SDWebImageOptions)options
                          completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `alternateImage` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the alternateImage.
 * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.
 * @param options        The options to use when downloading the alternateImage. @see BU_SDWebImageOptions for the possible values.
 * @param progressBlock  A block called while alternateImage is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the alternateImage was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original alternateImage url.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                   placeholderImage:(nullable UIImage *)placeholder
                            options:(BU_SDWebImageOptions)options
                           progress:(nullable SDImageLoaderProgressBlock)progressBlock
                          completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `alternateImage` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the alternateImage.
 * @param placeholder    The alternateImage to be set initially, until the alternateImage request finishes.
 * @param options        The options to use when downloading the alternateImage. @see BU_SDWebImageOptions for the possible values.
 * @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called while alternateImage is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the alternateImage parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the alternateImage was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original alternateImage url.
 */
- (void)sdBu_setAlternateImageWithURL:(nullable NSURL *)url
                   placeholderImage:(nullable UIImage *)placeholder
                            options:(BU_SDWebImageOptions)options
                            context:(nullable SDWebImageContext *)context
                           progress:(nullable SDImageLoaderProgressBlock)progressBlock
                          completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
#pragma mark - Cancel
/**
 * Cancel the current image download
 */
- (void)sdBu_cancelCurrentImageLoad;
/**
 * Cancel the current alternateImage download
 */
- (void)sdBu_cancelCurrentAlternateImageLoad;
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSData+BUImageContentType.h
New file
@@ -0,0 +1,59 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 * (c) Fabrice Aneche
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import <Foundation/Foundation.h>
#import "BU_SDWebImageCompat.h"
/**
 You can use switch case like normal enum. It's also recommended to add a default case. You should not assume anything about the raw value.
 For custom coder plugin, it can also extern the enum for supported format. See `SDImageCoder` for more detailed information.
 */
typedef NSInteger BU_SDImageFormat NS_TYPED_EXTENSIBLE_ENUM;
static const BU_SDImageFormat BU_SDImageFormatUndefined = -1;
static const BU_SDImageFormat BU_SDImageFormatJPEG      = 0;
static const BU_SDImageFormat BU_SDImageFormatPNG       = 1;
static const BU_SDImageFormat BU_SDImageFormatGIF       = 2;
static const BU_SDImageFormat BU_SDImageFormatTIFF      = 3;
static const BU_SDImageFormat BU_SDImageFormatWebP      = 4;
static const BU_SDImageFormat BU_SDImageFormatHEIC      = 5;
static const BU_SDImageFormat BU_SDImageFormatHEIF      = 6;
static const BU_SDImageFormat BU_SDImageFormatPDF       = 7;
static const BU_SDImageFormat BU_SDImageFormatSVG       = 8;
/**
 NSData category about the image content type and UTI.
 */
@interface NSData (BU_ImageContentType)
/**
 *  Return image format
 *
 *  @param data the input image data
 *
 *  @return the image format as `BU_SDImageFormat` (enum)
 */
+ (BU_SDImageFormat)sdBu_imageFormatForImageData:(nullable NSData *)data;
/**
 *  Convert BU_SDImageFormat to UTType
 *
 *  @param format Format as BU_SDImageFormat
 *  @return The UTType as CFStringRef
 */
+ (nonnull CFStringRef)sdBu_UTTypeFromImageFormat:(BU_SDImageFormat)format CF_RETURNS_NOT_RETAINED NS_SWIFT_NAME(sdBu_UTType(from:));
/**
 *  Convert UTTyppe to BU_SDImageFormat
 *
 *  @param uttype The UTType as CFStringRef
 *  @return The Format as BU_SDImageFormat
 */
+ (BU_SDImageFormat)sdBu_imageFormatFromUTType:(nonnull CFStringRef)uttype;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSDictionary+BUUtilities.h
New file
@@ -0,0 +1,42 @@
//
//  NSMutableDictionary+Utilities.h
//  BUAdSDK
//
//  Created by æŽç›› on 2018/2/28.
//  Copyright Â© 2018å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSDictionary (BU_Helper)
#pragma mark - Safe Value Type From Key
- (nullable NSString *)bu_stringForKey:(NSString *)key defaultValue:(nullable NSString *)defalutValue;
- (NSInteger)bu_integerForKey:(NSString *)key defaultValue:(NSInteger)defalutValue;
- (long)bu_longForKey:(NSString *)key defaultValue:(long)defalutValue;
- (long long)bu_longLongForKey:(NSString *)key defaultValue:(long long)defalutValue;
- (NSTimeInterval)bu_timeIntervalForKey:(NSString *)key defaultValue:(NSTimeInterval)defalutValue;
- (float)bu_floatForKey:(NSString *)key defaultValue:(float)defalutValue;
- (nullable NSArray *)bu_arrayForKey:(NSString *)key defaultValue:(nullable NSArray *)defalutValue;
- (nullable NSDictionary *)bu_dictionaryForKey:(NSString *)key defaultValue:(nullable NSDictionary *)defalutValue;
@end
@interface NSDictionary(BU_JSONValue)
- (nullable NSString *)bu_JSONRepresentation:(NSError **)error;
+ (nullable NSDictionary *)bu_dictionaryWithJSONData:(NSData *)inData error:(NSError **)outError;
+ (nullable NSDictionary *)bu_dictionaryWithJSONString:(NSString *)inJSON error:(NSError **)outError;
@end
@interface NSMutableDictionary (BU_Helper)
#pragma mark - Safe Set Object For Key
- (void)bu_setObject:(id)object forKey:(id<NSCopying>)key;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSImage+BUCompatibility.h
New file
@@ -0,0 +1,53 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_MAC
/**
 This category is provided to easily write cross-platform(AppKit/UIKit) code. For common usage, see `UIImage+BUMetadata.h`.
 */
@interface NSImage (Compatibility)
/**
The underlying Core Graphics image object. This will actually use `CGImageForProposedRect` with the image size.
 */
@property (nonatomic, readonly, nullable) CGImageRef CGImage;
/**
 The scale factor of the image. This wil actually use `bestRepresentationForRect` with image size and pixel size to calculate the scale factor. If failed, use the default value 1.0. Should be greater than or equal to 1.0.
 */
@property (nonatomic, readonly) CGFloat scale;
// These are convenience methods to make AppKit's `NSImage` match UIKit's `UIImage` behavior. The scale factor should be greater than or equal to 1.0.
/**
 Returns an image object with the scale factor and orientation. The representation is created from the Core Graphics image object.
 @note The difference between this and `initWithCGImage:size` is that `initWithCGImage:size` will actually create a `NSCGImageSnapshotRep` representation and always use `backingScaleFactor` as scale factor. So we should avoid it and use `NSBitmapImageRep` with `initWithCGImage:` instead.
 @note The difference between this and UIKit's `UIImage` equivalent method is the way to process orientation. If the provided image orientation is not equal to Up orientation, this method will firstly rotate the CGImage to the correct orientation to work compatible with `NSImageView`. However, UIKit will not actually rotate CGImage and just store it as `imageOrientation` property.
 @param cgImage A Core Graphics image object
 @param scale The image scale factor
 @param orientation The orientation of the image data
 @return The image object
 */
- (nonnull instancetype)initWithCGImage:(nonnull CGImageRef)cgImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation;
/**
 Returns an image object with the scale factor. The representation is created from the image data.
 @note The difference between these this and `initWithData:` is that `initWithData:` will always use `backingScaleFactor` as scale factor.
 @param data The image data
 @param scale The image scale factor
 @return The image object
 */
- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale;
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSJSONSerialization+BUSafeSerializaiton.h
New file
@@ -0,0 +1,18 @@
//
//  NSJSONSerialization+BUSafeSerializaiton.h
//  BUFoundation
//
//  Created by bytedance on 2020/10/10.
//  Copyright Â© 2020 Union. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSJSONSerialization (BUSafeSerializaiton)
+ (nonnull NSString *)bu_stringJsonSerializationWithObject:(id)object options:(NSJSONWritingOptions)opt error:(NSError **)error;
+ (nullable NSData *)bu_dataJsonSerializationWithObject:(id)object options:(NSJSONWritingOptions)opt error:(NSError **)error;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSKeyedArchiver+BUKeyedArchiver.h
New file
@@ -0,0 +1,16 @@
//
//  NSKeyedArchiver+BUKeyedArchiver.h
//  BUFoundation
//
//  Created by Eason on 2021/4/20.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSKeyedArchiver (BUKeyedArchiver)
+ (NSData *)bu_archivedDataWithRootObject:(id)rootObject;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSObject+BUSafeKVO.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSObject+BUUtils.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSPointerArray+BUSafely.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSString+BUAddtion.h
New file
@@ -0,0 +1,104 @@
//
//  NSString+URLEncoding.h
//  BUAdSDK
//
//  Created by carl on 2017/10/26.
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, BULanguageType) {//"万"转换规则
    BULanguageType_showWan     = 0,         //直接拼接万,默认
    BULanguageType_showNum     = 1,         //直接展示数字
};
@interface NSString (BU_URLCoding)
- (nullable NSString *)bu_URLEncodedString;
- (nullable NSString *)bu_URLDecodedString;
@end
@interface NSString (BU_Encryption)
- (nullable NSString *)bu_sha256;
/**
 * @brief è¿”回自身的md5
 * @return è¿”回自身的md5的16进制字串
 */
- (nullable NSString *)bu_MD5HashString;
@end
@interface NSString (BU_NumberToWan)
/// æ•°å­—转换成x万(以1w为界限,小于1w显示原始数字) æ²¡æœ‰â€ä¸‡â€œèµ°å¦ä¸€å¥—展示逻辑
+ (NSString *)bu_numberToWan:(NSInteger)target wan:(NSString *)wan;
/// å¤§äºŽ1w就用k表示,不大于就直接展示多少个评分
+ (NSString *)bu_numberToThousand:(NSInteger)target;
@end
@interface NSString (BU_URLStringAppend)
/*
 *
 string转URL
 */
+ (nullable NSURL *)bu_URLWithURLString:(NSString *)str;
/*
 *
 string转字典
 */
+ (NSDictionary*)bu_parametersOfURLString:(NSString*)urlString DEPRECATED_MSG_ATTRIBUTE("使用 `bu_parametersOfURLQueryString` ä»£æ›¿æ­¤æ–¹æ³•");
+ (NSDictionary*)bu_parametersOfURLQueryString:(NSString*)urlString;
/*
 *
 url字符串拼接参数,需要判断是否是第一个
 */
+ (NSString *)bu_urlStringWithOriginUrlString:(NSString *)originUrlString appendParameters:(NSDictionary *)parameters;
@end
@interface NSString (BU_Sandbox)
/**
 *  èŽ·å–ç¼“å­˜è·¯å¾„
 *
 *  @return path where to cache
 */
- (NSString *)bu_CachePath;
/**
 * @brief èŽ·å–ç¨‹åºçš„ç”¨æˆ·æ–‡æ¡£ç›®å½•çš„è·¯å¾„åŠ ä¸Šè‡ªèº«
 * @return ç”¨æˆ·æ–‡æ¡£ç›®å½•路径字串加上自身,该字符串是自动释放的
 */
- (NSString *)bu_DocumentsPath;
@end
@interface NSString(BU_JSONValue)
- (nullable id)bu_JSONValue:(NSError **)error;
+ (nullable id)bu_objectWithJSONData:(NSData *)inData error:(NSError **)outError;
@end
@interface NSString(BU_Time)
+ (NSString*)bu_dateNowString;
+ (NSString*)bu_dateStringSince:(NSTimeInterval)timeInterval;
+ (NSNumber*)bu_currentInterval;
@end
@interface NSString(BU_Random)
/*  @deccription生成随机字符
 *  @param count å¤šå°‘位随机数
 */
+ (NSString *)randomStringWithCount:(NSUInteger)count;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSTimer+BUBlockSupport.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/NSUserDefaults+BUCrypt.h
New file
@@ -0,0 +1,32 @@
//
//  NSUserDefaults+BUCrypt.h
//  BUFoundation
//
//  Created by Willie on 2020/9/11.
//  Copyright Â© 2020 bytedance. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSUserDefaults (BUCrypt)
- (void)setValue:(nullable id)value
          forKey:(NSString *)key
           crypt:(BOOL)crypt
           error:(NSError **)error;
- (nullable id)valueForKey:(NSString *)defaultName
                     crypt:(BOOL)crypt
                     error:(NSError **)error;
- (void)removeObjectForKey:(NSString *)defaultName
                     crypt:(BOOL)crypt
                     error:(NSError **)error;
- (void)bu_synchronize;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIButton+BUWebCache.h
New file
@@ -0,0 +1,387 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_UIKIT
#import "BU_SDWebImageManager.h"
/**
 * Integrates SDWebImage async downloading and caching of remote images with UIButton.
 */
@interface UIButton (BUWebCache)
#pragma mark - Image
/**
 * Get the current image URL.
 */
@property (nonatomic, strong, readonly, nullable) NSURL *sdBu_currentImageURL;
/**
 * Get the image URL for a control state.
 *
 * @param state Which state you want to know the URL for. The values are described in UIControlState.
 */
- (nullable NSURL *)sdBu_imageURLForState:(UIControlState)state;
/**
 * Set the button `image` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url   The url for the image.
 * @param state The state that uses the specified title. The values are described in UIControlState.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url` and a placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param state       The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @see sdBu_setImageWithURL:placeholderImage:options:
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param state       The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param state       The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context;
/**
 * Set the button `image` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param state          The state that uses the specified title. The values are described in UIControlState.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `image` with an `url`, placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param state          The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
          placeholderImage:(nullable UIImage *)placeholder
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param state          The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `image` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param state          The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `image` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param state          The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setImageWithURL:(nullable NSURL *)url
                  forState:(UIControlState)state
          placeholderImage:(nullable UIImage *)placeholder
                   options:(BU_SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
#pragma mark - Background Image
/**
 * Get the current background image URL.
 */
@property (nonatomic, strong, readonly, nullable) NSURL *sdBu_currentBackgroundImageURL;
/**
 * Get the background image URL for a control state.
 *
 * @param state Which state you want to know the URL for. The values are described in UIControlState.
 */
- (nullable NSURL *)sdBu_backgroundImageURLForState:(UIControlState)state;
/**
 * Set the button `backgroundImage` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url   The url for the image.
 * @param state The state that uses the specified title. The values are described in UIControlState.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state NS_REFINED_FOR_SWIFT;
/**
 * Set the button `backgroundImage` with an `url` and a placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param state       The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @see sdBu_setImageWithURL:placeholderImage:options:
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                    placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;
/**
 * Set the button `backgroundImage` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param state       The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                    placeholderImage:(nullable UIImage *)placeholder
                             options:(BU_SDWebImageOptions)options NS_REFINED_FOR_SWIFT;
/**
 * Set the button `backgroundImage` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param state       The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                    placeholderImage:(nullable UIImage *)placeholder
                             options:(BU_SDWebImageOptions)options
                             context:(nullable SDWebImageContext *)context;
/**
 * Set the button `backgroundImage` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param state          The state that uses the specified title. The values are described in UIControlState.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                           completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `backgroundImage` with an `url`, placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param state          The state that uses the specified title. The values are described in UIControlState.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                    placeholderImage:(nullable UIImage *)placeholder
                           completed:(nullable BU_SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;
/**
 * Set the button `backgroundImage` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                    placeholderImage:(nullable UIImage *)placeholder
                             options:(BU_SDWebImageOptions)options
                           completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `backgroundImage` with an `url`, placeholder and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                    placeholderImage:(nullable UIImage *)placeholder
                             options:(BU_SDWebImageOptions)options
                            progress:(nullable SDImageLoaderProgressBlock)progressBlock
                           completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the button `backgroundImage` with an `url`, placeholder, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setBackgroundImageWithURL:(nullable NSURL *)url
                            forState:(UIControlState)state
                    placeholderImage:(nullable UIImage *)placeholder
                             options:(BU_SDWebImageOptions)options
                             context:(nullable SDWebImageContext *)context
                            progress:(nullable SDImageLoaderProgressBlock)progressBlock
                           completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
#pragma mark - Cancel
/**
 * Cancel the current image download
 */
- (void)sdBu_cancelImageLoadForState:(UIControlState)state;
/**
 * Cancel the current backgroundImage download
 */
- (void)sdBu_cancelBackgroundImageLoadForState:(UIControlState)state;
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIColor+BUHexString.h
New file
@@ -0,0 +1,18 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
@interface UIColor (BUHexString)
/**
 Convenience way to get hex string from color. The output should always be 32-bit RGBA hex string like `#00000000`.
 */
@property (nonatomic, copy, readonly, nonnull) NSString *sdBu_hexString;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIColor+BUTheme.h
New file
@@ -0,0 +1,22 @@
//
//  UIColor+BUTheme.h
//  BUAdSDK
//
//  Created by carl on 2017/8/15.
//  Copyright Â© 2017å¹´ bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIColor (BU_Theme)
+ (UIColor *)bu_colorWithHEX:(NSUInteger)hex;
+ (UIColor *)bu_colorWithHEX:(NSUInteger)hex alpha:(CGFloat)alpha;
+ (UIColor *)bu_colorWithHexString:(NSString *)color;
+ (UIColor *)bu_colorWithHexString:(NSString *)color alpha:(CGFloat)alpha;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUForceDecode.h
New file
@@ -0,0 +1,46 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
/**
 UIImage category about force decode feature (avoid Image/IO's lazy decoding during rendering behavior).
 */
@interface UIImage (BUForceDecode)
/**
 A bool value indicating whether the image has already been decoded. This can help to avoid extra force decode.
 */
@property (nonatomic, assign) BOOL sdBu_isDecoded;
/**
 Decode the provided image. This is useful if you want to force decode the image before rendering to improve performance.
 @param image The image to be decoded
 @return The decoded image
 */
+ (nullable UIImage *)sdBu_decodedImageWithImage:(nullable UIImage *)image;
/**
 Decode and scale down the provided image
 @param image The image to be decoded
 @return The decoded and scaled down image
 */
+ (nullable UIImage *)sdBu_decodedAndScaledDownImageWithImage:(nullable UIImage *)image;
/**
 Decode and scale down the provided image with limit bytes
 @param image The image to be decoded
 @param bytes The limit bytes size. Provide 0 to use the build-in limit.
 @return The decoded and scaled down image
 */
+ (nullable UIImage *)sdBu_decodedAndScaledDownImageWithImage:(nullable UIImage *)image limitBytes:(NSUInteger)bytes;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUGIF.h
New file
@@ -0,0 +1,26 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 * (c) Laurin Brandner
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
/**
 This category is just use as a convenience method. For more detail control, use methods in `UIImage+BUMultiFormat.h` or directlly use `SDImageCoder`.
 */
@interface UIImage (BUGIF)
/**
 Creates an animated UIImage from an NSData.
 This will create animated image if the data is Animated GIF. And will create a static image is the data is Static GIF.
 @param data The GIF data
 @return The created image
 */
+ (nullable UIImage *)sdBu_imageWithGIFData:(nullable NSData *)data;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUMemoryCacheCost.h
New file
@@ -0,0 +1,27 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
/**
 UIImage category for memory cache cost.
 */
@interface UIImage (BUMemoryCacheCost)
/**
 The memory cache cost for specify image used by image cache. The cost function is the bytes size held in memory.
 If you set some associated object to `UIImage`, you can set the custom value to indicate the memory cost.
 For `UIImage`, this method return the single frame bytes size when `image.images` is nil for static image. Retuen full frame bytes size when `image.images` is not nil for animated image.
 For `NSImage`, this method return the single frame bytes size because `NSImage` does not store all frames in memory.
 @note Note that because of the limitations of category this property can get out of sync if you create another instance with CGImage or other methods.
 @note For custom animated class conforms to `BU_SDAnimatedImage`, you can override this getter method in your subclass to return a more proper value instead, which representing the current frame's total bytes.
 */
@property (assign, nonatomic) NSUInteger sdBu_memoryCost;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUMetadata.h
New file
@@ -0,0 +1,49 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import "NSData+BUImageContentType.h"
/**
 UIImage category for image metadata, including animation, loop count, format, incremental, etc.
 */
@interface UIImage (BUMetadata)
/**
 * UIKit:
 * For static image format, this value is always 0.
 * For animated image format, 0 means infinite looping.
 * Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods.
 * AppKit:
 * NSImage currently only support animated via GIF imageRep unlike UIImage.
 * The getter of this property will get the loop count from GIF imageRep
 * The setter of this property will set the loop count from GIF imageRep
 */
@property (nonatomic, assign) NSUInteger sdBu_imageLoopCount;
/**
 * UIKit:
 * Check the `images` array property
 * AppKit:
 * NSImage currently only support animated via GIF imageRep unlike UIImage. It will check the imageRep's frame count.
 */
@property (nonatomic, assign, readonly) BOOL sdBu_isAnimated;
/**
 * The image format represent the original compressed image data format.
 * If you don't manually specify a format, this information is retrieve from CGImage using `CGImageGetUTType`, which may return nil for non-CG based image. At this time it will return `BU_SDImageFormatUndefined` as default value.
 * @note Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods.
 */
@property (nonatomic, assign) BU_SDImageFormat sdBu_imageFormat;
/**
 A bool value indicating whether the image is during incremental decoding and may not contains full pixels.
 */
@property (nonatomic, assign) BOOL sdBu_isIncremental;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUMultiFormat.h
New file
@@ -0,0 +1,79 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import "NSData+BUImageContentType.h"
/**
 UIImage category for convenient image format decoding/encoding.
 */
@interface UIImage (BUMultiFormat)
#pragma mark - Decode
/**
 Create and decode a image with the specify image data
 @param data The image data
 @return The created image
 */
+ (nullable UIImage *)sdBu_imageWithData:(nullable NSData *)data;
/**
 Create and decode a image with the specify image data and scale
 @param data The image data
 @param scale The image scale factor. Should be greater than or equal to 1.0.
 @return The created image
 */
+ (nullable UIImage *)sdBu_imageWithData:(nullable NSData *)data scale:(CGFloat)scale;
/**
 Create and decode a image with the specify image data and scale, allow specify animate/static control
 @param data The image data
 @param scale The image scale factor. Should be greater than or equal to 1.0.
 @param firstFrameOnly Even if the image data is animated image format, decode the first frame only as static image.
 @return The created image
 */
+ (nullable UIImage *)sdBu_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly;
#pragma mark - Encode
/**
 Encode the current image to the data, the image format is unspecified
 @return The encoded data. If can't encode, return nil
 */
- (nullable NSData *)sdBu_imageData;
/**
 Encode the current image to data with the specify image format
 @param imageFormat The specify image format
 @return The encoded data. If can't encode, return nil
 */
- (nullable NSData *)sdBu_imageDataAsFormat:(BU_SDImageFormat)imageFormat NS_SWIFT_NAME(sdBu_imageData(as:));
/**
 Encode the current image to data with the specify image format and compression quality
 @param imageFormat The specify image format
 @param compressionQuality The quality of the resulting image data. Value between 0.0-1.0. Some coders may not support compression quality.
 @return The encoded data. If can't encode, return nil
 */
- (nullable NSData *)sdBu_imageDataAsFormat:(BU_SDImageFormat)imageFormat compressionQuality:(double)compressionQuality NS_SWIFT_NAME(sdBu_imageData(as:compressionQuality:));
/**
 Encode the current image to data with the specify image format and compression quality, allow specify animate/static control
 @param imageFormat The specify image format
 @param compressionQuality The quality of the resulting image data. Value between 0.0-1.0. Some coders may not support compression quality.
 @param firstFrameOnly Even if the image is animated image, encode the first frame only as static image.
 @return The encoded data. If can't encode, return nil
 */
- (nullable NSData *)sdBu_imageDataAsFormat:(BU_SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly NS_SWIFT_NAME(sdBu_imageData(as:compressionQuality:firstFrameOnly:));
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImage+BUTransform.h
New file
@@ -0,0 +1,146 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
typedef NS_ENUM(NSUInteger, BU_SDImageScaleMode) {
    BU_SDImageScaleModeFill = 0,
    BU_SDImageScaleModeAspectFit = 1,
    BU_SDImageScaleModeAspectFill = 2
};
#if SD_UIKIT || SD_WATCH
typedef UIRectCorner BU_SDRectCorner;
#else
typedef NS_OPTIONS(NSUInteger, BU_SDRectCorner) {
    BU_SDRectCornerTopLeft     = 1 << 0,
    BU_SDRectCornerTopRight    = 1 << 1,
    BU_SDRectCornerBottomLeft  = 1 << 2,
    BU_SDRectCornerBottomRight = 1 << 3,
    BU_SDRectCornerAllCorners  = ~0UL
};
#endif
/**
 Provide some commen method for `UIImage`.
 Image process is based on Core Graphics and vImage.
 */
@interface UIImage (BUTransform)
#pragma mark - Image Geometry
/**
 Returns a new image which is resized from this image.
 You can specify a larger or smaller size than the image size. The image content will be changed with the scale mode.
 @param size        The new size to be resized, values should be positive.
 @param scaleMode   The scale mode for image content.
 @return The new image with the given size.
 */
- (nullable UIImage *)sdBu_resizedImageWithSize:(CGSize)size scaleMode:(BU_SDImageScaleMode)scaleMode;
/**
 Returns a new image which is cropped from this image.
 @param rect     Image's inner rect.
 @return         The new image with the cropping rect.
 */
- (nullable UIImage *)sdBu_croppedImageWithRect:(CGRect)rect;
/**
 Rounds a new image with a given corner radius and corners.
 @param cornerRadius The radius of each corner oval. Values larger than half the
 rectangle's width or height are clamped appropriately to
 half the width or height.
 @param corners      A bitmask value that identifies the corners that you want
 rounded. You can use this parameter to round only a subset
 of the corners of the rectangle.
 @param borderWidth  The inset border line width. Values larger than half the rectangle's
 width or height are clamped appropriately to half the width
 or height.
 @param borderColor  The border stroke color. nil means clear color.
 @return The new image with the round corner.
 */
- (nullable UIImage *)sdBu_roundedCornerImageWithRadius:(CGFloat)cornerRadius
                                              corners:(BU_SDRectCorner)corners
                                          borderWidth:(CGFloat)borderWidth
                                          borderColor:(nullable UIColor *)borderColor;
/**
 Returns a new rotated image (relative to the center).
 @param angle     Rotated radians in counterclockwise.⟲
 @param fitSize   YES: new image's size is extend to fit all content.
                  NO: image's size will not change, content may be clipped.
 @return The new image with the rotation.
 */
- (nullable UIImage *)sdBu_rotatedImageWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize;
/**
 Returns a new horizontally(vertically) flipped image.
 @param horizontal YES to flip the image horizontally. â‡‹
 @param vertical YES to flip the image vertically. â¥¯
 @return The new image with the flipping.
 */
- (nullable UIImage *)sdBu_flippedImageWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical;
#pragma mark - Image Blending
/**
 Return a tinted image with the given color. This actually use alpha blending of current image and the tint color.
 @param tintColor  The tint color.
 @return The new image with the tint color.
 */
- (nullable UIImage *)sdBu_tintedImageWithColor:(nonnull UIColor *)tintColor;
/**
 Return the pixel color at specify position. The point is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based.
 @note The point's x/y should not be smaller than 0, or greater than or equal to width/height.
 @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself.
 @param point The position of pixel
 @return The color for specify pixel, or nil if any error occur
 */
- (nullable UIColor *)sdBu_colorAtPoint:(CGPoint)point;
/**
 Return the pixel color array with specify rectangle. The rect is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based.
 @note The rect's width/height should not be smaller than or equal to 0. The minX/minY should not be smaller than 0. The maxX/maxY should not be greater than width/height. Attention this limit is different from `sdBu_colorAtPoint:` (point: (0, 0) like rect: (0, 0, 1, 1))
 @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself.
 @param rect The rectangle of pixels
 @return The color array for specify pixels, or nil if any error occur
 */
- (nullable NSArray<UIColor *> *)sdBu_colorsWithRect:(CGRect)rect;
#pragma mark - Image Effect
/**
 Return a new image applied a blur effect.
 @param blurRadius     The radius of the blur in points, 0 means no blur effect.
 @return               The new image with blur effect, or nil if an error occurs (e.g. no enough memory).
 */
- (nullable UIImage *)sdBu_blurredImageWithRadius:(CGFloat)blurRadius;
#if SD_UIKIT || SD_MAC
/**
 Return a new image applied a CIFilter.
 @param filter The CIFilter to be applied to the image.
 @return The new image with the CIFilter, or nil if an error occurs (e.g. no
 enough memory).
 */
- (nullable UIImage *)sdBu_filteredImageWithFilter:(nonnull CIFilter *)filter;
#endif
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImageView+BUHighlightedWebCache.h
New file
@@ -0,0 +1,129 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#if SD_UIKIT
#import "BU_SDWebImageManager.h"
/**
 * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state.
 */
@interface UIImageView (BUHighlightedWebCache)
/**
 * Set the imageView `highlightedImage` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url The url for the image.
 */
- (void)sdBu_setHighlightedImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;
/**
 * Set the imageView `highlightedImage` with an `url` and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url     The url for the image.
 * @param options The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 */
- (void)sdBu_setHighlightedImageWithURL:(nullable NSURL *)url
                              options:(BU_SDWebImageOptions)options NS_REFINED_FOR_SWIFT;
/**
 * Set the imageView `highlightedImage` with an `url`, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url     The url for the image.
 * @param options The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 */
- (void)sdBu_setHighlightedImageWithURL:(nullable NSURL *)url
                              options:(BU_SDWebImageOptions)options
                              context:(nullable SDWebImageContext *)context;
/**
 * Set the imageView `highlightedImage` with an `url`.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setHighlightedImageWithURL:(nullable NSURL *)url
                            completed:(nullable BU_SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;
/**
 * Set the imageView `highlightedImage` with an `url` and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setHighlightedImageWithURL:(nullable NSURL *)url
                              options:(BU_SDWebImageOptions)options
                            completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the imageView `highlightedImage` with an `url` and custom options.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setHighlightedImageWithURL:(nullable NSURL *)url
                              options:(BU_SDWebImageOptions)options
                             progress:(nullable SDImageLoaderProgressBlock)progressBlock
                            completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
/**
 * Set the imageView `highlightedImage` with an `url`, custom options and context.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sdBu_setHighlightedImageWithURL:(nullable NSURL *)url
                              options:(BU_SDWebImageOptions)options
                              context:(nullable SDWebImageContext *)context
                             progress:(nullable SDImageLoaderProgressBlock)progressBlock
                            completed:(nullable BU_SDExternalCompletionBlock)completedBlock;
@end
#endif
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImageView+BUWebCache.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIImageView+BU_ZFCache.h
New file
@@ -0,0 +1,127 @@
//
//  UIImageView+ZFCache.h
//  Player
//
// 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>
typedef void (^BU_ZFDownLoadDataCallBack)(NSData *data, NSError *error);
typedef void (^BU_ZFDownloadProgressBlock)(unsigned long long total, unsigned long long current);
@interface BU_ZFImageDownloader : NSObject<NSURLSessionDownloadDelegate>
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
@property (nonatomic, assign) unsigned long long totalLength;
@property (nonatomic, assign) unsigned long long currentLength;
@property (nonatomic, copy) BU_ZFDownloadProgressBlock progressBlock;
@property (nonatomic, copy) BU_ZFDownLoadDataCallBack callbackOnFinished;
- (void)startDownloadImageWithUrl:(NSString *)url
                         progress:(BU_ZFDownloadProgressBlock)progress
                         finished:(BU_ZFDownLoadDataCallBack)finished;
@end
typedef void (^BU_ZFImageBlock)(UIImage *image);
@interface UIImageView (BU_ZFCache)
/**
 *  Get/Set the callback block when download the image finished.
 *
 *  param image The image object from network or from disk.
 */
@property (nonatomic, copy) BU_ZFImageBlock bu_completion;
/**
 *  Image downloader
 */
@property (nonatomic, strong) BU_ZFImageDownloader *bu_imageDownloader;
/**
 *    Specify the URL to download images fails, the number of retries, the default is 2
 */
@property (nonatomic, assign) NSUInteger bu_attemptToReloadTimesForFailedURL;
/**
 *    Will automatically download to cutting for UIImageView size of image.The default value is NO.
 *  If set to YES, then the download after a successful store only after cutting the image
 */
@property (nonatomic, assign) BOOL bu_shouldAutoClipImageToViewSize;
/**
 * Set the imageView `image` with an `url` and a placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholderImageName The image name to be set initially, until the image request finishes.
 */
- (void)setBUImageWithURLString:(NSString *)url placeholderImageName:(NSString *)placeholderImageName;
/**
 * Set the imageView `image` with an `url` and a placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url         The url for the image.
 * @param placeholderImage The image to be set initially, until the image request finishes.
 */
- (void)setBUImageWithURLString:(NSString *)url placeholder:(UIImage *)placeholderImage;
/**
 * Set the imageView `image` with an `url`, placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholderImage    The image to be set initially, until the image request finishes.
 * @param completion     A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)setBUImageWithURLString:(NSString *)url
                  placeholder:(UIImage *)placeholderImage
                   completion:(void (^)(UIImage *image))completion;
/**
 * Set the imageView `image` with an `url`, placeholder.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholderImageName    The image name to be set initially, until the image request finishes.
 * @param completion     A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)setBUImageWithURLString:(NSString *)url
         placeholderImageName:(NSString *)placeholderImageName
                   completion:(void (^)(UIImage *image))completion;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIView+BUAdditions.h
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIView+BUWebCache.h
New file
@@ -0,0 +1,101 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import "BU_SDWebImageDefine.h"
#import "BU_SDWebImageManager.h"
#import "BU_SDWebImageTransition.h"
#import "BU_SDWebImageIndicator.h"
/**
 The value specify that the image progress unit count cannot be determined because the progressBlock is not been called.
 */
FOUNDATION_EXPORT const int64_t BU_SDWebImageProgressUnitCountUnknown; /* 1LL */
typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData, BU_SDImageCacheType cacheType, NSURL * _Nullable imageURL);
/**
 Integrates SDWebImage async downloading and caching of remote images with UIView subclass.
 */
@interface UIView (BUWebCache)
/**
 * Get the current image URL.
 *
 * @note Note that because of the limitations of categories this property can get out of sync if you use setImage: directly.
 */
@property (nonatomic, strong, readonly, nullable) NSURL *sdBu_imageURL;
/**
 * The current image loading progress associated to the view. The unit count is the received size and excepted size of download.
 * The `totalUnitCount` and `completedUnitCount` will be reset to 0 after a new image loading start (change from current queue). And they will be set to `BU_SDWebImageProgressUnitCountUnknown` if the progressBlock not been called but the image loading success to mark the progress finished (change from main queue).
 * @note You can use Key-Value Observing on the progress, but you should take care that the change to progress is from a background queue during download(the same as progressBlock). If you want to using KVO and update the UI, make sure to dispatch on the main queue. And it's recommand to use some KVO libs like KVOController because it's more safe and easy to use.
 * @note The getter will create a progress instance if the value is nil. But by default, we don't create one. If you need to use Key-Value Observing, you must trigger the getter or set a custom progresss instance before the loading start. The default value is nil.
 * @note Note that because of the limitations of categories this property can get out of sync if you update the progress directly.
 */
@property (nonatomic, strong, null_resettable) NSProgress *sdBu_imageProgress;
/**
 * Set the imageView `image` with an `url` and optionally a placeholder image.
 *
 * The download is asynchronous and cached.
 *
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values.
 * @param context        A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param setImageBlock  Block used for custom set image code. If not provide, use the built-in set image code (supports `UIImageView/NSImageView` and `UIButton/NSButton` currently)
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed.
 *   This block has no return value and takes the requested UIImage as first parameter and the NSData representation as second parameter.
 *   In case of error the image parameter is nil and the third parameter may contain an NSError.
 *
 *   The forth parameter is an `BU_SDImageCacheType` enum indicating if the image was retrieved from the local cache
 *   or from the memory cache or from the network.
 *
 *   The fith parameter normally is always YES. However, if you provide SDWebImageAvoidAutoSetImage with SDWebImageProgressiveLoad options to enable progressive downloading and set the image yourself. This block is thus called repeatedly with a partial image. When image is fully downloaded, the
 *   block is called a last time with the full image and the last parameter set to YES.
 *
 *   The last parameter is the original image URL
 */
- (void)sdBu_internalSetImageWithURL:(nullable NSURL *)url
                  placeholderImage:(nullable UIImage *)placeholder
                           options:(BU_SDWebImageOptions)options
                           context:(nullable SDWebImageContext *)context
                     setImageBlock:(nullable SDSetImageBlock)setImageBlock
                          progress:(nullable SDImageLoaderProgressBlock)progressBlock
                         completed:(nullable BU_SDInternalCompletionBlock)completedBlock;
/**
 * Cancel the current image load
 */
- (void)sdBu_cancelCurrentImageLoad;
#if SD_UIKIT || SD_MAC
#pragma mark - Image Transition
/**
 The image transition when image load finished. See `SDWebImageTransition`.
 If you specify nil, do not do transition. Defautls to nil.
 */
@property (nonatomic, strong, nullable) BU_SDWebImageTransition *sdBu_imageTransition;
#pragma mark - Image Indicator
/**
 The image indicator during the image loading. If you do not need indicator, specify nil. Defaults to nil
 The setter will remove the old indicator view and add new indicator view to current view's subview.
 @note Because this is UI related, you should access only from the main queue.
 */
@property (nonatomic, strong, nullable) id<SDWebImageIndicator> sdBu_imageIndicator;
#endif
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIView+BUWebCacheOperation.h
New file
@@ -0,0 +1,48 @@
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
#import "BU_SDWebImageCompat.h"
#import "BU_SDWebImageOperation.h"
/**
 These methods are used to support canceling for UIView image loading, it's designed to be used internal but not external.
 All the stored operations are weak, so it will be dalloced after image loading finished. If you need to store operations, use your own class to keep a strong reference for them.
 */
@interface UIView (BUWebCacheOperation)
/**
 *  Get the image load operation for key
 *
 *  @param key key for identifying the operations
 *  @return the image load operation
 */
- (nullable id<BU_SDWebImageOperation>)sdBu_imageLoadOperationForKey:(nullable NSString *)key;
/**
 *  Set the image load operation (storage in a UIView based weak map table)
 *
 *  @param operation the operation
 *  @param key       key for storing the operation
 */
- (void)sdBu_setImageLoadOperation:(nullable id<BU_SDWebImageOperation>)operation forKey:(nullable NSString *)key;
/**
 *  Cancel all operations for the current UIView and key
 *
 *  @param key key for identifying the operations
 */
- (void)sdBu_cancelImageLoadOperationWithKey:(nullable NSString *)key;
/**
 *  Just remove the operations corresponding to the current UIView and key without cancelling them
 *
 *  @param key key for identifying the operations
 */
- (void)sdBu_removeImageLoadOperationWithKey:(nullable NSString *)key;
@end
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIViewController+BUUtilities.h
New file
@@ -0,0 +1,41 @@
//
//  UIViewController+BUUtilities.h
//  BUAdSDK
//
//  Created by Siwant on 2019/4/11.
//  Copyright Â© 2019 bytedance. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIViewController (BUUtilities)
- (void)bu_safelyPresentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion;
// èŽ·å–å½“å‰æœ€åŽä¸€ä¸ªè¢«present出的VC,如果没有返回self
- (UIViewController *)bu_presentingViewController;
// èŽ·å–å½“å‰æœ€åŽä¸€ä¸ªè¢«present出的VC,如果没有返回window的最上的topVC
+ (UIViewController *)bu_presentingViewController;
// èŽ·å–å¹¿ä¹‰mainWindow的rootViewController
+ (nullable UIViewController*)bu_mainWindowRootViewController;
// èŽ·å–æŒ‡å®šUIResponder的链下游第一个ViewController对象
+ (nullable UIViewController*)bu_nextViewControllerFor:(UIResponder* _Nullable)responder;
// èŽ·å–æŒ‡å®šUIResponder的链下游第一个UINavigationController对象
+ (nullable UINavigationController*)bu_nextNavigationControllerFor:(UIResponder* _Nullable)responder;
/** æŸ¥æ‰¾å½“前显示的ViewController*/
+ (UIViewController *)bu_topViewController;
+ (UIViewController *)bu_recursiveFindCurrentShowViewControllerFromViewController:(UIViewController *)fromVC;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/A/Headers/UIWindow+BUUtilities.h
New file
@@ -0,0 +1,21 @@
//
//  UIWindow+BUUtilities.h
//  BUFoundation
//
//  Created by Rush.D.Xzj on 2020/12/17.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIWindow (BUUtilities)
// èŽ·å–å½“å‰åº”ç”¨çš„å¹¿ä¹‰mainWindow
+ (nullable UIWindow *)bu_mainWindow;
// å¹¿ä¹‰mainWindow的大小(兼容iOS7)
+ (CGSize)bu_windowSize;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/CSJ/BUFoundation.framework/Versions/Current
New file
@@ -0,0 +1 @@
A
BuWanVideo2.0/Common.h
@@ -17,6 +17,7 @@
#import "YYModel.h"
#import "Share.h"
#import "YYWebImage.h"
#import <SDAutoLayout/SDAutoLayout.h>
#import "HXEasyCustomShareView.h"//分享界面
@@ -125,6 +126,8 @@
// 2.用代码形式代码
#define UIColorFromRGBValue(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
#define UICOLOR_FROM_RGB(rgbValue,trans) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:trans]
// 3.屏幕宽高
#define KScreenHp [[UIScreen mainScreen] bounds].size.height*1.0 // å±å¹•高度
#define KScreenWp [[UIScreen mainScreen] bounds].size.width*1.0 // å±å¹•宽度
@@ -133,10 +136,22 @@
#define KScreenW MIN(KScreenHp,KScreenWp)// å±å¹•宽度
// 4.导航栏/工具栏/状态栏高度
#define IS_IPHONE_X ({\
BOOL isBangsScreen = NO; \
if (@available(iOS 11.0, *)) { \
UIWindow *window = [[UIApplication sharedApplication].windows firstObject]; \
isBangsScreen = window.safeAreaInsets.bottom > 0; \
} \
isBangsScreen; \
})
#define kNavigationBarH 64
#define kToolBarH 30
#define kStatusBarH 20
#define IS_IPHONE_X (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)812) < DBL_EPSILON)
#define kStatusBarH [[UIApplication sharedApplication] statusBarFrame].size.height
#define ALNavBarH 44
#define ALTabBar_H (CGFloat)(IS_IPHONE_X?(49.0 + 34.0):(49.0))
// 5.全局颜色
//#define kGlobalMainColor YTHColor(48, 39, 37)//应用的主色调
BuWanVideo2.0/Info.plist
@@ -23,14 +23,6 @@
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>iqiyi</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>iqiyi</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLIconFile</key>
@@ -143,6 +135,23 @@
    <string>同意布丸影视大全定位吗?</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>同意布丸影视大全使用相册吗?</string>
    <key>NSUserTrackingUsageDescription</key>
    <string>布丸影视大全需要您的同意,向您投放个性化广告</string>
    <key>SKAdNetworkItems</key>
    <array>
        <dict>
            <key>SKAdNetworkIdentifier</key>
            <string>22mmun2rn5.skadnetwork</string>
        </dict>
        <dict>
            <key>SKAdNetworkIdentifier</key>
            <string>x2jnk7ly8j.skadnetwork</string>
        </dict>
        <dict>
            <key>SKAdNetworkIdentifier</key>
            <string>238da6jt44.skadnetwork</string>
        </dict>
    </array>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
BuWanVideo2.0/JSAPI.h
New file
@@ -0,0 +1,26 @@
//
//  JSAPI.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
NS_ASSUME_NONNULL_BEGIN
@protocol JSAPIDelegate <JSExport>
- (void)tryPlayFinish;
@end
@interface JSAPI : NSObject <JSAPIDelegate>
@property (nonatomic, weak) id<JSAPIDelegate>delegate;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/JSAPI.m
New file
@@ -0,0 +1,17 @@
//
//  JSAPI.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "JSAPI.h"
@implementation JSAPI
- (void)tryPlayFinish {
}
@end
BuWanVideo2.0/LeftViewController.h
@@ -6,8 +6,8 @@
//  Copyright Â© 2016å¹´ com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "MainBaseController.h"
@interface LeftViewController : BaseViewController
@interface LeftViewController : MainBaseController
@end
BuWanVideo2.0/LeftViewController.m
@@ -36,6 +36,7 @@
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *MarkToMain;//这个的值为宽度的四分之一
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *LeftbackgroundH;//根据图片比例设置高
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageBGTopSpace;
@property (nonatomic, assign) BOOL userOnLine;//用户是否登录
@@ -47,17 +48,30 @@
    self = [super init];
    if (self) {
        self.title = @"我的";
        UITabBarItem *item = [[UITabBarItem alloc]initWithTitle:self.title image:[UIImage imageNamed:@"User-拷贝"] selectedImage:[UIImage imageNamed:@"User"]];
        item.titlePositionAdjustment = UIOffsetMake(0, -5);
        self.tabBarItem = item;
//        UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:self.title image:[UIImage imageNamed:@"User-拷贝"] selectedImage:[UIImage imageNamed:@"User"]];
//        //item.titlePositionAdjustment = UIOffsetMake(0, -5);
//        self.tabBarItem = item;
    }
    return self;
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    self.navigationController.navigationBar.translucent = NO;
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:animated];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor=[UIColor whiteColor];
    
    self.imageBGTopSpace.constant = kStatusBarH + ALNavBarH;
    //确定视图的位置
    self.MarkToMain.constant=0;
    self.LeftbackgroundH.constant=141;
BuWanVideo2.0/LeftViewController.xib
@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
@@ -19,6 +16,7 @@
                <outlet property="LeftbackgroundH" destination="UPy-jU-CfA" id="C4I-aH-Coc"/>
                <outlet property="MarkToMain" destination="dki-s9-h4v" id="2mG-fB-ENQ"/>
                <outlet property="headerImageview" destination="FSC-YP-ZG2" id="ikf-pd-uqW"/>
                <outlet property="imageBGTopSpace" destination="U1o-hc-1Qp" id="Tm2-RH-5Ie"/>
                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
            </connections>
        </placeholder>
@@ -49,7 +47,7 @@
                    <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                    <color key="sectionIndexBackgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                </tableView>
                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vJq-5r-coT">
                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vJq-5r-coT">
                    <rect key="frame" x="85" y="100" width="187.5" height="30"/>
                    <constraints>
                        <constraint firstAttribute="height" constant="30" id="cJu-rD-mvM"/>
@@ -84,7 +82,7 @@
            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
            <point key="canvasLocation" x="547" y="274"/>
        </imageView>
        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="ZfB-TX-ZCe">
        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" id="ZfB-TX-ZCe">
            <rect key="frame" x="0.0" y="0.0" width="46" height="30"/>
            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
            <state key="normal" title="Button"/>
BuWanVideo2.0/Nethader.h
@@ -57,7 +57,7 @@
#define GetHomeAd  @"getHomeAd"
#pragma mark æŽ¨èåˆ†ç±»
#define GetHomeType @"getHomeType"
#define GetHomeType @"getHomeTypeNew"
#pragma mark æ›´å¤šè§†é¢‘
#define GetMoreVideo @"getMoreVideo"
BuWanVideo2.0/PPTVBottomVIpVIew.h
New file
@@ -0,0 +1,17 @@
//
//  PPTVBottomVIpVIew.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface PPTVBottomVIpVIew : UIView
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/PPTVBottomVIpVIew.m
New file
@@ -0,0 +1,196 @@
//
//  PPTVBottomVIpVIew.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "PPTVBottomVIpVIew.h"
@interface PPTVBottomVIpVIew ()
@property (nonatomic, nullable, strong) UIView *viewYellow;
@property (nonatomic, nullable, strong) UILabel *labelStart;
@property (nonatomic, nullable, strong) UILabel *labelEnd;
@property (nonatomic, nullable, strong) UILabel *labelBL;
@end
@implementation PPTVBottomVIpVIew
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = UICOLOR_FROM_RGB(0x000000, 0.5);
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    UIView *viewGB = [[UIView alloc] init];
    viewGB.backgroundColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0];
    viewGB.layer.borderWidth = 0.5;
    viewGB.layer.borderColor = [UIColor colorWithRed:153/255.0 green:153/255.0 blue:153/255.0 alpha:1.0].CGColor;
    viewGB.layer.cornerRadius = 20;
    [self addSubview:viewGB];
    viewGB.sd_layout.leftSpaceToView(self, 0).bottomSpaceToView(self, 0).rightSpaceToView(self, 0).heightIs(200 + (KIsiPhoneX?20:0));
    UIButton *buttonRight = [UIButton buttonWithType:UIButtonTypeCustom];
    [buttonRight setImage:[UIImage imageNamed:@"pptv_delete"] forState:UIControlStateNormal];
    [buttonRight addTarget:self action:@selector(onDelete) forControlEvents:UIControlEventTouchUpInside];
    [viewGB addSubview:buttonRight];
    buttonRight.sd_layout.rightSpaceToView(viewGB, 10).topSpaceToView(viewGB, 10).widthIs(20).heightIs(20);
    UILabel *labelTitle = [[UILabel alloc] init];
    labelTitle.textColor = UIColorFromRGBValue(0x010101);
    labelTitle.text = @"购买详情";
    labelTitle.textAlignment = NSTextAlignmentCenter;
    labelTitle.font = [UIFont systemFontOfSize:18];
    [viewGB addSubview:labelTitle];
    labelTitle.sd_layout.topSpaceToView(viewGB, 18).centerXEqualToView(viewGB).widthIs(100).heightIs(18);
    UIView *line = [[UIView alloc] init];
    line.backgroundColor = [UIColor colorWithRed:205/255.0 green:205/255.0 blue:205/255.0 alpha:1.0];
    [viewGB addSubview:line];
    line.sd_layout.leftSpaceToView(viewGB, 20).rightSpaceToView(viewGB, 20).topSpaceToView(viewGB, 57).heightIs(0.5);
    UILabel *labelName = [[UILabel alloc] init];
    labelName.font = [UIFont systemFontOfSize:12];
    labelName.textAlignment = NSTextAlignmentLeft;
    labelName.textColor = UIColorFromRGBValue(0x010101);
    [viewGB addSubview:labelName];
    NSString *str1 = @"片名";
    long len1= [str1 length];
    NSString * str2 = @"《流浪地球》";
    long len2 = [str2 length];
    NSString * str = [NSString stringWithFormat:@"%@%@",str1, str2];
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
    [attributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:18] range:NSMakeRange(len1, len2)];
    labelName.attributedText = attributedString;
    labelName.isAttributedContent = YES;
    labelName.sd_layout.leftSpaceToView(viewGB, 10).topSpaceToView(line , 20).rightSpaceToView(viewGB, 110).heightIs(18);
    // æ¥æº
    UILabel *labelSource = [[UILabel alloc] init];
    labelSource.font = [UIFont systemFontOfSize:13];
    labelSource.textColor = UIColorFromRGBValue(0x999999);
    labelSource.text = @"来源:PP视频";
    labelSource.textAlignment = NSTextAlignmentRight;
    [viewGB addSubview:labelSource];
    labelSource.sd_layout.rightSpaceToView(viewGB, 20).bottomEqualToView(labelName).widthIs(85).heightIs(13);
    // ä¼šå‘˜èƒŒæ™¯
    self.viewYellow = [[UIView alloc] init];
    // self.viewYellow.backgroundColor = [UIColor colorWithRed:240/255.0 green:96/255.0 blue:0/255.0 alpha:1.0];
    self.viewYellow.frame = CGRectMake(9, 116, KScreenW - 18, 59);
    [viewGB addSubview:self.viewYellow];
    self.viewYellow.layer.masksToBounds = YES;
    self.viewYellow.layer.cornerRadius = 6;
    CAGradientLayer *layer = [CAGradientLayer layer];
    layer.startPoint = CGPointMake(0, 0);//(0,0)表示从左上角开始变化。默认值是(0.5,0.0)表示从x轴为中间,y为顶端的开始变化
    layer.endPoint = CGPointMake(1, 1);//(1,1)表示到右下角变化结束。默认值是(0.5,1.0)  è¡¨ç¤ºä»Žx轴为中间,y为低端的结束变化
    layer.colors = [NSArray arrayWithObjects:UIColorFromRGBValue(0xF7EDD7).CGColor, UIColorFromRGBValue(0xE9CE93).CGColor, nil];
    layer.locations = @[@0.0f, @1.0f];//渐变颜色的区间分布,locations的数组长度和color一致,这个值一般不用管它,默认是nil,会平均分布
    layer.frame = self.viewYellow.layer.bounds;
    [self.viewYellow.layer insertSublayer:layer atIndex:0];
    UIImageView *imageViewVip = [[UIImageView alloc] init];
    imageViewVip.image = [UIImage imageNamed:@"pptv_vip_icon"];
    [self.viewYellow addSubview:imageViewVip];
    imageViewVip.sd_layout.leftSpaceToView(self.viewYellow, 17).centerYEqualToView(self.viewYellow).widthIs(24).heightIs(25);
    UILabel *labelVipTitle = [[UILabel alloc] init];
    labelVipTitle.text = @"VIP看高清 å…å¹¿å‘Š";
    labelVipTitle.textColor = UIColorFromRGBValue(0x885E24);
    labelVipTitle.font = [UIFont systemFontOfSize:15];
    labelVipTitle.textAlignment = NSTextAlignmentLeft;
    [self.viewYellow addSubview:labelVipTitle];
    labelVipTitle.sd_layout.leftSpaceToView(imageViewVip, 5).topSpaceToView(self.viewYellow, 13).rightSpaceToView(self.viewYellow, 20).heightIs(15);
    UILabel *labelVipContent = [[UILabel alloc] init];
    labelVipContent.text = @"包月、季、年卡";
    labelVipContent.textColor = UIColorFromRGBValue(0x885E24);
    labelVipContent.font = [UIFont systemFontOfSize:11];
    labelVipContent.textAlignment = NSTextAlignmentLeft;
    [self.viewYellow addSubview:labelVipContent];
    labelVipContent.sd_layout.leftSpaceToView(imageViewVip, 5).topSpaceToView(labelVipTitle, 6).rightSpaceToView(self.viewYellow, 20).heightIs(15);
    UIImageView *imageViewArrow = [[UIImageView alloc] init];
    imageViewArrow.image = [UIImage imageNamed:@"pptv_arrow"];
    [self.viewYellow addSubview:imageViewArrow];
    imageViewArrow.sd_layout.rightSpaceToView(self.viewYellow, 12).centerYEqualToView(self.viewYellow).widthIs(8).heightIs(11);
    self.labelEnd = [[UILabel alloc] init];
    self.labelEnd.textColor = UIColorFromRGBValue(0x885E24);
    self.labelEnd.font = [UIFont systemFontOfSize:10];
    self.labelEnd.textAlignment = NSTextAlignmentRight;
    [self.viewYellow addSubview:self.labelEnd];
    NSString *endStr1 = @"Â¥";
    long endLen1= [endStr1 length];
    NSString * endStr2 = @"99";
    long endLen2 = [endStr2 length];
    NSString * strEnd = [NSString stringWithFormat:@"%@%@",endStr1, endStr2];
    NSMutableAttributedString *attributedStringEnd = [[NSMutableAttributedString alloc] initWithString:strEnd];
    [attributedStringEnd addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:18] range:NSMakeRange(endLen1, endLen2)];
    self.labelEnd.attributedText = attributedStringEnd;
    self.labelEnd.isAttributedContent = YES;
    self.labelEnd.sd_layout.rightSpaceToView(imageViewArrow, 5).topSpaceToView(self.viewYellow, 19).autoWidthRatio(0).heightIs(15);
    [self.labelEnd setSingleLineAutoResizeWithMaxWidth:100];
    self.labelBL = [[UILabel alloc] init];
    self.labelBL.text = @"~";
    self.labelBL.textColor = UIColorFromRGBValue(0x885E24);
    self.labelBL.font = [UIFont systemFontOfSize:20];
    self.labelBL.textAlignment = NSTextAlignmentRight;
    [self.viewYellow addSubview:self.labelBL];
    self.labelBL.sd_layout.rightSpaceToView(self.labelEnd, 2).centerYEqualToView(self.viewYellow).autoWidthRatio(0).heightIs(15);
    [self.labelBL setSingleLineAutoResizeWithMaxWidth:100];
    self.labelStart = [[UILabel alloc] init];
    self.labelStart.textColor = UIColorFromRGBValue(0x885E24);
    self.labelStart.font = [UIFont systemFontOfSize:10];
    self.labelStart.textAlignment = NSTextAlignmentRight;
    [self.viewYellow addSubview:self.labelStart];
    NSString *str1Start = @"Â¥";
    long len1Start= [str1Start length];
    NSString * str2Start = @"6";
    long len2Start = [str2Start length];
    NSString * strStart = [NSString stringWithFormat:@"%@%@",str1Start, str2Start];
    NSMutableAttributedString *attributedStringStart = [[NSMutableAttributedString alloc] initWithString:strStart];
    [attributedStringStart addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:19] range:NSMakeRange(len1Start, len2Start)];
    self.labelStart.attributedText = attributedStringStart;
    self.labelStart.isAttributedContent = YES;
    self.labelStart.sd_layout.rightSpaceToView(self.labelBL, 2).topSpaceToView(self.viewYellow, 19).autoWidthRatio(0).heightIs(15);
    [self.labelStart setSingleLineAutoResizeWithMaxWidth:100];
}
- (void)onDelete {
}
@end
BuWanVideo2.0/PPTVController.m
@@ -7,12 +7,23 @@
//
#import "PPTVController.h"
#import "PPTVNavView.h"
#import "PPTVPppView.h"
#import "PPTVBottomVIpVIew.h"
#import <WebKit/WebKit.h>
#import "JSAPI.h"
@interface PPTVController () <WKNavigationDelegate, WKUIDelegate>
@interface PPTVController () <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler, PPTVDelegate>
@property (nonatomic, nullable, strong) WKWebView *webView;
@property (nonatomic, nullable, strong) PPTVNavView *viewPPTVNav;
@property (nonatomic, nullable, strong) PPTVPppView *viewPPTVPop;
@property (nonatomic, nullable, strong) PPTVBottomVIpVIew *viewPPTVVip;
@property (nonatomic, nullable, strong) JSAPI *jsAPI;
@property (nonatomic, nullable, copy) NSString *name;
@property (nonatomic, nullable, copy) NSString *content;
@end
@implementation PPTVController
@@ -22,49 +33,53 @@
    [self loadViewConfig];
}
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"tryPlayFinish"];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:animated];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"tryPlayFinish"];
}
- (void)loadViewConfig {
    [self.view addSubview:self.viewPPTVNav];
    self.viewPPTVNav.name = _parms[@"name"];
    self.viewPPTVNav.content = _parms[@"playUrl"];
    [self.view addSubview:self.webView];
    [self.view addSubview:self.viewPPTVPop];
    [self.view addSubview:self.viewPPTVVip];
    self.jsAPI = [[JSAPI alloc] init];
    
    NSString *url = self.parms[@"playUrl"];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [self.webView loadRequest:request];
    
    UIButton *backbutton = [UIButton buttonWithType:UIButtonTypeCustom];
    [backbutton setImage:[UIImage imageNamed:@"详情页面返回"] forState:UIControlStateNormal];
    [self.view addSubview:backbutton];
    backbutton.frame = CGRectMake(10, KIsiPhoneX?85:65, 40, 30);
    [backbutton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, [[UIApplication sharedApplication] statusBarFrame].size.height+1)];
    view.backgroundColor = [UIColor blackColor];
    [self.view addSubview:view];
    if (@available(iOS 13, *)) {
   
    } else {
        //将要进入全屏
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startFullScreen) name:UIWindowDidResignKeyNotification object:nil];
        //退出全屏
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endFullScreen) name:UIWindowDidBecomeHiddenNotification object:nil];
    }
    //[self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];
        //修改滚动速度
}
-(void)startFullScreen {
    //[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
    UIApplication *application = [UIApplication sharedApplication];
    [application setStatusBarOrientation: UIInterfaceOrientationLandscapeRight];
    application.keyWindow.transform=CGAffineTransformMakeRotation(M_PI/2);
@@ -83,8 +98,56 @@
    }];
}
- (void)back {
//- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//    //网页title
//    if ([keyPath isEqualToString:@"title"]) {
//        if (object == self.webView) {
//            self.viewPPTVNav.name = self.webView.title;
//
//        } else {
//            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
//        }
//
//     } else {
//        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
//     }
//}
#pragma mark --------- PPTVDelegate ---------
- (void)backVc {
    [self.navigationController popViewControllerAnimated:YES];
}
- (void)moreSelect {
    self.viewPPTVPop.hidden = NO;
}
- (void)selectType:(NSString *)type {
    if ([type isEqualToString:@"刷新"]) {
        [self.webView reload];
    } else  if ([type isEqualToString:@"复制链接"]) {
        [self copyUrl];
    }else  if ([type isEqualToString:@"用其他浏览器打开"]) {
        if (@available(iOS 10, *)) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_content?:@""] options:@{} completionHandler:^(BOOL success) {}];
        } else {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_content?:@""]];
        }
    }
}
- (void)copyUrl {
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    pasteboard.string = _content?:@"";
    [SVProgressHUD showWithStatus:@"复制成功"];
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSLog(@"");
}
// é¡µé¢å¼€å§‹åŠ è½½æ—¶è°ƒç”¨
@@ -101,12 +164,23 @@
    [self performSelector:@selector(afterDelay) withObject:nil afterDelay:0.5];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {
    NSString *strRequest = navigationAction.request.URL.absoluteString;
    if ([strRequest containsString:@"acmd.api.pptv.com"] && [strRequest containsString:@"bwysdqmovie"]) {
        self.content = strRequest;
        self.viewPPTVNav.content = strRequest;
    }
    decisionHandler(WKNavigationActionPolicyAllow);//允许跳转
}
- (void)afterDelay {
    [self.webView evaluateJavaScript:@"javascript:adPlayFinish()" completionHandler:^(id _Nullable object, NSError * _Nullable error) {}];
}
- (WKWebView *)webView
{
- (WKWebView *)webView {
    if (!_webView) {
        // 0.网页配置对象
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
@@ -144,15 +218,40 @@
        //设置请求的User-Agent信息中应用程序名称 iOS9后可用
        config.applicationNameForUserAgent = @"ChinaDailyForiPad";
        
        _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, KScreenH) configuration:config];
        _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.viewPPTVNav.frame), KScreenW, KScreenH - CGRectGetHeight(self.viewPPTVNav.frame)) configuration:config];
        _webView.UIDelegate = self;
        _webView.navigationDelegate = self;
        // æ˜¯å¦å…è®¸æ‰‹åŠ¿å·¦æ»‘è¿”å›žä¸Šä¸€çº§, ç±»ä¼¼å¯¼èˆªæŽ§åˆ¶çš„左滑返回
        _webView.allowsBackForwardNavigationGestures = YES;
        //可返回的页面列表, å­˜å‚¨å·²æ‰“开过的网页
        WKBackForwardList * backForwardList = [_webView backForwardList];
        //WKBackForwardList * backForwardList = [_webView backForwardList];
    }
    return _webView;
}
- (PPTVNavView *)viewPPTVNav {
    if (!_viewPPTVNav) {
        _viewPPTVNav = [[PPTVNavView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, kStatusBarH + ALNavBarH)];
        _viewPPTVNav.delegate = self;
    }
    return _viewPPTVNav;
}
- (PPTVPppView *)viewPPTVPop {
    if (!_viewPPTVPop) {
        _viewPPTVPop = [[PPTVPppView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.viewPPTVNav.frame), KScreenW, KScreenH - CGRectGetHeight(self.viewPPTVNav.frame))];
        _viewPPTVPop.hidden = YES;
        _viewPPTVPop.delegate = self;
    }
    return _viewPPTVPop;
}
- (PPTVBottomVIpVIew *)viewPPTVVip {
    if (!_viewPPTVVip) {
        _viewPPTVVip = [[PPTVBottomVIpVIew alloc] initWithFrame:CGRectMake(0, 0, KScreenW, KScreenH)];
       // _viewPPTVVip.hidden = YES;
       // _viewPPTVVip.delegate = self;
    }
    return _viewPPTVVip;
}
@end
BuWanVideo2.0/PPTVDelegate.h
New file
@@ -0,0 +1,21 @@
//
//  PPTVDelegate.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol PPTVDelegate <NSObject>
- (void)backVc;
- (void)moreSelect;
- (void)selectType:(NSString *)type;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/PPTVNavView.h
New file
@@ -0,0 +1,22 @@
//
//  PPTVNavView.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "PPTVDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface PPTVNavView : UIView
@property (nonatomic, weak) id<PPTVDelegate>delegate;
@property (nonatomic, nullable , copy) NSString *name;
@property (nonatomic, nullable , copy) NSString *content;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/PPTVNavView.m
New file
@@ -0,0 +1,110 @@
//
//  PPTVNavView.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "PPTVNavView.h"
@interface PPTVNavView ()
@property (nonatomic, nullable, strong) UIView *viewBG;
@property (nonatomic, nullable, strong) UIButton *buttonBack;
@property (nonatomic, nullable, strong) UIButton *buutonRight;
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@property (nonatomic, nullable, strong) UILabel *labelContent;
@end
@implementation PPTVNavView
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self addSubview:self.viewBG];
    [self.viewBG addSubview:self.buttonBack];
    [self.viewBG addSubview:self.buutonRight];
    [self.viewBG addSubview:self.labelTitle];
    [self.viewBG addSubview:self.labelContent];
    self.viewBG.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, kStatusBarH).rightSpaceToView(self, 0).bottomSpaceToView(self, 0);
    self.buttonBack.sd_layout.leftSpaceToView(self.viewBG, 10).centerYEqualToView(self.viewBG).widthIs(30).heightIs(30);
    self.buutonRight.sd_layout.rightSpaceToView(self.viewBG, 10).centerYEqualToView(self.viewBG).widthIs(30).heightIs(30);
    self.labelTitle.sd_layout.leftSpaceToView(self.buttonBack, 10).topSpaceToView(self.viewBG, 3).rightSpaceToView(self.buutonRight, 0).autoHeightRatio(0);
    self.labelContent.sd_layout.leftSpaceToView(self.buttonBack, 10).topSpaceToView(self.labelTitle, -3).rightSpaceToView(self.buutonRight, 0).widthIs(KScreenW - 90);
}
- (void)back {
    if (_delegate && [_delegate respondsToSelector:@selector(backVc)]) {
        [_delegate backVc];
    }
}
- (void)more {
    if (_delegate && [_delegate respondsToSelector:@selector(moreSelect)]) {
        [_delegate moreSelect];
    }
}
- (void)setName:(NSString *)name {
    self.labelTitle.text = name;
}
- (void)setContent:(NSString *)content {
    self.labelContent.text = content;
}
- (UIView *)viewBG {
    if (!_viewBG) {
        _viewBG = [[UIView alloc] init];
    }
    return _viewBG;
}
- (UIButton *)buttonBack {
    if (!_buttonBack) {
        _buttonBack = [UIButton buttonWithType:UIButtonTypeCustom];
        [_buttonBack setImage:[UIImage imageNamed:@"详情页面返回"] forState:UIControlStateNormal];
        [_buttonBack addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    }
    return _buttonBack;
}
- (UIButton *)buutonRight {
    if (!_buutonRight) {
        _buutonRight = [UIButton buttonWithType:UIButtonTypeCustom];
        [_buutonRight setImage:[UIImage imageNamed:@"pptv_more"] forState:UIControlStateNormal];
        [_buutonRight addTarget:self action:@selector(more) forControlEvents:UIControlEventTouchUpInside];
    }
    return _buutonRight;
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.font = [UIFont systemFontOfSize:17];
        _labelTitle.textColor =UIColorFromRGBValue(0x000000);
        _labelTitle.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTitle;
}
- (UILabel *)labelContent {
    if (!_labelContent) {
        _labelContent = [[UILabel alloc] init];
        _labelContent.font = [UIFont systemFontOfSize:10];
        _labelContent.textColor =UIColorFromRGBValue(0x999999);
        _labelContent.textAlignment = NSTextAlignmentLeft;
    }
    return _labelContent;
}
@end
BuWanVideo2.0/PPTVPopCell.h
New file
@@ -0,0 +1,20 @@
//
//  PPTVPopCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface PPTVPopCell : UITableViewCell
@property (nonatomic, nullable, strong) NSDictionary *data;
@property (nonatomic, assign) NSInteger index;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/PPTVPopCell.m
New file
@@ -0,0 +1,89 @@
//
//  PPTVPopCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "PPTVPopCell.h"
@interface PPTVPopCell ()
@property (nonatomic, nullable, strong) UIImageView *imageViewIcon;
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@end
@implementation PPTVPopCell
- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    // Configure the view for the selected state
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        self.backgroundColor = [UIColor whiteColor];
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self.contentView addSubview:self.imageViewIcon];
    self.imageViewIcon.sd_layout.leftSpaceToView(self.contentView, 17).centerYEqualToView(self.contentView).widthIs(17).heightIs(17);
    [self.contentView addSubview:self.labelTitle];
    self.labelTitle.sd_layout.leftSpaceToView(self.imageViewIcon, 9).centerYEqualToView(self.imageViewIcon).rightSpaceToView(self.contentView, 0).heightIs(20);
}
- (void)setIndex:(NSInteger)index {
    _index = index;
}
- (void)setData:(NSDictionary *)data {
    if (data) {
        if (_index == 0) {
            self.imageViewIcon.sd_resetLayout.leftSpaceToView(self.contentView, 17).bottomSpaceToView(self.contentView, 6).widthIs(17).heightIs(17);
        } else  if (_index == 1) {
            self.imageViewIcon.sd_resetLayout.leftSpaceToView(self.contentView, 17).centerYEqualToView(self.contentView).widthIs(17).heightIs(17);
        } else  if (_index == 2) {
            self.imageViewIcon.sd_resetLayout.leftSpaceToView(self.contentView, 17).topSpaceToView(self.contentView, 6).widthIs(17).heightIs(17);
        }
        self.imageViewIcon.image = [UIImage imageNamed:data[@"icon"]];
        self.labelTitle.text = data[@"name"];
    }
}
- (UIImageView *)imageViewIcon {
    if (!_imageViewIcon) {
        _imageViewIcon = [[UIImageView alloc] init];
    }
    return _imageViewIcon;;
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.font = [UIFont systemFontOfSize:15];
        _labelTitle.textColor =UIColorFromRGBValue(0x666666);
        _labelTitle.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTitle;
}
@end
BuWanVideo2.0/PPTVPppView.h
New file
@@ -0,0 +1,20 @@
//
//  PPTVPppView.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "PPTVDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface PPTVPppView : UIView
@property (nonatomic, weak) id<PPTVDelegate>delegate;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/PPTVPppView.m
New file
@@ -0,0 +1,143 @@
//
//  PPTVPppView.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/15.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "PPTVPppView.h"
#import "PPTVPopCell.h"
@interface PPTVPppView () <UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>
@property (nonatomic, nullable, strong) UIView *viewBG;
@property (nonatomic, nullable, strong) UITableView *tabView;
@property (nonatomic, nullable, strong) UIImageView *imageViewTT;
@property(nonatomic, nullable, strong) NSArray *arrayContent;
@end
@implementation PPTVPppView
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = UICOLOR_FROM_RGB(0x000000, 0.5);
        self.userInteractionEnabled = YES;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismisView)];
        tap.delegate = self;
        [self addGestureRecognizer:tap];
        self.arrayContent = @[@{@"name" : @"刷新", @"icon" : @"pptv_refresh"} ,
                              @{@"name" : @"复制链接", @"icon" : @"pptv_copy"} ,
                              @{@"name" : @"用其他浏览器打开", @"icon" : @"pptv_other"}];
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self addSubview:self.imageViewTT];
    self.imageViewTT.sd_layout.rightSpaceToView(self, 8).topSpaceToView(self, 1).widthIs(33).heightIs(24);
    [self addSubview:self.viewBG];
    self.viewBG.sd_layout.rightSpaceToView(self, 5).topSpaceToView(self, 8).widthIs(180).heightIs(138);
    self.viewBG.sd_cornerRadius = @6;
    [self.viewBG addSubview:self.tabView];
}
- (void)dismisView {
    self.hidden = YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    // è¾“出点击的view的类名,则不截获Touch事件
    NSLog(@"%@", NSStringFromClass([touch.view class]));
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
            return NO;
        }
    }
    return YES;
}
#pragma mark UITableViewDelegate, UITableViewDataSource
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self dismisView];
    if (_delegate && [_delegate respondsToSelector:@selector(selectType:)]) {
        [_delegate selectType:self.arrayContent[indexPath.section][@"name"]];
    }
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.arrayContent.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *cellIden = @"PPTVPopCell";
    PPTVPopCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIden];
    if (!cell){
        cell = [[PPTVPopCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIden];
    }
    cell.index = indexPath.section;
    cell.data = self.arrayContent[indexPath.section];
    return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *view = [[UIView alloc] init];
    return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    UIView *view = [[UIView alloc] init];
    return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}
- (UIView *)viewBG {
    if (!_viewBG) {
        _viewBG = [[UIView alloc] init];
        _viewBG.backgroundColor = [UIColor whiteColor];
    }
    return _viewBG;
}
- (UITableView *)tabView {
    if (!_tabView) {
        _tabView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, (172),  137) style:UITableViewStyleGrouped];
        _tabView.delegate = self;
        _tabView.dataSource = self;
        _tabView.estimatedRowHeight = 47;
        _tabView.estimatedSectionFooterHeight = 0;
        _tabView.estimatedSectionHeaderHeight = 0;
        _tabView.backgroundColor = [UIColor whiteColor];
        _tabView.separatorStyle = UITableViewCellSeparatorStyleNone;
        _tabView.showsVerticalScrollIndicator = YES;
        _tabView.scrollEnabled = NO;
    }
    return _tabView;
}
- (UIImageView *)imageViewTT {
    if (!_imageViewTT) {
        _imageViewTT = [[UIImageView alloc] init];
        _imageViewTT.image = [UIImage imageNamed:@"pptv_bg"];
    }
    return _imageViewTT;
}
@end
BuWanVideo2.0/Recommend/BaseController.h
New file
@@ -0,0 +1,17 @@
//
//  BaseController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/23.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface BaseController : UIViewController
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/BaseController.m
New file
@@ -0,0 +1,33 @@
//
//  BaseController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/23.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "BaseController.h"
@interface BaseController ()
@end
@implementation BaseController
- (void)viewDidLoad {
    [super viewDidLoad];
    [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/
@end
BuWanVideo2.0/Recommend/HDController/HDController.h
New file
@@ -0,0 +1,19 @@
//
//  HDController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "BaseController.h"
#import "ZJScrollPageView.h"
NS_ASSUME_NONNULL_BEGIN
@interface HDController : BaseController <ZJScrollPageViewChildVcDelegate>
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/HDController/HDController.m
New file
@@ -0,0 +1,178 @@
//
//  HDController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "HDController.h"
#import "HDHeaderCell.h"
#import "RecommendThreeColumnCell.h"
#import "RecpmmendTitleView.h"
#import "UICollectionViewLeftAlignedLayout.h"
@interface HDController () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, nullable, strong) UICollectionView *collectionView;
@property (nonatomic, nullable, strong) HDHeaderCell *cellHDHeader;
@end
@implementation HDController
- (BOOL)shouldAutomaticallyForwardAppearanceMethods{
    return NO;
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.cellHDHeader open];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.cellHDHeader close];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupDataConfig];
    [self setupViewConfig];
}
- (void)setupDataConfig {
}
- (void)setupViewConfig {
    [self.view addSubview:self.collectionView];
}
#pragma mark UICollectionViewDelegate, UICollectionViewDataSource
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    //[self cellClick:indexPath];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 4;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section > 0) {
        return 6;
    }
    return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        if (!self.cellHDHeader) {
            self.cellHDHeader = [collectionView dequeueReusableCellWithReuseIdentifier:@"HDHeaderCell" forIndexPath:indexPath];
        }
        return self.cellHDHeader;
    }  else {
        RecommendThreeColumnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendThreeColumnCell" forIndexPath:indexPath];
        return cell;
    }
}
// å®šåˆ¶collectionView的head和foot
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    if (kind == UICollectionElementKindSectionHeader) {
        if (indexPath.section > 0) {
            RecpmmendTitleView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView" forIndexPath:indexPath];
            if (indexPath.section == 2) {
                view.isBanaer = YES;
            }
            return view;
        }
    }
    UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView" forIndexPath:indexPath];
    return view;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
    //宽度随便定,系统会自动取collectionView的宽度
    //高度为分组头的高度
    if (section > 0) {
        if (section == 2) {
            return CGSizeMake(KScreenW, 216);
        }
        return CGSizeMake(KScreenW, 47);
    }
    return CGSizeMake(0, 0);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return CGSizeMake(KScreenW, CGFLOAT_MIN);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section > 0) {
        return  CGSizeMake((KScreenW - 9 - 9 - 6 - 6) / 3, 201);
    } else {
        return  CGSizeMake(KScreenW, 105);
    }
}
//协议中的方法,用于返回整个CollectionView上、左、下、右距四边的间距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    if (section > 0 ) {
        return UIEdgeInsetsMake(0, 9, 0, 9);
    }
    return UIEdgeInsetsMake(0, 0, 0, 0);
}
//两行cell之间的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    if (section > 0) {
        return 10;
    }
    return 0;
}
//同一行两个cell的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    if (section > 0) {
        return 6;
    }
    return 0;
}
- (UICollectionView *)collectionView {
    if (!_collectionView) {
        UICollectionViewLeftAlignedLayout *flow = [[UICollectionViewLeftAlignedLayout alloc] init];
        //指定布局方式为垂直
        flow.scrollDirection = UICollectionViewScrollDirectionVertical;
        // STATUSBAR_HEIGHT + 27
        //创建CollectionView并指定布局对象
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0,  KScreenW, KScreenH - ALTabBar_H - kStatusBarH - ALNavBarH - 36) collectionViewLayout:flow];
        _collectionView.backgroundColor = [UIColor whiteColor];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        _collectionView.delaysContentTouches = NO;
        _collectionView.showsVerticalScrollIndicator = NO;
        [_collectionView registerClass:[HDHeaderCell class] forCellWithReuseIdentifier:@"HDHeaderCell"];
        [_collectionView registerClass:[RecommendThreeColumnCell class] forCellWithReuseIdentifier:@"RecommendThreeColumnCell"];
        [_collectionView registerClass:[RecpmmendTitleView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView"];
        [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView"];
    }
    return _collectionView;
}
@end
BuWanVideo2.0/Recommend/HDController/cell/HDHeaderCell.h
New file
@@ -0,0 +1,21 @@
//
//  HDHeaderCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface HDHeaderCell : UICollectionViewCell
@property (nonatomic, nullable, strong) NSArray *arrayImage;
- (void)open;
- (void)close;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/HDController/cell/HDHeaderCell.m
New file
@@ -0,0 +1,141 @@
//
//  HDHeaderCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "HDHeaderCell.h"
#import "SDCycleScrollView.h"
#import "CWCarouselHeader.h"
@interface HDHeaderCell () <CWCarouselDatasource, CWCarouselDelegate, SDCycleScrollViewDelegate>
@property (nonatomic, nullable, strong) UIView *viewBG;
@property (nonatomic, nullable, strong) CWCarousel *carousel;
@end
@implementation HDHeaderCell
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        [self setupDataConfig];
        [self setupCellConfig];
    }
    return self;
}
- (void)setupDataConfig {
    self.arrayImage = @[@"01.jpg"];
}
- (void)setupCellConfig {
    [self addSubview:self.viewBG];
    self.viewBG.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, 5).rightSpaceToView(self, 0).bottomSpaceToView(self, 0);
    if (self.arrayImage.count > 2) {
        CWFlowLayout *flowLayout = [[CWFlowLayout alloc] initWithStyle:CWCarouselStyle_H_1];
        flowLayout.itemWidth = KScreenW - 20;
        flowLayout.itemSpace_H = 5;
        CWCarousel *carousel = [[CWCarousel alloc] initWithFrame:CGRectMake(0, 0, KScreenW, 100)
                                                        delegate:self
                                                      datasource:self
                                                      flowLayout:flowLayout];
        [self.viewBG addSubview:carousel];
        carousel.isAuto = YES;
        carousel.endless = YES;
        carousel.backgroundColor = [UIColor whiteColor];
        [carousel registerViewClass:[UICollectionViewCell class] identifier:@"cellId"];
        [carousel freshCarousel];
        [carousel.pageControl removeFromSuperview];;
        self.carousel = carousel;
    } else {
        CGRect frame = CGRectMake(10, 0, KScreenW - 20, 100);
        //if (images && images.count != 0) {
        SDCycleScrollView *cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:frame delegate:self placeholderImage:nil];
        //cycleScrollView.imageURLStringsGroup = images;
        cycleScrollView.localizationImageNamesGroup = _arrayImage;
        cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleClassic;
        cycleScrollView.pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
        cycleScrollView.autoScrollTimeInterval = 5.0f;
        cycleScrollView.currentPageDotColor = UICOLOR_FROM_RGB(0x159FFF, 1.0);
        cycleScrollView.pageDotColor = UICOLOR_FROM_RGB(0xffffff, 0.5);
        cycleScrollView.pageControlBottomOffset = 5;
        cycleScrollView.layer.masksToBounds = YES;
        cycleScrollView.layer.cornerRadius = 8;
        if (self.arrayImage.count < 2) {
        cycleScrollView.infiniteLoop = NO;
        }
        //[self.viewBannerBG addSubview:cycleScrollView];
        [self.viewBG addSubview:cycleScrollView];
    }
}
- (void)open {
    if (self.carousel) {
        [self.carousel controllerWillAppear];
    }
}
- (void)close {
    if (self.carousel) {
        [self.carousel controllerWillDisAppear];
    }
}
#pragma mark - Delegate
- (NSInteger)numbersForCarousel {
    return self.arrayImage.count;
}
- (UICollectionViewCell *)viewForCarousel:(CWCarousel *)carousel indexPath:(NSIndexPath *)indexPath index:(NSInteger)index{
    UICollectionViewCell *cell = [carousel.carouselView dequeueReusableCellWithReuseIdentifier:@"cellId" forIndexPath:indexPath];
    cell.contentView.backgroundColor = [UIColor whiteColor];
    UIImageView *imgView = [cell.contentView viewWithTag:666];
    if(!imgView) {
        imgView = [[UIImageView alloc] initWithFrame:cell.contentView.bounds];
        [imgView setContentScaleFactor:[[UIScreen mainScreen] scale]];
        imgView.contentMode = UIViewContentModeScaleAspectFill;
        imgView.clipsToBounds = YES;
        imgView.tag = 666;
        [cell.contentView addSubview:imgView];
        cell.layer.masksToBounds = YES;
        cell.layer.cornerRadius = 8;
    }
//    https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwio8MyTp-DdAhWKM94KHUmEDcAQjRx6BAgBEAU&url=http%3A%2F%2F699pic.com%2Ftupian%2Fchuan.html&psig=AOvVaw20gpsPpW4JcNm0mJi9dYrb&ust=1538313533814128
//    NSString *name = [NSString stringWithFormat:@"%02ld.jpg", index + 1];
    NSString *name = self.arrayImage[index];
    UIImage *img = [UIImage imageNamed:name];
    [imgView setImage:img];
    return cell;
}
- (void)CWCarousel:(CWCarousel *)carousel didSelectedAtIndex:(NSInteger)index {
    NSLog(@"...%ld...", (long)index);
}
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index {
}
- (UIView *)viewBG {
    if (!_viewBG) {
        _viewBG = [[UIView alloc] init];
        _viewBG.backgroundColor = [UIColor whiteColor];
    }
    return _viewBG;;
}
@end
BuWanVideo2.0/Recommend/LifeHomeController.h
New file
@@ -0,0 +1,20 @@
//
//  LifeHomeController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "BaseController.h"
#import "ZJScrollPageView.h"
NS_ASSUME_NONNULL_BEGIN
@interface LifeHomeController : BaseController <ZJScrollPageViewChildVcDelegate>
@property (nonatomic, nullable, strong) NSDictionary *parms;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/LifeHomeController.m
New file
@@ -0,0 +1,212 @@
//
//  LifeHomeController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "LifeHomeController.h"
#import "RecommendHeaderViewCell.h"
#import "ToDayHotCell.h"
#import "RecommendTwoColumnCell.h"
#import "RecommendThreeColumnCell.h"
#import "RecpmmendTitleView.h"
#import "UICollectionViewLeftAlignedLayout.h"
@interface LifeHomeController () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, nullable, strong) UICollectionView *collectionView;
@property (nonatomic, nullable, strong) RecommendHeaderViewCell *cellRecommendHeader;
@end
@implementation LifeHomeController
- (BOOL)shouldAutomaticallyForwardAppearanceMethods{
    return NO;
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.cellRecommendHeader open];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.cellRecommendHeader close];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupDataConfig];
    [self setupViewConfig];
}
- (void)setupDataConfig {
}
- (void)setupViewConfig {
    [self.view addSubview:self.collectionView];
}
#pragma mark UICollectionViewDelegate, UICollectionViewDataSource
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    //[self cellClick:indexPath];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 4;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section == 2) {
        return 6;
    } else if (section == 3) {
        return 6;
    }
    return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        if (!self.cellRecommendHeader) {
            self.cellRecommendHeader = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendHeaderViewCell" forIndexPath:indexPath];
        }
        return self.cellRecommendHeader;
    }  else if (indexPath.section == 1) {
        ToDayHotCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ToDayHotCell" forIndexPath:indexPath];
        return cell;
    } else if (indexPath.section == 2) {
        RecommendTwoColumnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendTwoColumnCell" forIndexPath:indexPath];
        return cell;
    } else if (indexPath.section == 3) {
        RecommendThreeColumnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendThreeColumnCell" forIndexPath:indexPath];
        return cell;
    }
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
    return cell;
    abort();
}
// å®šåˆ¶collectionView的head和foot
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
        if (kind == UICollectionElementKindSectionHeader) {
            if (indexPath.section > 0) {
                RecpmmendTitleView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView" forIndexPath:indexPath];
                if (indexPath.section == 2) {
                    view.isBanaer = YES;
                }
                return view;
            }
        }
    UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView" forIndexPath:indexPath];
    return view;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
    //宽度随便定,系统会自动取collectionView的宽度
    //高度为分组头的高度
    if (section > 0) {
        if (section == 2) {
            return CGSizeMake(KScreenW, 216);
        }
        return CGSizeMake(KScreenW, 47);
    }
    return CGSizeMake(0, 0);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return CGSizeMake(KScreenW, CGFLOAT_MIN);
  }
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        return  CGSizeMake(KScreenW, 161);
    } else if (indexPath.section == 1) {
        return  CGSizeMake(KScreenW, 140);
    }  else if (indexPath.section == 2) {
        return  CGSizeMake((KScreenW - 9 - 9 - 8) / 2, 140);
    } else if (indexPath.section == 3) {
        return  CGSizeMake((KScreenW - 9 - 9 - 6 - 6) / 3, 201);
    }
    return  CGSizeMake(KScreenW, 35);
    abort();
}
//协议中的方法,用于返回整个CollectionView上、左、下、右距四边的间距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    if (section == 2 || section == 3) {
        return UIEdgeInsetsMake(0, 9, 0, 9);
    }
    return UIEdgeInsetsMake(0, 0, 0, 0);
    abort();
}
//两行cell之间的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 2) {
        return 16;
    } else if (section == 3) {
        return 10;
    }
    return 0;
}
//同一行两个cell的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 2) {
        return 8;
    } else if (section == 3) {
        return 6;
    }
    return 0;
}
- (UICollectionView *)collectionView {
    if (!_collectionView) {
        UICollectionViewLeftAlignedLayout *flow = [[UICollectionViewLeftAlignedLayout alloc] init];
        //指定布局方式为垂直
        flow.scrollDirection = UICollectionViewScrollDirectionVertical;
        // STATUSBAR_HEIGHT + 27
        //创建CollectionView并指定布局对象
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0,  KScreenW, KScreenH - ALTabBar_H - kStatusBarH - ALNavBarH - 36) collectionViewLayout:flow];
        _collectionView.backgroundColor = [UIColor whiteColor];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        _collectionView.delaysContentTouches = NO;
        _collectionView.showsVerticalScrollIndicator = NO;
        [_collectionView registerClass:[RecommendHeaderViewCell class] forCellWithReuseIdentifier:@"RecommendHeaderViewCell"];
        [_collectionView registerClass:[ToDayHotCell class] forCellWithReuseIdentifier:@"ToDayHotCell"];
        [_collectionView registerClass:[RecommendTwoColumnCell class] forCellWithReuseIdentifier:@"RecommendTwoColumnCell"];
        [_collectionView registerClass:[RecommendThreeColumnCell class] forCellWithReuseIdentifier:@"RecommendThreeColumnCell"];
         [_collectionView registerClass:[RecpmmendTitleView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView"];
         [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView"];
    }
    return _collectionView;
}
@end
BuWanVideo2.0/Recommend/ListControlelr/ListController.h
New file
@@ -0,0 +1,20 @@
//
//  ListController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "BaseController.h"
#import "ZJScrollPageView.h"
NS_ASSUME_NONNULL_BEGIN
@interface ListController : BaseController <ZJScrollPageViewChildVcDelegate>
@property (nonatomic, nullable, strong) NSDictionary *parms;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/ListControlelr/ListController.m
New file
@@ -0,0 +1,414 @@
//
//  ListController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "ListController.h"
#import "RecommendHeaderViewCell.h"
#import "ToDayHotCell.h"
#import "RecommendTwoColumnCell.h"
#import "RecommendThreeColumnCell.h"
#import "RecpmmendTitleView.h"
#import "RecommendChangeFooterView.h"
#import "UICollectionViewLeftAlignedLayout.h"
@interface ListController () <UICollectionViewDelegate, UICollectionViewDataSource, RecommendDelegate>
@property (nonatomic, nullable, strong) UICollectionView *collectionView;
@property (nonatomic, nullable, strong) RecommendHeaderViewCell *cellRecommendHeader;
@property (nonatomic, assign) NSUInteger page;
@property (nonatomic, nullable, strong) NSDictionary *dictionaryBanaer;
@property (nonatomic, nullable, strong) NSArray *arrayTemp;
@property (nonatomic, nullable, strong) NSMutableArray *arrayContent;
@property (nonatomic, assign) NSUInteger count;
@end
@implementation ListController
- (BOOL)shouldAutomaticallyForwardAppearanceMethods{
    return NO;
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.cellRecommendHeader open];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.cellRecommendHeader close];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupDataConfig];
    [self setupViewConfig];
    [self getHomeAd];
}
- (void)setupDataConfig {
    self.page = 1;
}
- (void)setupViewConfig {
    [self.view addSubview:self.collectionView];
}
-(void)getHomeAd{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    // åˆ›å»ºå…¨å±€å¹¶è¡Œ
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        [[YTHNetInterface startInterface] getRecommendCategoryVideoBannerWithUid:[YTHsharedManger startManger].Uid vtid:_parms[@"Id"] withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) {
            if (isSuccessful) {
                NSDictionary *dic = (NSDictionary *)result;
                self.dictionaryBanaer = dic[@"Data"];
            }
            dispatch_semaphore_signal(semaphore);
        }];
    });
    dispatch_group_async(group, queue, ^{
        [[YTHNetInterface startInterface] getRecommendCategoryVideoListWithUid:[YTHsharedManger startManger].Uid withVideoType:_parms[@"Id"] withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) {
            if (isSuccessful) {
                if (_page == 1) {
                    [self.arrayContent removeAllObjects];
                }
                self.arrayTemp = result[@"Data"][@"data"];
                self.count = [result[@"Data"][@"count"] integerValue];
                self.page++;
                if (self.count == self.arrayContent.count) {
                    [self hideFooger];
                } else {
                    if (!self.collectionView.mj_footer) {
                        [self setFooterRefresh];
                    }
                }
            }
            dispatch_semaphore_signal(semaphore);
        }];
    });
    dispatch_group_notify(group, queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.arrayContent addObjectsFromArray:self.arrayTemp];
            [self.collectionView reloadData];
        });
    });
}
- (void)loadFooter:(void(^)(void))handel {
    [[YTHNetInterface startInterface] getHomeTypeWithUid:[YTHsharedManger startManger].Uid vtid:_parms[@"Id"] withSystem:@"1" DataKey:_parms[@"DataKey"] PageSize:10 Page:_page withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            if (_page == 1) {
                [self.arrayContent removeAllObjects];
            }
            self.arrayTemp = result[@"Data"][@"data"];
            self.count = [result[@"Data"][@"count"] integerValue];
            self.page++;
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.arrayContent addObjectsFromArray:self.arrayTemp];
                [self.collectionView reloadData];
            });
        }
        [self.collectionView.mj_header endRefreshing];
        [self.collectionView.mj_footer endRefreshing];
        if (self.count == self.arrayContent.count) {
            [self hideFooger];
        } else {
            if (!self.collectionView.mj_footer) {
                [self setFooterRefresh];
            }
        }
        handel();
    }];
}
- (void)changeData:(NSString *)vid page:(NSUInteger)page index:(NSInteger)index {
    [[YTHNetInterface startInterface] getVideoRecommendWithUid:vid Page:page WithSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            NSMutableDictionary *parms = [[NSMutableDictionary alloc] initWithDictionary:self.arrayContent[index-1]];
            parms[@"page"] = result[@"Data"][@"page"];
            parms[@"HomeVideoList"] = result[@"Data"][@"list"];
            self.arrayContent[index-1] = parms;
            [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:index]];
        }
    }];
}
- (void)onEventChange:(NSString *)vid page:(NSUInteger)page index:(NSInteger)index pages:(nonnull NSString *)pages {
    if (!pages) {
        page = 1;
    }
    page+=1;
    [self changeData:vid page:page index:index];
}
- (void)hideFooger {
    self.collectionView.mj_footer = nil;
}
- (void)setFooterRefresh {
    self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
        [self loadFooter:^{
        }];
    }];
}
#pragma mark UICollectionViewDelegate, UICollectionViewDataSource
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    //[self cellClick:indexPath];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return self.arrayContent.count+1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section == 0) {
        return 1;
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2 || Columns == 3) {
            BOOL BigPicture = [self.arrayContent[section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            if (BigPicture) {
                return [self.arrayContent[section-1][@"HomeVideoList"] count]-1;
            }
            return [self.arrayContent[section-1][@"HomeVideoList"] count];
        }
    }
    return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        if (!self.cellRecommendHeader) {
            self.cellRecommendHeader = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendHeaderViewCell" forIndexPath:indexPath];
        }
        self.cellRecommendHeader.arrayImageData = self.dictionaryBanaer;
        return self.cellRecommendHeader;
    } else {
        NSUInteger Columns = [self.arrayContent[indexPath.section-1][@"Columns"] integerValue];
        if (Columns > 3) {
            ToDayHotCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ToDayHotCell" forIndexPath:indexPath];
            cell.data = self.arrayContent[indexPath.section-1];
            return cell;
        } else if (Columns == 2) {
            RecommendTwoColumnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendTwoColumnCell" forIndexPath:indexPath];
            BOOL BigPicture = [self.arrayContent[indexPath.section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            if (BigPicture) {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row+1][@"Video"];
            } else {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row][@"Video"];
            }
            return cell;
        } else if (Columns == 3) {
            RecommendThreeColumnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendThreeColumnCell" forIndexPath:indexPath];
            BOOL BigPicture = [self.arrayContent[indexPath.section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            if (BigPicture) {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row+1][@"Video"];
            } else {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row][@"Video"];
            }
            return cell;
        }
    }
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
    return cell;
}
// å®šåˆ¶collectionView的head和foot
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    if (kind == UICollectionElementKindSectionHeader) {
        if (indexPath.section > 0) {
            RecpmmendTitleView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView" forIndexPath:indexPath];
            view.delegate = self;
            BOOL BigPicture = [self.arrayContent[indexPath.section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            view.isBanaer = BigPicture;
            view.data = self.arrayContent[indexPath.section-1];
            view.index = indexPath.section;
            return view;
        }
    } else {
        if (indexPath.section > 1) {
            NSDictionary *data = self.arrayContent[indexPath.section-1];
            if ([data[@"RefreshPosition"] integerValue] == 2) {
                RecommendChangeFooterView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"RecommendChangeFooterView" forIndexPath:indexPath];
                view.delegate = self;
                view.data = data;
                view.position = indexPath.section;
                return view;
            }
        }
    }
    UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView" forIndexPath:indexPath];
    return view;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
    //宽度随便定,系统会自动取collectionView的宽度
    //高度为分组头的高度
    if (section > 0) {
        BOOL BigPicture = [self.arrayContent[section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
        if (BigPicture) {
            return CGSizeMake(KScreenW, 216 + 40 + 30);
        }
        return CGSizeMake(KScreenW, 47);
    }
    return CGSizeMake(0, 0);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    if (section == 0) {
        return CGSizeMake(CGFLOAT_MIN, CGFLOAT_MIN);
    }
    NSUInteger Columns = [self.arrayContent[section-1][@"RefreshPosition"] integerValue];
    if (Columns == 2) {
        return CGSizeMake(KScreenW, 41);
    } else {
        return CGSizeMake(CGFLOAT_MIN, CGFLOAT_MIN);
    }
  }
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        CGFloat bannerSizeRate = [self.dictionaryBanaer[@"bannerSizeRate"] doubleValue];
        return  CGSizeMake(KScreenW, 5 + (156 * bannerSizeRate));
    } else {
        NSUInteger Columns = [self.arrayContent[indexPath.section-1][@"Columns"] integerValue];
        if (Columns > 3) {
            return  CGSizeMake(KScreenW, 140);
        } else if (Columns == 2) {
            return  CGSizeMake((KScreenW - 9 - 9 - 8) / 2, 140);
        } else if (Columns == 3) {
            return  CGSizeMake((KScreenW - 9 - 9 - 6 - 6) / 3, 201);
        }
    }
    return  CGSizeMake(KScreenW, 35);
}
//协议中的方法,用于返回整个CollectionView上、左、下、右距四边的间距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    if (section == 0) {
        return UIEdgeInsetsMake(0, 0, 0, 0);
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2 || Columns == 3) {
            return UIEdgeInsetsMake(5, 9, 0, 9);
        } else if (Columns == 3) {
            return UIEdgeInsetsMake(0, 9, 0, 9);
        }
    }
    return UIEdgeInsetsMake(0, 0, 0, 0);
}
//两行cell之间的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 0) {
        return 0;
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2) {
            return 12;
        } else if (Columns == 3) {
            return 10;
        }
    }
    return 0;;
}
//同一行两个cell的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 0) {
        return 0;
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2) {
            return 8;
        } else if (Columns == 3) {
            return 6;
        }
    }
    return 0;
}
- (UICollectionView *)collectionView {
    if (!_collectionView) {
        UICollectionViewLeftAlignedLayout *flow = [[UICollectionViewLeftAlignedLayout alloc] init];
        //指定布局方式为垂直
        flow.scrollDirection = UICollectionViewScrollDirectionVertical;
        // STATUSBAR_HEIGHT + 27
        //创建CollectionView并指定布局对象
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0,  KScreenW, KScreenH - ALTabBar_H - kStatusBarH - ALNavBarH - 36) collectionViewLayout:flow];
        _collectionView.backgroundColor = [UIColor whiteColor];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        _collectionView.delaysContentTouches = NO;
        _collectionView.showsVerticalScrollIndicator = NO;
        [_collectionView registerClass:[RecommendHeaderViewCell class] forCellWithReuseIdentifier:@"RecommendHeaderViewCell"];
        [_collectionView registerClass:[ToDayHotCell class] forCellWithReuseIdentifier:@"ToDayHotCell"];
        [_collectionView registerClass:[RecommendTwoColumnCell class] forCellWithReuseIdentifier:@"RecommendTwoColumnCell"];
        [_collectionView registerClass:[RecommendThreeColumnCell class] forCellWithReuseIdentifier:@"RecommendThreeColumnCell"];
        [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
         [_collectionView registerClass:[RecpmmendTitleView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView"];
        [_collectionView registerClass:[RecommendChangeFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"RecommendChangeFooterView"];
         [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView"];
    }
    return _collectionView;
}
- (NSMutableArray *)arrayContent {
    if (!_arrayContent) {
        _arrayContent = [[NSMutableArray alloc] init];
    }
    return _arrayContent;
}
@end
BuWanVideo2.0/Recommend/MainBaseController.h
New file
@@ -0,0 +1,17 @@
//
//  MainBaseController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "BaseController.h"
NS_ASSUME_NONNULL_BEGIN
@interface MainBaseController : BaseController
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/MainBaseController.m
New file
@@ -0,0 +1,75 @@
//
//  MainBaseController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "MainBaseController.h"
#import "SearchController.h"
#import "RecommendNavView.h"
@interface MainBaseController ()
@property(nonatomic, nullable, strong) RecommendNavView *viewRecommendNav;
@property (nonatomic, nullable, strong) NSMutableArray *dataHot;
@end
@implementation MainBaseController
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupMainViewConfig];
    [self getHotSearch];
}
- (void)getHotSearch {
    if (![YTHsharedManger startManger].searchTitle || [[YTHsharedManger startManger].searchTitle isEqualToString:@""]) {
        [[YTHNetInterface startInterface] getHotSerachWithUid:[YTHsharedManger startManger].Uid withSystem:@"1" withblock:^(BOOL isSuccessful, id result, NSString *error) {
            if (isSuccessful) {
                NSDictionary *dic = (NSDictionary *)result;
                if (!_dataHot) {
                    self.dataHot = [[NSMutableArray alloc] initWithCapacity:0];
                }
                [self.dataHot removeAllObjects];
                NSArray *ar = [[dic objectForKey:@"Data"] objectForKey:@"data"];
                for (int i =0; i<ar.count; i++) {
                    [self.dataHot addObject:[ar objectAtIndex:i]];
                }
                NSInteger rand = arc4random()%self.dataHot.count ;
                self.viewRecommendNav.title = self.dataHot[rand];
                [YTHsharedManger startManger].searchTitle = self.viewRecommendNav.title;
            } else {
            }
        }];
    } else {
        self.viewRecommendNav.title = [YTHsharedManger startManger].searchTitle;
    }
}
- (void)setupMainViewConfig {
    [self.view addSubview:self.viewRecommendNav];
    __weak typeof(self) weakSelf = self;
    self.viewRecommendNav.onSearch = ^{
        SearchController *vc = [[SearchController alloc] init];
        vc.ptitle = [YTHsharedManger startManger].searchTitle;
        vc.hidesBottomBarWhenPushed = YES;
        [weakSelf.navigationController pushViewController:vc animated:YES];
    };
}
- (RecommendNavView *)viewRecommendNav {
    if (!_viewRecommendNav) {
        _viewRecommendNav = [[RecommendNavView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, kStatusBarH + ALNavBarH)];
    }
    return _viewRecommendNav;
}
@end
BuWanVideo2.0/Recommend/Recommend/Cell/01.jpg
BuWanVideo2.0/Recommend/Recommend/Cell/02.jpg
BuWanVideo2.0/Recommend/Recommend/Cell/03.jpg
BuWanVideo2.0/Recommend/Recommend/Cell/04.jpg
BuWanVideo2.0/Recommend/Recommend/Cell/05.jpg
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendChangeFooterView.h
New file
@@ -0,0 +1,23 @@
//
//  RecommendChangeFooterView.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "RecommendDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface RecommendChangeFooterView : UICollectionReusableView
@property (nonatomic, weak) id<RecommendDelegate>delegate;
@property (nonatomic, assign) NSInteger position;
@property (nonatomic, nullable, strong) NSDictionary *data;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendChangeFooterView.m
New file
@@ -0,0 +1,66 @@
//
//  RecommendChangeFooterView.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecommendChangeFooterView.h"
@interface RecommendChangeFooterView ()
@property (nonatomic, nullable, strong) UIButton *buttonChange;
@end
@implementation RecommendChangeFooterView
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        [self setupDataConfig];
        [self setupViewConfig];
    }
    return self;
}
- (void)setupDataConfig {
}
- (void)setupViewConfig {
    [self addSubview:self.buttonChange];
    self.buttonChange.sd_layout.centerXEqualToView(self).centerYEqualToView(self).widthIs(73).heightIs(21);
    self.buttonChange.sd_cornerRadius = @10.5;
}
- (void)setPosition:(NSInteger)position {
    _position = position;
}
- (void)setData:(NSDictionary *)data {
    _data = data;
}
- (void)eventChange {
    if (_delegate && [_delegate respondsToSelector:@selector(onEventChange:page:index:pages:)]) {
        [_delegate onEventChange:_data[@"Id"] page:[_data[@"page"] integerValue] index:_position pages:_data[@"page"]];
    }
}
- (UIButton *)buttonChange {
    if (!_buttonChange) {
        _buttonChange = [UIButton buttonWithType:UIButtonTypeCustom];
        [_buttonChange setImage:[UIImage imageNamed:@"home_recommend_change"] forState:UIControlStateNormal];
        [_buttonChange setTitle:@"  æ¢ä¸€æ‰¹" forState:UIControlStateNormal];
        _buttonChange.titleLabel.font = [UIFont systemFontOfSize:10];
        [_buttonChange setTitleColor:UICOLOR_FROM_RGB(0x666666, 1) forState:UIControlStateNormal];
        _buttonChange.backgroundColor = UICOLOR_FROM_RGB(0xE9F0FF, 1);
        [_buttonChange addTarget:self action:@selector(eventChange) forControlEvents:UIControlEventTouchUpInside];
    }
    return _buttonChange;
}
@end
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendHeaderViewCell.h
New file
@@ -0,0 +1,21 @@
//
//  RecommendHeaderViewCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface RecommendHeaderViewCell : UICollectionViewCell
@property (nonatomic, nullable, strong) NSDictionary *arrayImageData;
- (void)open;
- (void)close;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendHeaderViewCell.m
New file
@@ -0,0 +1,180 @@
//
//  RecommendHeaderViewCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecommendHeaderViewCell.h"
#import "SDCycleScrollView.h"
#import "CWCarouselHeader.h"
#define BSKPlaceHolderImage [UIImage imageNamed:@"默认加载图片"]
@interface RecommendHeaderViewCell () <CWCarouselDatasource, CWCarouselDelegate, SDCycleScrollViewDelegate>
@property (nonatomic, nullable, strong) UIView *viewBG;
@property (nonatomic, nullable, strong) CWCarousel *carousel;
@property (nonatomic, nullable, strong) NSMutableArray *arrayImage;
@property (nonatomic, nullable, strong) NSMutableArray *arrayData;
@end
@implementation RecommendHeaderViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        [self setupDataConfig];
        [self setupCellConfig];
    }
    return self;
}
- (void)setupDataConfig {
}
- (void)setupCellConfig {
    [self addSubview:self.viewBG];
    self.viewBG.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, 5).rightSpaceToView(self, 0).bottomSpaceToView(self, 0);
}
- (void)setArrayImageData:(NSDictionary *)arrayImageData {
    _arrayImageData = arrayImageData;
    if (arrayImageData) {
//        for (__strong UIView *view in [self.viewBG subviews]) {
//            [view removeFromSuperview];
//            view = nil;
//        }
        if ([self.viewBG subviews].count != 0) {
            return;
        }
        CGFloat bannerSizeRate = [arrayImageData[@"bannerSizeRate"] doubleValue];
        for (int i = 0; i < [arrayImageData[@"data"] count]; i++) {
            [self.arrayImage addObject:arrayImageData[@"data"][i][@"Picture"]];
            [self.arrayData addObject:arrayImageData[@"data"][i]];
        }
        if (_arrayImage.count > 2) {
            CWFlowLayout *flowLayout = [[CWFlowLayout alloc] initWithStyle:CWCarouselStyle_H_1];
            flowLayout.itemWidth = KScreenW - 20;
            flowLayout.itemSpace_H = 5;
            CWCarousel *carousel = [[CWCarousel alloc] initWithFrame:CGRectMake(0, 0, KScreenW, 156 * bannerSizeRate)
                                                            delegate:self
                                                          datasource:self
                                                          flowLayout:flowLayout];
            [self.viewBG addSubview:carousel];
            carousel.isAuto = YES;
            carousel.endless = YES;
            carousel.backgroundColor = [UIColor whiteColor];
            [carousel registerViewClass:[UICollectionViewCell class] identifier:@"cellId"];
            [carousel freshCarousel];
            [carousel.pageControl removeFromSuperview];
            self.carousel = carousel;
        } else {
            CGRect frame = CGRectMake(10, 0, KScreenW - 20, 156 * bannerSizeRate);
            //if (images && images.count != 0) {
            SDCycleScrollView *cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:frame delegate:self placeholderImage:nil];
            //cycleScrollView.imageURLStringsGroup = images;
            cycleScrollView.localizationImageNamesGroup = _arrayImage;
            cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleClassic;
            cycleScrollView.pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
            cycleScrollView.autoScrollTimeInterval = 5.0f;
            cycleScrollView.currentPageDotColor = UICOLOR_FROM_RGB(0x159FFF, 1.0);
            cycleScrollView.pageDotColor = UICOLOR_FROM_RGB(0xffffff, 0.5);
            cycleScrollView.pageControlBottomOffset = 5;
            cycleScrollView.layer.masksToBounds = YES;
            cycleScrollView.layer.cornerRadius = 8;
            if (self.arrayImage.count < 2) {
                cycleScrollView.infiniteLoop = NO;
            }
            //[self.viewBannerBG addSubview:cycleScrollView];
            [self.viewBG addSubview:cycleScrollView];
        }
    }
}
- (void)open {
    if (self.carousel) {
        [self.carousel controllerWillAppear];
    }
}
- (void)close {
    if (self.carousel) {
        [self.carousel controllerWillDisAppear];
    }
}
#pragma mark - Delegate
- (NSInteger)numbersForCarousel {
    return self.arrayImage.count;
}
- (UICollectionViewCell *)viewForCarousel:(CWCarousel *)carousel indexPath:(NSIndexPath *)indexPath index:(NSInteger)index{
    UICollectionViewCell *cell = [carousel.carouselView dequeueReusableCellWithReuseIdentifier:@"cellId" forIndexPath:indexPath];
    cell.contentView.backgroundColor = [UIColor whiteColor];
    UIImageView *imgView = [cell.contentView viewWithTag:666];
    if(!imgView) {
        imgView = [[UIImageView alloc] initWithFrame:cell.contentView.bounds];
        [imgView setContentScaleFactor:[[UIScreen mainScreen] scale]];
        imgView.contentMode = UIViewContentModeScaleAspectFill;
        imgView.clipsToBounds = YES;
        imgView.tag = 666;
        [cell.contentView addSubview:imgView];
        cell.layer.masksToBounds = YES;
        cell.layer.cornerRadius = 8;
    }
    NSString *name = self.arrayImage[index];
    [imgView setYthImageWithURL:name placeholderImage:BSKPlaceHolderImage];
    return cell;
}
- (void)CWCarousel:(CWCarousel *)carousel didSelectedAtIndex:(NSInteger)index {
    NSLog(@"...%ld...", (long)index);
}
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index {
}
- (UIView *)viewBG {
    if (!_viewBG) {
        _viewBG = [[UIView alloc] init];
        _viewBG.backgroundColor = [UIColor whiteColor];
    }
    return _viewBG;;
}
- (NSMutableArray *)arrayImage {
    if (!_arrayImage) {
        _arrayImage = [[NSMutableArray alloc] init];
    }
    return _arrayImage;
}
- (NSMutableArray *)arrayData {
    if (!_arrayData) {
        _arrayData = [[NSMutableArray alloc] init];
    }
    return _arrayData;
}
@end
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendThreeColumnCell.h
New file
@@ -0,0 +1,19 @@
//
//  RecommendThreeColumnCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface RecommendThreeColumnCell : UICollectionViewCell
@property (nonatomic, nullable, strong) NSDictionary *data;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendThreeColumnCell.m
New file
@@ -0,0 +1,163 @@
//
//  RecommendThreeColumnCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecommendThreeColumnCell.h"
@interface RecommendThreeColumnCell ()
@property (nonatomic, nullable, strong) UIImageView *imaegView;
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@property (nonatomic, nullable, strong) UIImageView *imaegViewGQ;
@property (nonatomic, nullable, strong) UIImageView *imaegViewVIP;
@property (nonatomic, nullable, strong) UILabel *labelTag;
@property (nonatomic, nullable, strong) UILabel *labelScore;
@end
@implementation RecommendThreeColumnCell
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.contentView.backgroundColor = [UIColor whiteColor];
        [self setuoViewConfig];
    }
    return self;
}
- (void)setuoViewConfig {
    [self.contentView addSubview:self.imaegView];
    [self.contentView addSubview:self.labelTitle];
    [self.contentView addSubview:self.imaegViewGQ];
    [self.contentView addSubview:self.imaegViewVIP];
    self.imaegView.sd_layout.leftEqualToView(self.contentView).topEqualToView(self.contentView).rightEqualToView(self.contentView).heightIs(160);
    self.imaegView.sd_cornerRadius = @6;
    self.labelTitle.sd_layout.leftSpaceToView(self.contentView, 0).topSpaceToView(self.imaegView, 6).rightSpaceToView(self.contentView, 0).heightIs(0);
    self.imaegViewGQ.sd_layout.leftSpaceToView(self.contentView, 0).topSpaceToView(self.contentView, 0).widthIs(29).heightIs(17);
    self.imaegViewVIP.sd_layout.rightSpaceToView(self.contentView, 0).topSpaceToView(self.contentView, 0).widthIs(30).heightIs(18);
    [self.imaegView addSubview:self.labelTag];
    self.labelTag.sd_layout.rightSpaceToView(self.imaegView, 0).bottomSpaceToView(self.imaegView, 6).leftSpaceToView(self.imaegView, 5).heightIs(12);
    [self.imaegView addSubview:self.labelScore];
    self.labelScore.sd_layout.rightSpaceToView(self.imaegView, 5).bottomSpaceToView(self.imaegView, 6).leftSpaceToView(self.imaegView, 0).heightIs(12);
}
- (CGFloat)fetchLabelHeight:(NSString *)string fontSize:(NSInteger)fontSize width:(float)width {
    NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
    CGRect rect =  [string boundingRectWithSize:CGSizeMake(width, 0) options:NSStringDrawingUsesLineFragmentOrigin |
                    NSStringDrawingUsesFontLeading attributes:dic context:nil];
    return rect.size.height;
}
- (void)setData:(NSDictionary *)data {
    _data = data;
    if (data) {
        [_imaegView setYthImageWithURL:data[@"Vpicture"] placeholderImage:nil];
        NSString *conetnt = data[@"Name"];
        self.labelTag.text = [NSString stringWithFormat:@"%@",data[@"Tag"]];
        if (data[@"Score"]) {
            NSMutableAttributedString *noteStr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@分",data[@"Score"]]];
            NSRange range1 = NSMakeRange(0, 0);
            NSRange range2 = NSMakeRange(0, 0);
            if ([((NSString *)data[@"Score"]) containsString:@"."]) {
                range1 = [[NSString stringWithFormat:@"%@分",data[@"Score"]] rangeOfString:@"."];
                range2 = NSMakeRange(range1.location+1, 2);
            } else {
                range2 = NSMakeRange(0, [NSString stringWithFormat:@"%@分",data[@"Score"]].length);
            }
            [noteStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:9] range:range2];
            [ self.labelScore setAttributedText:noteStr];
        }
        self.labelTitle.text = conetnt;
        self.labelTitle.numberOfLines = 2;
        CGFloat height = [self fetchLabelHeight:conetnt fontSize:14 width:(KScreenW - 9 - 6 - 6 - 9) / 3];
        if (height > 34) {
            height = 34;
        }
        self.labelTitle.sd_resetLayout.leftSpaceToView(self.contentView, 0).topSpaceToView(self.imaegView, 6).rightSpaceToView(self.contentView, 0).heightIs(height);
    }
}
- (UIImageView *)imaegView {
    if (!_imaegView) {
        _imaegView = [[UIImageView alloc] init];
        [_imaegView setContentScaleFactor:[[UIScreen mainScreen] scale]];
        _imaegView.contentMode =  UIViewContentModeScaleAspectFill;
        _imaegView.clipsToBounds  = YES;
        _imaegView.backgroundColor = UICOLOR_FROM_RGB(0xe0e0e0, 1);
    }
    return _imaegView;
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.textColor = UICOLOR_FROM_RGB(0x000000, 1);
        _labelTitle.font = [UIFont systemFontOfSize:14];
        _labelTitle.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTitle;
}
- (UIImageView *)imaegViewGQ {
    if (!_imaegViewGQ) {
        _imaegViewGQ = [[UIImageView alloc] init];
        _imaegViewGQ.image = [UIImage imageNamed:@"home_recommend_gq"];
        [_imaegViewGQ setContentScaleFactor:[[UIScreen mainScreen] scale]];
        _imaegViewGQ.contentMode =  UIViewContentModeScaleAspectFill;
        _imaegViewGQ.clipsToBounds  = YES;
    }
    return _imaegViewGQ;
}
- (UIImageView *)imaegViewVIP {
    if (!_imaegViewVIP) {
        _imaegViewVIP = [[UIImageView alloc] init];
        _imaegViewVIP.image = [UIImage imageNamed:@"home_recommend_vip"];
        [_imaegViewVIP setContentScaleFactor:[[UIScreen mainScreen] scale]];
        _imaegViewVIP.contentMode =  UIViewContentModeScaleAspectFill;
        _imaegViewVIP.clipsToBounds  = YES;
    }
    return _imaegViewVIP;
}
- (UILabel *)labelTag {
    if (!_labelTag) {
        _labelTag = [[UILabel alloc] init];
        _labelTag.textColor = [UIColor whiteColor];
        _labelTag.font = [UIFont systemFontOfSize:12];
        _labelTag.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTag;
}
- (UILabel *)labelScore {
    if (!_labelScore) {
        _labelScore = [[UILabel alloc] init];
        _labelScore.textColor = [UIColor colorWithRed:246/255.0 green:213/255.0 blue:141/255.0 alpha:1];
        _labelScore.font = [UIFont systemFontOfSize:13];
        _labelScore.textAlignment = NSTextAlignmentRight;
    }
    return _labelScore;
}
@end
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendTwoColumnCell.h
New file
@@ -0,0 +1,19 @@
//
//  RecommendTwoColumnCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface RecommendTwoColumnCell : UICollectionViewCell
@property (nonatomic, nullable, strong) NSDictionary *data;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/Cell/RecommendTwoColumnCell.m
New file
@@ -0,0 +1,122 @@
//
//  RecommendTwoColumnCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecommendTwoColumnCell.h"
@interface RecommendTwoColumnCell ()
@property (nonatomic, nullable, strong) UIImageView *imaegView;
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@property (nonatomic, nullable, strong) UILabel *labelTag;
@property (nonatomic, nullable, strong) UILabel *labelScore;
@end
@implementation RecommendTwoColumnCell
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.contentView.backgroundColor = [UIColor whiteColor];
        [self setuoViewConfig];
    }
    return self;
}
- (void)setuoViewConfig {
    [self.contentView addSubview:self.imaegView];
    [self.contentView addSubview:self.labelTitle];
    self.imaegView.sd_layout.leftEqualToView(self.contentView).topEqualToView(self.contentView).rightEqualToView(self.contentView).heightIs(99);
    self.imaegView.sd_cornerRadius = @6;
    self.labelTitle.sd_layout.leftSpaceToView(self.contentView, 0).topSpaceToView(self.imaegView, 6).rightSpaceToView(self.contentView, 0).heightIs(0);
    [self.imaegView addSubview:self.labelTag];
    self.labelTag.sd_layout.leftSpaceToView(self.imaegView, 4).bottomSpaceToView(self.imaegView, 6).rightSpaceToView(self.imaegView, 0).heightIs(12);
    [self.imaegView addSubview:self.labelScore];
    self.labelScore.sd_layout.rightSpaceToView(self.imaegView, 5).bottomSpaceToView(self.imaegView, 6).leftSpaceToView(self.imaegView, 0).heightIs(12);
}
- (void)setData:(NSDictionary *)data {
    _data = data;
    if (data) {
        [_imaegView setYthImageWithURL:data[@"Hpicture"] placeholderImage:nil];
        self.labelTag.text = data[@"Tag"];
        if (data[@"Score"]) {
            NSMutableAttributedString *noteStr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@分",data[@"Score"]]];
            NSRange range1 = [[NSString stringWithFormat:@"%@分",data[@"Score"]] rangeOfString:@"."];
            NSRange range2 = NSMakeRange(range1.location+1, 2);
            [noteStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:9] range:range2];
            [ self.labelScore setAttributedText:noteStr];
        }
        NSString *conetnt = data[@"Name"];
        self.labelTitle.text = conetnt;
        self.labelTitle.numberOfLines = 2;
        CGFloat height = [self fetchLabelHeight:conetnt fontSize:14 width:(KScreenW - 9 - 8 - 9) / 2];
        if (height > 34) {
            height = 34;
        }
        self.labelTitle.sd_resetLayout.leftSpaceToView(self.contentView, 0).topSpaceToView(self.imaegView, 6).rightSpaceToView(self.contentView, 0).heightIs(height);
    }
}
- (CGFloat)fetchLabelHeight:(NSString *)string fontSize:(NSInteger)fontSize width:(float)width {
    NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
    CGRect rect =  [string boundingRectWithSize:CGSizeMake(width, 0) options:NSStringDrawingUsesLineFragmentOrigin |
                    NSStringDrawingUsesFontLeading attributes:dic context:nil];
    return rect.size.height;
}
- (UIImageView *)imaegView {
    if (!_imaegView) {
        _imaegView = [[UIImageView alloc] init];
        [_imaegView setContentScaleFactor:[[UIScreen mainScreen] scale]];
        _imaegView.contentMode =  UIViewContentModeScaleAspectFill;
        _imaegView.clipsToBounds  = YES;
    }
    return _imaegView;
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.textColor = UICOLOR_FROM_RGB(0x000000, 1);
        _labelTitle.font = [UIFont systemFontOfSize:14];
        _labelTitle.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTitle;
}
- (UILabel *)labelTag {
    if (!_labelTag) {
        _labelTag = [[UILabel alloc] init];
        _labelTag.textColor = [UIColor whiteColor];
        _labelTag.font = [UIFont systemFontOfSize:12];
        _labelTag.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTag;
}
- (UILabel *)labelScore {
    if (!_labelScore) {
        _labelScore = [[UILabel alloc] init];
        _labelScore.textColor = [UIColor colorWithRed:246/255.0 green:213/255.0 blue:141/255.0 alpha:1];
        _labelScore.font = [UIFont systemFontOfSize:13];
        _labelScore.textAlignment = NSTextAlignmentRight;
    }
    return _labelScore;
}
@end
BuWanVideo2.0/Recommend/Recommend/Cell/RecpmmendTitleView.h
New file
@@ -0,0 +1,28 @@
//
//  RecpmmendTitleView.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "RecommendDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface RecpmmendTitleView : UICollectionReusableView
@property (nonatomic, weak) id<RecommendDelegate>delegate;
@property (nonatomic, nullable, strong) NSDictionary *data;
@property (nonatomic, assign) NSUInteger index;
/// æ˜¯å¦æœ‰è½®æ’­å›¾
@property (nonatomic , assign) BOOL isBanaer;
@property (nonatomic, nullable, strong) NSArray *arrayImage;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/Cell/RecpmmendTitleView.m
New file
@@ -0,0 +1,212 @@
//
//  RecpmmendTitleView.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecpmmendTitleView.h"
#import "SDCycleScrollView.h"
@interface RecpmmendTitleView () <SDCycleScrollViewDelegate>
@property (nonatomic, nullable, strong) UIView *viewTopBG;
@property (nonatomic, nullable, strong) UIView *viewBanaer;
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@property (nonatomic, nullable, strong) UIButton *buttonChange;
@property (nonatomic, nullable, strong) UIButton *buttonMore;
@property (nonatomic, nullable, strong) UILabel *labelContent;
@property (nonatomic, nullable, strong) UILabel *labelTag;
@end
@implementation RecpmmendTitleView
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        [self setupDataConfig];
        [self setupViewConfig];
    }
    return self;
}
- (void)setupDataConfig {
}
- (void)setupViewConfig {
    [self addSubview:self.viewTopBG];
    self.viewBanaer.frame = CGRectMake(0, 47, KScreenW, 196);
    [self addSubview:self.viewBanaer];
    [self.viewTopBG addSubview:self.labelTitle];
    [self.viewTopBG addSubview:self.buttonChange];
    [self.viewTopBG addSubview:self.buttonMore];
    [self addSubview:self.labelContent];
    self.viewTopBG.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, 0).rightSpaceToView(self, 0).heightIs(47);
    //self.viewBanaer.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, 47).rightSpaceToView(self, 0).heightIs(196);
    self.labelTitle.sd_layout.leftSpaceToView(self.viewTopBG, 10).topSpaceToView(self.viewTopBG, 22).autoWidthRatio(0).heightIs(16);
    [self.labelTitle setSingleLineAutoResizeWithMaxWidth:200];
    self.buttonChange.sd_layout.rightSpaceToView(self.viewTopBG, 9).topSpaceToView(self.viewTopBG, 20).widthIs(73).heightIs(21);
    self.buttonChange.sd_cornerRadius = @10.5;
    self.buttonMore.sd_layout.rightSpaceToView(self.viewTopBG, 9).topSpaceToView(self.viewTopBG, 20).widthIs(96).heightIs(21);
    self.buttonMore.sd_cornerRadius = @10.5;
    [ self.buttonMore setSemanticContentAttribute:UISemanticContentAttributeForceRightToLeft];
    //设置图片和文字之间的间隙
    self.buttonMore.imageEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
    self.labelContent.sd_layout.leftSpaceToView(self, 10).topSpaceToView(self.viewBanaer, 5).rightSpaceToView(self, 10).autoHeightRatio(0);
    [self addSubview:self.labelTag];
    self.labelTag.sd_layout.leftSpaceToView(self, 14).topSpaceToView(self, 220).rightSpaceToView(self, 10).heightIs(12);
}
- (void)setIsBanaer:(BOOL)isBanaer {
    _isBanaer = isBanaer;
}
- (void)setData:(NSDictionary *)data {
    _data = data;
    if (data) {
        self.labelTitle.text = data[@"Name"];
        self.labelTag.text = data[@"HomeVideoList"][0][@"Video"][@"Tag"];
        self.arrayImage = @[data[@"HomeVideoList"][0][@"Video"][@"Hpicture"]];
        self.labelContent.text = data[@"HomeVideoList"][0][@"Video"][@"Name"];
        if ([data[@"RefreshPosition"] intValue] == 0 || [data[@"RefreshPosition"] intValue] == 2) {
            self.buttonChange.hidden = YES;
        } else {
            self.buttonChange.hidden = NO;
        }
        for (__strong UIView *view in [self.viewBanaer subviews]) {
            [view removeFromSuperview];
            view = nil;
        }
        if (_isBanaer) {
            self.viewBanaer.hidden = NO;
            self.labelContent.hidden = NO;
            self.labelTag.hidden = NO;
            CGRect frame = CGRectMake(10, 0, KScreenW - 20, 196);
            SDCycleScrollView *cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:frame delegate:self placeholderImage:nil];
            cycleScrollView.imageURLStringsGroup = _arrayImage;
            cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleClassic;
            cycleScrollView.pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
            cycleScrollView.autoScrollTimeInterval = 5.0f;
            cycleScrollView.currentPageDotColor = UICOLOR_FROM_RGB(0x159FFF, 1.0);
            cycleScrollView.pageDotColor = UICOLOR_FROM_RGB(0xffffff, 0.5);
            cycleScrollView.pageControlBottomOffset = 5;
            cycleScrollView.layer.masksToBounds = YES;
            cycleScrollView.layer.cornerRadius = 8;
            cycleScrollView.infiniteLoop = NO;
            [self.viewBanaer addSubview:cycleScrollView];
        } else {
            self.viewBanaer.hidden = YES;
            self.labelContent.hidden = YES;
            self.labelTag.hidden = YES;
        }
    }
}
- (void)eventChange {
    if (_delegate && [_delegate respondsToSelector:@selector(onEventChange:page:index:pages:)]) {
        [_delegate onEventChange:_data[@"Id"] page:[_data[@"page"] integerValue] index:_index pages:_data[@"page"]];
    }
}
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index {
    //    NSDictionary *dictionary = [ALShareManager shareManger].find_banner[index];
    //    if (_delegate && [_delegate respondsToSelector:@selector(touchTopBanner:)]) {
    //        [_delegate touchTopBanner:dictionary];
    //    }
}
- (UIView *)viewTopBG {
    if (!_viewTopBG) {
        _viewTopBG = [[UIView alloc] init];
        _viewTopBG.backgroundColor = [UIColor whiteColor];
    }
    return _viewTopBG;;
}
- (UIView *)viewBanaer {
    if (!_viewBanaer) {
        _viewBanaer = [[UIView alloc] init];
        _viewBanaer.backgroundColor = [UIColor whiteColor];
    }
    return _viewBanaer;;
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.font = [UIFont systemFontOfSize:16];
        _labelTitle.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTitle;;
}
- (UILabel *)labelContent {
    if (!_labelContent) {
        _labelContent = [[UILabel alloc] init];
        _labelContent.textColor = UICOLOR_FROM_RGB(0x000000, 1);
        _labelContent.font = [UIFont systemFontOfSize:14];
        _labelContent.textAlignment = NSTextAlignmentLeft;
    }
    return _labelContent;
}
- (UIButton *)buttonChange {
    if (!_buttonChange) {
        _buttonChange = [UIButton buttonWithType:UIButtonTypeCustom];
        [_buttonChange setImage:[UIImage imageNamed:@"home_recommend_change"] forState:UIControlStateNormal];
        [_buttonChange setTitle:@"  æ¢ä¸€æ‰¹" forState:UIControlStateNormal];
        _buttonChange.titleLabel.font = [UIFont systemFontOfSize:10];
        [_buttonChange setTitleColor:UICOLOR_FROM_RGB(0x666666, 1) forState:UIControlStateNormal];
        _buttonChange.backgroundColor = UICOLOR_FROM_RGB(0xE9F0FF, 1);
        [_buttonChange addTarget:self action:@selector(eventChange) forControlEvents:UIControlEventTouchUpInside];
    }
    return _buttonChange;
}
- (UIButton *)buttonMore {
    if (!_buttonMore) {
        _buttonMore = [UIButton buttonWithType:UIButtonTypeCustom];
        [_buttonMore setImage:[UIImage imageNamed:@"home_recommend_more"] forState:UIControlStateNormal];
        [_buttonMore setTitle:@"更多免费热剧" forState:UIControlStateNormal];
        _buttonMore.titleLabel.font = [UIFont systemFontOfSize:10];
        [_buttonMore setTitleColor:UICOLOR_FROM_RGB(0x666666, 1) forState:UIControlStateNormal];
        _buttonMore.backgroundColor = UICOLOR_FROM_RGB(0xE9F0FF, 1);
        _buttonMore.hidden = YES;
    }
    return _buttonMore;
}
- (UILabel *)labelTag {
    if (!_labelTag) {
        _labelTag = [[UILabel alloc] init];
        _labelTag.textColor = [UIColor whiteColor];
        _labelTag.font = [UIFont systemFontOfSize:12];
        _labelTag.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTag;
}
@end
BuWanVideo2.0/Recommend/Recommend/Cell/ToDayHotCell.h
New file
@@ -0,0 +1,19 @@
//
//  ToDayHotCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ToDayHotCell : UICollectionViewCell
@property (nonatomic, nullable, strong) NSDictionary *data;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/Cell/ToDayHotCell.m
New file
@@ -0,0 +1,101 @@
//
//  ToDayHotCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/29.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "ToDayHotCell.h"
#define BSKPlaceHolderImage [UIImage imageNamed:@"默认加载图片"]
@interface ToDayHotCell ()
@property (nonatomic, nullable, strong) UIScrollView *scrollView;
@end
@implementation ToDayHotCell
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        [self setupDataConfig];
        [self setupCellConfig];
    }
    return self;
}
- (void)setupDataConfig {
}
- (void)setupCellConfig {
    [self addSubview:self.scrollView];
    self.scrollView.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, 0).rightSpaceToView(self, 0).bottomSpaceToView(self, 0);
}
- (void)setData:(NSDictionary *)data {
    _data = data;
    if (_data) {
        NSArray *homeVideoList = data[@"HomeVideoList"];
        for (__strong UIView *view in [self.scrollView subviews]) {
            [view removeFromSuperview];
            view = nil;
        }
        [self.scrollView setContentOffset:CGPointMake(0, 0)];
        for (int i = 0; i < homeVideoList.count; i++) {
            NSDictionary *video = homeVideoList[i][@"Video"];
            UIView *viewBG = [[UIView alloc] init];
            [self.scrollView addSubview:viewBG];
            viewBG.sd_layout.leftSpaceToView(self.scrollView, 9 + 150 * i + 8 * i).topSpaceToView(self.scrollView, 0).widthIs(150).bottomSpaceToView(self.scrollView, 0);
            UIImageView *imgView = [[UIImageView alloc] init];
            [imgView setContentScaleFactor:[[UIScreen mainScreen] scale]];
            imgView.contentMode = UIViewContentModeScaleAspectFill;
            imgView.clipsToBounds = YES;
            [viewBG addSubview:imgView];
            imgView.sd_layout.leftSpaceToView(viewBG, 0).topSpaceToView(viewBG, 0).rightSpaceToView(viewBG, 0).heightIs(99);
            imgView.sd_cornerRadius = @6;
            NSString *conetnt = video[@"Name"];
            UILabel *labelTitle = [[UILabel alloc] init];
            labelTitle.text = conetnt;
            labelTitle.font = [UIFont systemFontOfSize:14];
            labelTitle.textAlignment = NSTextAlignmentLeft;
            labelTitle.textColor = UIColorFromRGBValue(0x000000);
            labelTitle.numberOfLines = 2;
            [viewBG addSubview:labelTitle];
            CGFloat height = [self fetchLabelHeight:conetnt fontSize:14 width:150];
            if (height > 34) {
                height = 34;
            }
            labelTitle.sd_layout.leftSpaceToView(viewBG, 0).topSpaceToView(imgView, 6).rightSpaceToView(viewBG, 0).heightIs(height);
            [imgView setYthImageWithURL:video[@"Picture"] placeholderImage:nil];
        }
        self.scrollView.contentSize = CGSizeMake(9 + 150 * homeVideoList.count + 8 * (homeVideoList.count-1) + 9, 140);
    }
}
- (CGFloat)fetchLabelHeight:(NSString *)string fontSize:(NSInteger)fontSize width:(float)width {
    NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
    CGRect rect =  [string boundingRectWithSize:CGSizeMake(width, 0) options:NSStringDrawingUsesLineFragmentOrigin |
                    NSStringDrawingUsesFontLeading attributes:dic context:nil];
    return rect.size.height;
}
- (UIScrollView *)scrollView {
    if (!_scrollView) {
        _scrollView = [[UIScrollView alloc] init];
        _scrollView.showsHorizontalScrollIndicator = NO;
    }
    return _scrollView;
}
@end
BuWanVideo2.0/Recommend/Recommend/Delegate/RecommendDelegate.h
New file
@@ -0,0 +1,20 @@
//
//  RecommendDelegate.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/6/5.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol RecommendDelegate <NSObject>
- (void)onEventChange:(NSString *)vid page:(NSUInteger)page index:(NSInteger)index pages:(NSString *)pages;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/RecommendController.h
New file
@@ -0,0 +1,20 @@
//
//  RecommendController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "BaseController.h"
#import "ZJScrollPageView.h"
NS_ASSUME_NONNULL_BEGIN
@interface RecommendController : BaseController <ZJScrollPageViewChildVcDelegate>
@property (nonatomic, nullable, strong) NSDictionary *parms;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/Recommend/RecommendController.m
New file
@@ -0,0 +1,416 @@
//
//  RecommendController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/24.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecommendController.h"
#import "RecommendHeaderViewCell.h"
#import "ToDayHotCell.h"
#import "RecommendTwoColumnCell.h"
#import "RecommendThreeColumnCell.h"
#import "RecpmmendTitleView.h"
#import "RecommendChangeFooterView.h"
#import "UICollectionViewLeftAlignedLayout.h"
@interface RecommendController () <UICollectionViewDelegate, UICollectionViewDataSource, RecommendDelegate>
@property (nonatomic, nullable, strong) UICollectionView *collectionView;
@property (nonatomic, nullable, strong) RecommendHeaderViewCell *cellRecommendHeader;
@property (nonatomic, assign) NSUInteger page;
@property (nonatomic, nullable, strong) NSDictionary *dictionaryBanaer;
@property (nonatomic, nullable, strong) NSArray *arrayTemp;
@property (nonatomic, nullable, strong) NSMutableArray *arrayContent;
@property (nonatomic, assign) NSUInteger count;
@end
@implementation RecommendController
- (BOOL)shouldAutomaticallyForwardAppearanceMethods{
    return NO;
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.cellRecommendHeader open];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.cellRecommendHeader close];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupDataConfig];
    [self setupViewConfig];
    [self getHomeAd];
}
- (void)setupDataConfig {
    self.page = 1;
}
- (void)setupViewConfig {
    [self.view addSubview:self.collectionView];
}
-(void)getHomeAd{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    // åˆ›å»ºå…¨å±€å¹¶è¡Œ
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        [[YTHNetInterface startInterface] getHomeAdWithUid:[YTHsharedManger startManger].Uid vtid:_parms[@"Id"] withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) {
            if (isSuccessful) {
                NSDictionary *dic = (NSDictionary *)result;
                self.dictionaryBanaer = dic[@"Data"];
            }
            dispatch_semaphore_signal(semaphore);
        }];
    });
    dispatch_group_async(group, queue, ^{
        [[YTHNetInterface startInterface] getHomeTypeWithUid:[YTHsharedManger startManger].Uid vtid:_parms[@"Id"] withSystem:@"1" DataKey:_parms[@"DataKey"] PageSize:10 Page:_page withBlock:^(BOOL isSuccessful, id result, NSString *error) {
            if (isSuccessful) {
                if (_page == 1) {
                    [self.arrayContent removeAllObjects];
                }
                self.arrayTemp = result[@"Data"][@"data"];
                self.count = [result[@"Data"][@"count"] integerValue];
                self.page++;
                if (self.count == self.arrayContent.count) {
                    [self hideFooger];
                } else {
                    if (!self.collectionView.mj_footer) {
                        [self setFooterRefresh];
                    }
                }
            }
            dispatch_semaphore_signal(semaphore);
        }];
    });
    dispatch_group_notify(group, queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.arrayContent addObjectsFromArray:self.arrayTemp];
            [self.collectionView reloadData];
        });
    });
}
- (void)loadFooter:(void(^)(void))handel {
    [[YTHNetInterface startInterface] getHomeTypeWithUid:[YTHsharedManger startManger].Uid vtid:_parms[@"Id"] withSystem:@"1" DataKey:_parms[@"DataKey"] PageSize:10 Page:_page withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            if (_page == 1) {
                [self.arrayContent removeAllObjects];
            }
            self.arrayTemp = result[@"Data"][@"data"];
            self.count = [result[@"Data"][@"count"] integerValue];
            self.page++;
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.arrayContent addObjectsFromArray:self.arrayTemp];
                [self.collectionView reloadData];
            });
        }
        [self.collectionView.mj_header endRefreshing];
        [self.collectionView.mj_footer endRefreshing];
        if (self.count == self.arrayContent.count) {
            [self hideFooger];
        } else {
            if (!self.collectionView.mj_footer) {
                [self setFooterRefresh];
            }
        }
        handel();
    }];
}
- (void)changeData:(NSString *)vid page:(NSUInteger)page index:(NSInteger)index {
    [[YTHNetInterface startInterface] getVideoRecommendWithUid:vid Page:page WithSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            NSMutableDictionary *parms = [[NSMutableDictionary alloc] initWithDictionary:self.arrayContent[index-1]];
            parms[@"page"] = result[@"Data"][@"page"];
            parms[@"HomeVideoList"] = result[@"Data"][@"list"];
            self.arrayContent[index-1] = parms;
            [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:index]];
        }
    }];
}
- (void)onEventChange:(NSString *)vid page:(NSUInteger)page index:(NSInteger)index pages:(nonnull NSString *)pages {
    if (!pages) {
        page = 1;
    }
    page+=1;
    [self changeData:vid page:page index:index];
}
- (void)hideFooger {
    self.collectionView.mj_footer = nil;
}
- (void)setFooterRefresh {
    self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
        [self loadFooter:^{
        }];
    }];
}
#pragma mark UICollectionViewDelegate, UICollectionViewDataSource
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    //[self cellClick:indexPath];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return self.arrayContent.count+1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section == 0) {
        return 1;
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2 || Columns == 3) {
            BOOL BigPicture = [self.arrayContent[section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            if (BigPicture) {
                return [self.arrayContent[section-1][@"HomeVideoList"] count]-1;
            }
            return [self.arrayContent[section-1][@"HomeVideoList"] count];
        }
    }
    return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        if (!self.cellRecommendHeader) {
            self.cellRecommendHeader = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendHeaderViewCell" forIndexPath:indexPath];
        }
        self.cellRecommendHeader.arrayImageData = self.dictionaryBanaer;
        return self.cellRecommendHeader;
    } else {
        NSUInteger Columns = [self.arrayContent[indexPath.section-1][@"Columns"] integerValue];
        if (Columns > 3) {
            ToDayHotCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ToDayHotCell" forIndexPath:indexPath];
            cell.data = self.arrayContent[indexPath.section-1];
            return cell;
        } else if (Columns == 2) {
            RecommendTwoColumnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendTwoColumnCell" forIndexPath:indexPath];
            BOOL BigPicture = [self.arrayContent[indexPath.section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            if (BigPicture) {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row+1][@"Video"];
            } else {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row][@"Video"];
            }
            return cell;
        } else if (Columns == 3) {
            RecommendThreeColumnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"RecommendThreeColumnCell" forIndexPath:indexPath];
            BOOL BigPicture = [self.arrayContent[indexPath.section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            if (BigPicture) {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row+1][@"Video"];
            } else {
                cell.data = self.arrayContent[indexPath.section-1][@"HomeVideoList"][indexPath.row][@"Video"];
            }
            return cell;
        }
    }
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
    return cell;
}
// å®šåˆ¶collectionView的head和foot
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    if (kind == UICollectionElementKindSectionHeader) {
        if (indexPath.section > 0) {
            RecpmmendTitleView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView" forIndexPath:indexPath];
            view.delegate = self;
            BOOL BigPicture = [self.arrayContent[indexPath.section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
            view.isBanaer = BigPicture;
            view.data = self.arrayContent[indexPath.section-1];
            view.index = indexPath.section;
            return view;
        }
    } else {
        if (indexPath.section > 1) {
            NSDictionary *data = self.arrayContent[indexPath.section-1];
            if ([data[@"RefreshPosition"] integerValue] == 2) {
                RecommendChangeFooterView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"RecommendChangeFooterView" forIndexPath:indexPath];
                view.delegate = self;
                view.data = data;
                view.position = indexPath.section;
                return view;
            }
        }
    }
    UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView" forIndexPath:indexPath];
    return view;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
    //宽度随便定,系统会自动取collectionView的宽度
    //高度为分组头的高度
    if (section > 0) {
        BOOL BigPicture = [self.arrayContent[section-1][@"HomeVideoList"][0][@"BigPicture"] boolValue];
        if (BigPicture) {
            return CGSizeMake(KScreenW, 216 + 40 + 30);
        }
        return CGSizeMake(KScreenW, 47);
    }
    return CGSizeMake(0, 0);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    if (section == 0) {
        return CGSizeMake(CGFLOAT_MIN, CGFLOAT_MIN);
    }
    NSUInteger Columns = [self.arrayContent[section-1][@"RefreshPosition"] integerValue];
    if (Columns == 2) {
        return CGSizeMake(KScreenW, 41);
    } else {
        return CGSizeMake(CGFLOAT_MIN, CGFLOAT_MIN);
    }
  }
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        CGFloat bannerSizeRate = [self.dictionaryBanaer[@"bannerSizeRate"] doubleValue];
        return  CGSizeMake(KScreenW, 5 + (156 * bannerSizeRate));
    } else {
        NSUInteger Columns = [self.arrayContent[indexPath.section-1][@"Columns"] integerValue];
        if (Columns > 3) {
            return  CGSizeMake(KScreenW, 140);
        } else if (Columns == 2) {
            return  CGSizeMake((KScreenW - 9 - 9 - 8) / 2, 140);
        } else if (Columns == 3) {
            return  CGSizeMake((KScreenW - 9 - 9 - 6 - 6) / 3, 201);
        }
    }
    return  CGSizeMake(KScreenW, 35);
}
//协议中的方法,用于返回整个CollectionView上、左、下、右距四边的间距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    if (section == 0) {
        return UIEdgeInsetsMake(0, 0, 0, 0);
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2 || Columns == 3) {
            return UIEdgeInsetsMake(5, 9, 0, 9);
        } else if (Columns == 3) {
            return UIEdgeInsetsMake(0, 9, 0, 9);
        }
    }
    return UIEdgeInsetsMake(0, 0, 0, 0);
}
//两行cell之间的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 0) {
        return 0;
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2) {
            return 12;
        } else if (Columns == 3) {
            return 10;
        }
    }
    return 0;;
}
//同一行两个cell的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 0) {
        return 0;
    } else {
        NSUInteger Columns = [self.arrayContent[section-1][@"Columns"] integerValue];
        if (Columns == 2) {
            return 8;
        } else if (Columns == 3) {
            return 6;
        }
    }
    return 0;
}
- (UICollectionView *)collectionView {
    if (!_collectionView) {
        UICollectionViewLeftAlignedLayout *flow = [[UICollectionViewLeftAlignedLayout alloc] init];
        //指定布局方式为垂直
        flow.scrollDirection = UICollectionViewScrollDirectionVertical;
        // STATUSBAR_HEIGHT + 27
        //创建CollectionView并指定布局对象
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0,  KScreenW, KScreenH - ALTabBar_H - kStatusBarH - ALNavBarH - 36) collectionViewLayout:flow];
        _collectionView.backgroundColor = [UIColor whiteColor];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        _collectionView.delaysContentTouches = NO;
        _collectionView.showsVerticalScrollIndicator = NO;
        [_collectionView registerClass:[RecommendHeaderViewCell class] forCellWithReuseIdentifier:@"RecommendHeaderViewCell"];
        [_collectionView registerClass:[ToDayHotCell class] forCellWithReuseIdentifier:@"ToDayHotCell"];
        [_collectionView registerClass:[RecommendTwoColumnCell class] forCellWithReuseIdentifier:@"RecommendTwoColumnCell"];
        [_collectionView registerClass:[RecommendThreeColumnCell class] forCellWithReuseIdentifier:@"RecommendThreeColumnCell"];
        [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
         [_collectionView registerClass:[RecpmmendTitleView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"RecpmmendTitleView"];
        [_collectionView registerClass:[RecommendChangeFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"RecommendChangeFooterView"];
         [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView"];
    }
    return _collectionView;
}
- (NSMutableArray *)arrayContent {
    if (!_arrayContent) {
        _arrayContent = [[NSMutableArray alloc] init];
    }
    return _arrayContent;
}
@end
BuWanVideo2.0/Recommend/RecommendMainController.h
New file
@@ -0,0 +1,17 @@
//
//  RecommendController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/23.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "MainBaseController.h"
NS_ASSUME_NONNULL_BEGIN
@interface RecommendMainController : MainBaseController
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/RecommendMainController.m
New file
@@ -0,0 +1,154 @@
//
//  RecommendController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/23.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecommendMainController.h"
#import "RecommendController.h"
#import "LifeHomeController.h"
#import "HDController.h"
#import "ListController.h"
@interface RecommendMainController () <ZJScrollPageViewDelegate>
@property(nonatomic, nullable, strong) ZJScrollPageView *scrollPageView;
@property (nonatomic, nullable, strong) NSMutableArray *arrayClassName;
@property (nonatomic, nullable, strong) NSMutableArray *arrayKeyName;
@end
@implementation RecommendMainController
- (instancetype)init {
    self = [super init];
    if (self) {
        self.title = @"精选";
    }
    return self;
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    self.navigationController.navigationBar.translucent = NO;
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setuoDataConfig];
    [self loadDataFromFile];
}
- (void)setuoDataConfig {
}
-(void)loadDataFromFile{
    [[YTHNetInterface startInterface]cancelAll];
    [[YTHNetInterface startInterface] getVideoClassWithUid:[YTHsharedManger startManger].Uid WithSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            for (int i = 0; i < [result[@"Data"][@"data"] count]; i++) {
                [self.arrayClassName addObject:result[@"Data"][@"data"][i][@"Name"]];
                [self.arrayKeyName addObject:result[@"Data"][@"data"][i]];
            }
            [self setupViewConfig];
        }
    }];
}
- (void)setupViewConfig {
    [self setupContentView];
}
- (void)setupContentView {
    if (self.scrollPageView) {
        [self.scrollPageView removeFromSuperview];
    }
    ZJSegmentStyle *style = [[ZJSegmentStyle alloc] init];
    // ç¼©æ”¾æ ‡é¢˜
    style.scaleTitle = YES;
    // é¢œè‰²æ¸å˜
    style.gradualChangeTitleColor = YES;
    // é€‰ä¸­å­—体的颜色
    style.selectedTitleColor = UICOLOR_FROM_RGB(0x159FFF, 1);
    // æ ‡é¢˜ä¸€èˆ¬çŠ¶æ€çš„é¢œè‰²
    style.normalTitleColor = UICOLOR_FROM_RGB(0x3B3B3B, 1);
    // æ ‡é¢˜ä¹‹é—´çš„é—´éš™
    style.titleMargin = 23;
    // æ”¾å¤§å€æ•°
    style.titleBigScale = 1.3;
    // å­—体
    style.titleFont = [UIFont systemFontOfSize:14];
    // è®¾ç½®segment的高度
    style.segmentHeight = 36;
    style.autoAdjustTitlesWidth = YES;
    // åˆå§‹åŒ–
    ZJScrollPageView *scrollPageView = [[ZJScrollPageView alloc] initWithFrame:CGRectMake(0, kStatusBarH + ALNavBarH, KScreenW, KScreenH - kStatusBarH - ALNavBarH - ALTabBar_H) segmentStyle:style titles:self.arrayClassName parentViewController:self delegate:self];
    self.scrollPageView = scrollPageView;
    [self.view addSubview:self.scrollPageView];
}
#pragma mark --- ZJScrollPageViewDelegate ---
- (NSInteger)numberOfChildViewControllers {
    return self.arrayClassName.count;
}
- (UIViewController<ZJScrollPageViewChildVcDelegate> *)childViewController:(UIViewController<ZJScrollPageViewChildVcDelegate> *)reuseViewController forIndex:(NSInteger)index {
    UIViewController<ZJScrollPageViewChildVcDelegate> *childVc = reuseViewController;
    if (!childVc) {
        NSString *type = self.arrayKeyName[index][@"DataType"];
        if ([type containsString:@"recommend"]) {
            RecommendController *vc = [[RecommendController alloc] init];
            vc.parms = _arrayKeyName[index];
            childVc = vc;
        } else if ([type containsString:@"class"]) {
            ListController *vc = [[ListController alloc] init];
            vc.parms = _arrayKeyName[index];
            childVc = vc;
        }
        //        if (index == 0) {
        //
        //
        //        } else if (index == 1) {
        //            LifeHomeController *vc = [[LifeHomeController alloc] init];
        //            childVc = vc;
        //
        //        } else if (index == 2) {
        //            HDController *vc = [[HDController alloc] init];
        //            childVc = vc;
        //
        //        } else {
        //
        //        }
    }
    return childVc;
}
- (NSMutableArray *)arrayClassName {
    if (!_arrayClassName) {
        _arrayClassName = [[NSMutableArray alloc] init];
    }
    return _arrayClassName;
}
- (NSMutableArray *)arrayKeyName {
    if (!_arrayKeyName) {
        _arrayKeyName = [[NSMutableArray alloc] init];
    }
    return _arrayKeyName;
}
@end
BuWanVideo2.0/Recommend/View/RecommendNavView.h
New file
@@ -0,0 +1,22 @@
//
//  RecommendNavView.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/23.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef void(^onSearch)(void);
NS_ASSUME_NONNULL_BEGIN
@interface RecommendNavView : UIView
@property (nonatomic, nullable, copy) NSString *title;
@property (nonatomic) onSearch onSearch;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/Recommend/View/RecommendNavView.m
New file
@@ -0,0 +1,88 @@
//
//  RecommendNavView.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/23.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "RecommendNavView.h"
@interface RecommendNavView ()
@property (nonatomic, strong) UIView *viewNav;
@property (nonatomic, strong) UIView *viewSearch;
@end
@implementation RecommendNavView
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self addSubview:self.viewNav];
    self.viewNav.sd_layout.topSpaceToView(self, kStatusBarH).leftEqualToView(self).rightEqualToView(self).heightIs(44);
    //UIButton *buttonMore = [[UIButton alloc] init];
    //[buttonMore setImage:[UIImage imageNamed:@"home_more"] forState:UIControlStateNormal];
    //[self addSubview:buttonMore];
    //buttonMore.sd_layout.rightSpaceToView(self, 18).centerYEqualToView(_viewNav).widthIs(21).heightIs(24);
    UIButton *buttonRecord = [[UIButton alloc] init];
    [buttonRecord setImage:[UIImage imageNamed:@"home_record"] forState:UIControlStateNormal];
    [self addSubview:buttonRecord];
    buttonRecord.sd_layout.rightSpaceToView(self, 21).centerYEqualToView(_viewNav).widthIs(23).heightIs(23);
    [self.viewNav addSubview:self.viewSearch];
    self.viewSearch.sd_layout.leftSpaceToView(self.viewNav, 11).centerYEqualToView(self.viewNav).rightSpaceToView(buttonRecord, 21).heightIs(34);
    self.viewSearch.sd_cornerRadius = @17;
    UIImageView *imageViewSearch = [[UIImageView alloc] init];
    imageViewSearch.image = [UIImage imageNamed:@"home_search"];
    [_viewSearch addSubview:imageViewSearch];
    imageViewSearch.sd_layout.leftSpaceToView(_viewSearch, 13).centerYEqualToView(_viewSearch).widthIs(19).heightIs(19);
    UILabel *label = [[UILabel alloc] init];
    label.font = [UIFont systemFontOfSize:14];
    label.textAlignment = NSTextAlignmentLeft;
    label.textColor = UICOLOR_FROM_RGB(0x787878, 1);
    [_viewSearch addSubview:label];
    label.sd_layout.leftSpaceToView(imageViewSearch, 13).centerYEqualToView(_viewSearch).heightIs(20).rightSpaceToView(_viewSearch, 0);
}
- (void)touchSearch {
    !self.onSearch?:self.onSearch();
}
- (void)setTitle:(NSString *)title {
    _title = title;
    if (title) {
        UILabel *label = [self.viewSearch subviews][1];
        label.text = title;
    }
}
- (UIView *)viewNav {
    if (!_viewNav) {
        _viewNav = [[UIView alloc] init];
    }
    return _viewNav;
}
- (UIView *)viewSearch {
    if (!_viewSearch) {
        _viewSearch = [[UIView alloc] init];
        _viewSearch.backgroundColor = UICOLOR_FROM_RGB(0xEBEBEB, 1);
        _viewSearch.userInteractionEnabled = YES;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(touchSearch)];
        [_viewSearch addGestureRecognizer:tap];
    }
    return _viewSearch;
}
@end
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarousel.h
New file
@@ -0,0 +1,152 @@
//
//  CWCarousel.h
//  CWCarousel
//
//  Created by WangChen on 2018/4/3.
//  Copyright Â© 2018å¹´ ChenWang. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "CWCarouselProtocol.h"
#import "CWFlowLayout.h"
@interface CWCarousel : UIView
#pragma mark - < ç›¸å…³å±žæ€§ >
/**
 æŽ§ä»¶ç‰ˆæœ¬å·
 */
@property (nonatomic, readonly, copy) NSString                  * _Nullable version;
/**
 ç›¸å…³ä»£ç†
 */
@property (nonatomic, assign) id <CWCarouselDelegate> _Nullable delegate;
/**
 ç›¸å…³æ•°æ®æº
 */
@property (nonatomic, assign) id <CWCarouselDatasource> _Nullable datasource;
/**
 å¸ƒå±€è‡ªå®šä¹‰layout
 */
@property (nonatomic, strong, readonly) CWFlowLayout    * _Nonnull flowLayout;
/**
 æ ·å¼é£Žæ ¼
 */
@property (nonatomic, assign, readonly) CWCarouselStyle   style;
/**
 style = CWCarouselStyle_H_3时的扩展高度 (1.1.0版本后该属性废弃,请不要使用了)
 */
@property (nonatomic, assign, readonly) CGFloat           addHeight;
/**
 å®žé™…的示轮播图内容的视图(其实就是基于collectionView实现的)
 */
@property (nonatomic, strong, readonly) UICollectionView  * _Nonnull carouselView;
/**
 æ˜¯å¦è‡ªåŠ¨è½®æ’­, é»˜è®¤ä¸ºNO
 */
@property (nonatomic, assign) BOOL                        isAuto;
/**
 è‡ªåŠ¨è½®æ’­æ—¶é—´é—´éš”, é»˜è®¤ 3s
 */
@property (nonatomic, assign) NSTimeInterval              autoTimInterval;
/**
 é»˜è®¤çš„pageControl
 1. é»˜è®¤åœ¨æ°´å¹³å±…中正下方
 2. ä½ç½®å¯ä»¥è‡ªå·±æ ¹æ®frame自行调整
 3. å¦‚果不想将其添加在carousel上,请自行通过调用目标父视图的addSubview方法添加到其他父视图上
 */
@property (nonatomic, strong) UIPageControl               * _Nullable pageControl;
/**
 è‡ªå®šä¹‰çš„pageControl
 */
@property (nonatomic, strong) UIView<CWCarouselPageControlProtocol> * _Nullable customPageControl;
/**
 æ˜¯å¦å¼€å§‹æ— é™è½®æ’­
 YES: å¯ä»¥æ— é™è¡”接
 NO: æ»‘动到第一张或者最后一张就不能滑动了
 */
@property (nonatomic, assign) BOOL                        endless;
#pragma mark - < ç›¸å…³æ–¹æ³• >
/**
 åˆ›å»ºå®žä¾‹æž„造方法
 @param frame å°ºå¯¸å¤§å°
 @param delegate ä»£ç†
 @param datasource æ•°æ®æº
 @param flowLayout è‡ªå®šä¹‰flowlayout
 @return å®žä¾‹å¯¹è±¡
 */
- (instancetype _Nullable )initWithFrame:(CGRect)frame
                        delegate:(id<CWCarouselDelegate> _Nullable)delegate
                        datasource:(id<CWCarouselDatasource> _Nullable)datasource
                       flowLayout:(nonnull CWFlowLayout *)flowLayout;
/**
 æ³¨å†Œè‡ªå®šè§†å›¾
 @param viewClass è‡ªå®šä¹‰è§†å›¾ç±»å
 @param identifier é‡ç”¨å”¯ä¸€æ ‡è¯†ç¬¦
 */
- (void)registerViewClass:(Class _Nullable )viewClass identifier:(NSString *_Nullable)identifier;
/**
 æ³¨å†Œè‡ªå®šä¹‰è§†å›¾
 @param nibName è‡ªå®šä¹‰è§†å›¾xib相关文件名
 @param identifier é‡ç”¨å”¯ä¸€æ ‡è¯†ç¬¦
 */
- (void)registerNibView:(NSString *_Nullable)nibName identifier:(NSString *_Nullable)identifier;
/**
 åˆ·æ–°è½®æ’­å›¾
 */
- (void)freshCarousel;
/**
 æš‚停轮播图后,可以调用改方法继续播放
 */
- (void)resumePlay;
/**
 è½®æ’­å›¾æš‚停自动播放
 */
- (void)pause;
/**
 å¦‚果开启自动轮播,销毁前需要调用该方法,释放定时器.否则可能内存泄漏
 */
- (void)releaseTimer;
/**
 è½®æ’­å›¾æ‰€å¤„控制器WillAppear方法里调用
 */
- (void)controllerWillAppear;
/**
 è½®æ’­å›¾æ‰€å¤„控制器WillDisAppear方法里调用
 */
- (void)controllerWillDisAppear;
@end
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarousel.m
New file
@@ -0,0 +1,645 @@
//
//  CWCarousel.m
//  CWCarousel
//
//  Created by WangChen on 2018/4/3.
//  Copyright Â© 2018å¹´ ChenWang. All rights reserved.
//
#import "CWCarousel.h"
@interface CWTempleteCell: UICollectionViewCell
@end
@implementation CWTempleteCell
@end
@interface CWCarousel ()<UICollectionViewDelegate, UICollectionViewDataSource> {
}
@property (nonatomic, strong) UICollectionView *carouselView;
@property (nonatomic, assign) NSInteger        numbers;
@property (nonatomic, assign) NSInteger        currentIndex;
@property (nonatomic, assign) NSInteger        infactIndex;
@property (nonatomic, assign) CGFloat          addHeight;
/**
 è‡ªåŠ¨æ’­æ”¾æ˜¯å¦æš‚åœ
 */
@property (nonatomic, assign) BOOL             isPause;
/**
 å½“前展示在中间的cell下标
 */
@property (nonatomic, strong) NSIndexPath      *currentIndexPath;
@end
@implementation CWCarousel
@synthesize carouselView = _carouselView;
- (instancetype)initWithFrame:(CGRect)frame delegate:(id<CWCarouselDelegate>)delegate datasource:(id<CWCarouselDatasource>)datasource flowLayout:(CWFlowLayout *)flowLayout {
    CGFloat addHeight = 0;
//    if(flowLayout.style == CWCarouselStyle_H_3) {
//        /* å¦‚果是CWCarouselStyle_H_3, å› ä¸ºä¸­é—´ä¸€å¼ å›¾ç‰‡æ”¾å¤§çš„原因,需要扩充一下frame的高度,所以会和实际的传入的frame
//         çš„高度有部分偏差
//         */
//        addHeight = (flowLayout.maxScale - 1) * CGRectGetHeight(frame);
//    }
    frame.size.height += addHeight;
    self.addHeight = addHeight;
    if(self = [super initWithFrame:frame]) {
        _flowLayout = flowLayout;
        self.delegate = delegate;
        self.datasource = datasource;
        self.isAuto = NO;
        self.autoTimInterval = 3;
        self.endless = YES;
        [self configureView];
    }
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appBecomeInactive:) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    return self;
}
- (void)appBecomeInactive:(NSNotification *)notification {
    [self adjustErrorCell:YES];
}
- (void)appBecomeActive:(NSNotification *)notification {
    [self adjustErrorCell:YES];
}
- (void)controllerWillAppear {
    if(self.isAuto) {
        [self resumePlay];
    }
    [self adjustErrorCell:YES];
}
- (void)controllerWillDisAppear {
    if(self.isAuto) {
        [self pause];
    }
    [self adjustErrorCell:YES];
}
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)willMoveToSuperview:(UIView *)newSuperview {
    newSuperview.clipsToBounds = NO;
    if(self.customPageControl == nil && self.pageControl.superview == nil) {
        [self addSubview:self.pageControl];
        self.pageControl.translatesAutoresizingMaskIntoConstraints = NO;
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[control]-0-|"
                                                                     options:kNilOptions
                                                                     metrics:nil
                                                                       views:@{@"control" : self.pageControl}]];
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[control(30)]-0-|"
                                                                     options:kNilOptions
                                                                     metrics:nil
                                                                       views:@{@"control" : self.pageControl}]];
    }else if(self.customPageControl || self.customPageControl.superview == nil) {
        [self addSubview:self.customPageControl];
    }
    [super willMoveToSuperview:newSuperview];
}
- (void)registerViewClass:(Class)viewClass identifier:(NSString *)identifier {
    [self.carouselView registerClass:viewClass forCellWithReuseIdentifier:identifier];
}
- (void)registerNibView:(NSString *)nibName identifier:(NSString *)identifier {
    [self.carouselView registerNib:[UINib nibWithNibName:nibName bundle:[NSBundle mainBundle]]
        forCellWithReuseIdentifier:identifier];
}
- (void)freshCarousel {
    if([self numbers] <= 0) {
        return;
    }
    [self.carouselView reloadData];
    [self.carouselView layoutIfNeeded];
    if (self.endless)
        [self.carouselView scrollToItemAtIndexPath:[self originIndexPath] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
    else
    {
        if(self.flowLayout.style == CWCarouselStyle_Normal)
        {
            [self.carouselView scrollToItemAtIndexPath:self.currentIndexPath = [NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        }
        else
        {
            [self.carouselView scrollToItemAtIndexPath:self.currentIndexPath = [NSIndexPath indexPathForRow:1 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        }
    }
    self.carouselView.userInteractionEnabled = YES;
    if (self.isAuto) {
        [self play];
    }
}
#pragma mark - < Scroll Delegate >
/// å¼€å§‹æ‹–拽
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    // é˜²æ­¢æ‹–动加速度太大,一次跳过多张图片,这里设置一下
    if (@available(iOS 14.0, *)) {
        scrollView.pagingEnabled = NO;
    } else {
        scrollView.pagingEnabled = YES;
    }
    if (self.isAuto) {
        [self stop];
    }
    if (self.delegate && [self.delegate respondsToSelector:@selector(CWCarousel:didStartScrollAtIndex:indexPathRow:)]) {
        [self.delegate CWCarousel:self didStartScrollAtIndex:[self caculateIndex:self.currentIndexPath.row] indexPathRow:self.currentIndexPath.row];
    }
}
/// å°†è¦ç»“束拖拽
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    if (!self.endless)
    {
        NSInteger maxIndex = [self numbers] - 1;
        NSInteger minIndex = 0;
        if(self.flowLayout.style != CWCarouselStyle_Normal)
        {
            maxIndex = [self infactNumbers] - 2;
            minIndex = 1;
        }
        if (velocity.x == 0) {
            //还有一种情况,当滑动后手指按住不放,然后松开,此时的加速度其实是为0的
            [self adjustErrorCell:NO];
            if (@available(iOS 14.0, *)) {
                // iOS14以前,就算加速度为0,后续系统会还是会走scrollViewWillBeginDecelerating:回调
                // ä½†æ˜¯iOS14以后,加速度为0时,不会在后续执行回调.这里手动触发一下
                [self scrollViewWillBeginDecelerating:self.carouselView];
            }
            return;
        }
        if (velocity.x >= 0 && self.currentIndexPath.row == maxIndex)
        {
            return;
        }
        if (velocity.x <= 0 && self.currentIndexPath.row == minIndex)
        {
            return;
        }
    }
    if(velocity.x > 0) {
        //左滑,下一张
        self.currentIndexPath = [NSIndexPath indexPathForRow:self.currentIndexPath.row + 1 inSection:self.currentIndexPath.section];
    }else if (velocity.x < 0) {
        //右滑,上一张
        self.currentIndexPath = [NSIndexPath indexPathForRow:self.currentIndexPath.row - 1 inSection:self.currentIndexPath.section];
    }else if (velocity.x == 0) {
        //还有一种情况,当滑动后手指按住不放,然后松开,此时的加速度其实是为0的
        [self adjustErrorCell:NO];
        if (@available(iOS 14.0, *)) {
            // iOS14以前,就算加速度为0,后续系统会还是会走scrollViewWillBeginDecelerating:回调
            // ä½†æ˜¯iOS14以后,加速度为0时,不会在后续执行回调.这里手动触发一下
            [self scrollViewWillBeginDecelerating:self.carouselView];
        }
    }
}
/// å¼€å§‹å‡é€Ÿ
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
    if(self.currentIndexPath != nil &&
       self.currentIndexPath.row < [self infactNumbers] &&
       self.currentIndexPath.row >= 0) {
        // ä¸­é—´ä¸€å¼ è½®æ’­,居中显示
        if (!self.endless)
        {
            if (self.currentIndexPath.row == 0 && self.style != CWCarouselStyle_Normal)
            {
                self.currentIndexPath = [NSIndexPath indexPathForRow:1 inSection:self.currentIndexPath.section];
            }
            else if (self.currentIndexPath.row == [self infactNumbers] - 1 && self.style != CWCarouselStyle_Normal)
            {
                self.currentIndexPath = [NSIndexPath indexPathForRow:[self infactNumbers] - 2 inSection:self.currentIndexPath.section];
            }
        }
        [self.carouselView scrollToItemAtIndexPath:self.currentIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
    }
}
/// å‡é€Ÿå®Œæˆ
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // æ‰“开交互
    scrollView.pagingEnabled = NO;
    if(self.isAuto) {
        [self play];
    }
}
/// æ»šåŠ¨åŠ¨ç”»å®Œæˆ
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    // æ»šåŠ¨å®Œæˆ,打开交互,关掉pagingEnabled
    // ä¸ºä»€ä¹ˆè¦å…³æŽ‰pagingEnabled呢,因为切换控制器的时候会有系统级bug,不信你试试.
    scrollView.userInteractionEnabled = YES;
    scrollView.pagingEnabled = NO;
    if(self.isAuto) {
        [self play];
    }
    if (self.endless)
        [self checkOutofBounds];
//    if(!self.endless)
//    {
//        CGFloat space = self.flowLayout.itemSpace_H + self.flowLayout.itemWidth * (1 - self.flowLayout.minScale) * 0.5;
//        if(self.currentIndexPath.row == 0)
//            self.carouselView.contentInset = UIEdgeInsetsMake(0, space, 0, 0);
//        else if(self.currentIndexPath.row == [self numbers] - 1)
//            self.carouselView.contentInset = UIEdgeInsetsMake(0, 0, 0, space);
//        else
//            self.carouselView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
//    }
    if (self.delegate && [self.delegate respondsToSelector:@selector(CWCarousel:didEndScrollAtIndex:indexPathRow:)]) {
        [self.delegate CWCarousel:self didEndScrollAtIndex:[self caculateIndex:self.currentIndexPath.row] indexPathRow:self.currentIndexPath.row];
    }
}
// æ»šåЍ䏭
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // æ»šåŠ¨è¿‡ç¨‹ä¸­å…³é—­äº¤äº’
//    scrollView.userInteractionEnabled = NO;
}
#pragma mark - < Logic Helper >
- (NSIndexPath *)originIndexPath {
    NSInteger num = [self numbers];
    if (num <= 0) {
        return [[NSIndexPath alloc] initWithIndex:0];
    }
    NSInteger centerIndex = [self infactNumbers] / [self numbers];
    if (self.endless) {
        if(centerIndex <= 1) {
            if (centerIndex == 1) {
                self.currentIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
            }else {
                self.currentIndexPath = [NSIndexPath indexPathForRow:self.numbers inSection:0];
            }
        }else {
            self.currentIndexPath = [NSIndexPath indexPathForRow:centerIndex / 2 * [self numbers] inSection:0];
        }
    }else {
        NSInteger row = self.flowLayout.style == CWCarouselStyle_Normal ? 0 : 1;
        self.currentIndexPath = [NSIndexPath indexPathForRow:row inSection:0];
    }
    return self.currentIndexPath;
}
- (void)checkOutofBounds {
    if ([self numbers] <= 0) {return;}
    // è¶Šç•Œæ£€æŸ¥
    if(self.currentIndexPath.row == [self infactNumbers] - 1) {
        //最后一张
        NSIndexPath *origin = [self originIndexPath];
        NSInteger index = [self caculateIndex:self.currentIndexPath.row] - 1;
        self.currentIndexPath = [NSIndexPath indexPathForRow:origin.row + index inSection:origin.section];
        [self.carouselView scrollToItemAtIndexPath:self.currentIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        self.carouselView.userInteractionEnabled = YES;
    }else if(self.currentIndexPath.row == 0) {
        //第一张
        NSIndexPath *origin = [self originIndexPath];
        NSInteger index = [self caculateIndex:self.currentIndexPath.row];
        self.currentIndexPath = [NSIndexPath indexPathForRow:origin.row + index inSection:origin.section];
        [self.carouselView scrollToItemAtIndexPath:self.currentIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        self.carouselView.userInteractionEnabled = YES;
    }
}
- (void)pageControlClick:(UIPageControl *)sender {
    if (![sender isKindOfClass:[UIPageControl class]]) {
        return;
    }
    NSInteger page = sender.currentPage;
    NSInteger prePage = [self caculateIndex:self.currentIndexPath.row];
    if(page == prePage) {
        return;
    }
    NSIndexPath *indexPath = nil;
    if(prePage - page == [self numbers] - 1) {
        //最后一张跳到第一张
        indexPath = [NSIndexPath indexPathForRow:self.currentIndexPath.row + 1 inSection:0];
    }else if(page - prePage == [self numbers] - 1) {
        //第一张跳到最后一张
        indexPath = [NSIndexPath indexPathForRow:self.currentIndexPath.row - 1 inSection:0];
    }else {
        indexPath = [NSIndexPath indexPathForRow:self.currentIndexPath.row + page - prePage inSection:0];
    }
    [self.carouselView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
    self.currentIndexPath = indexPath;
}
/**
 å®žé™…下标转换成业务需求下标
 @param factIndex å®žé™…下标
 @return ä¸šåŠ¡éœ€æ±‚ä¸‹æ ‡
 */
- (NSInteger)caculateIndex:(NSInteger)factIndex {
    if (self.numbers <= 0) {
        return 0;
    }
    NSInteger row = factIndex % [self numbers];
    if(!self.endless && self.flowLayout.style != CWCarouselStyle_Normal)
    {
        row = factIndex % [self infactNumbers] - 1;
    }
    return row;
}
- (void)adjustErrorCell:(BOOL)isScroll {
    NSArray <NSIndexPath *> *indexPaths = [self.carouselView indexPathsForVisibleItems];
    NSMutableArray <UICollectionViewLayoutAttributes *> *attriArr = [NSMutableArray arrayWithCapacity:indexPaths.count];
    [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        UICollectionViewLayoutAttributes *attri = [self.carouselView layoutAttributesForItemAtIndexPath:obj];
        [attriArr addObject:attri];
    }];
    CGFloat centerX = self.carouselView.contentOffset.x + CGRectGetWidth(self.carouselView.frame) * 0.5;
    __block CGFloat minSpace = MAXFLOAT;
//    BOOL shouldSet = YES;
//    if (self.flowLayout.style != CWCarouselStyle_Normal && indexPaths.count <= 2)
//    {
//        shouldSet = NO;
//    }
    [attriArr enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj.zIndex = 0;
//        if(ABS(minSpace) > ABS(obj.center.x - centerX) && shouldSet) {
//            minSpace = obj.center.x - centerX;
//            self.currentIndexPath = obj.indexPath;
//        }
        if(ABS(minSpace) > ABS(obj.center.x - centerX)) {
            minSpace = obj.center.x - centerX;
            self.currentIndexPath = obj.indexPath;
        }
    }];
    if(isScroll) {
        [self scrollViewWillBeginDecelerating:self.carouselView];
    }
}
- (void)play {
    [self stop];
    if(self.isPause) {
        return;
    }
    [self performSelector:@selector(nextCell) withObject:nil afterDelay:self.autoTimInterval];
}
- (void)nextCell {
    if([self numbers] <= 0) {
        return;
    }
    NSInteger maxIndex = 1;
    if(!self.endless && self.flowLayout.style != CWCarouselStyle_Normal)
    {
        maxIndex = 2;
    }
    if(self.currentIndexPath.row < [self infactNumbers] - maxIndex)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.currentIndexPath.row + 1 inSection:self.currentIndexPath.section];
        [self.carouselView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
        self.currentIndexPath = indexPath;
    }
    else if(!self.endless)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:maxIndex - 1 inSection:self.currentIndexPath.section];
        [self.carouselView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
        self.currentIndexPath = indexPath;
    }
    [self performSelector:@selector(nextCell) withObject:nil afterDelay:self.autoTimInterval];
}
- (void)stop {
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(nextCell) object:nil];
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}
- (void)resumePlay {
    self.isPause = NO;
    [self play];
}
- (void)pause {
    self.isPause = YES;
    [self stop];
}
- (void)releaseTimer {
    [self stop];
}
#pragma mark - < Configure View>
- (void)configureView {
    self.backgroundColor = [UIColor blackColor];
    self.carouselView.showsVerticalScrollIndicator = NO;
    self.carouselView.showsHorizontalScrollIndicator = NO;
    self.carouselView.decelerationRate = 0;
}
#pragma mark - < Delegate, Datasource >
- (nonnull __kindof UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
    if(!self.endless
       && self.flowLayout.style != CWCarouselStyle_Normal
       && (indexPath.row == 0 || indexPath.row == [self infactNumbers] - 1))
    {
        // æ·»åŠ å ä½cell
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"tempCell" forIndexPath:indexPath];
        cell.contentView.backgroundColor = [UIColor clearColor];
        return cell;
    }
    else
    {
        if(self.datasource &&
           [self.datasource respondsToSelector:@selector(viewForCarousel:indexPath:index:)])
        {
            UICollectionViewCell *cell = [self.datasource viewForCarousel:self indexPath:indexPath index:[self caculateIndex:indexPath.row]];
            return cell;
        }
        return nil;
    }
}
- (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if([self numbers] > 0)
        return [self infactNumbers];
    else
        return 0;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    if(self.delegate &&
       [self.delegate respondsToSelector:@selector(CWCarousel:didSelectedAtIndex:)]) {
        [self.delegate CWCarousel:self didSelectedAtIndex:[self caculateIndex:indexPath.row]];
    }
    // å¤„于动画中时,点击cell,可能会出现cell不居中问题.这里处理下
    // å°†é‡Œä¸­å¿ƒç‚¹æœ€è¿‘的那个cell居中
    [self adjustErrorCell:YES];
}
#pragma mark - <setter>
- (void)setBackgroundColor:(UIColor *)backgroundColor {
    self.carouselView.backgroundColor = backgroundColor;
    [super setBackgroundColor:backgroundColor];
}
- (void)setCurrentIndexPath:(NSIndexPath *)currentIndexPath {
    _currentIndexPath = currentIndexPath;
    if(self.customPageControl == nil)
        self.pageControl.currentPage = [self caculateIndex:currentIndexPath.row];
    else
        self.customPageControl.currentPage = [self caculateIndex:currentIndexPath.row];
}
- (void)setEndless:(BOOL)endless {
    if(_endless != endless)
    {
        _endless = endless;
    }
}
#pragma mark - < getter >
- (UICollectionView *)carouselView {
    if(!_carouselView) {
//        self.carouselView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, self.addHeight * 0.5, self.frame.size.width, self.frame.size.height - self.addHeight) collectionViewLayout:self.flowLayout];
        self.carouselView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.flowLayout];
        _carouselView.clipsToBounds = NO;
        _carouselView.delegate = self;
        _carouselView.dataSource = self;
        _carouselView.translatesAutoresizingMaskIntoConstraints = NO;
        [_carouselView registerClass:[CWTempleteCell class] forCellWithReuseIdentifier:@"tempCell"];
        [self addSubview:_carouselView];
        NSDictionary *views = @{@"view" : self.carouselView};
        NSDictionary *margins = @{@"top" : @(self.addHeight * 0.5),
                                  @"bottom" : @(self.addHeight * 0.5)
                                  };
        NSString *str = @"H:|-0-[view]-0-|";
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:str
                                                                     options:kNilOptions
                                                                     metrics:margins
                                                                       views:views]];
        str = @"V:|-top-[view]-top-|";
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:str
                                                                     options:kNilOptions
                                                                     metrics:margins
                                                                       views:views]];
    }
    return _carouselView;
}
- (CWCarouselStyle)style {
    if(self.flowLayout)
    {
        return self.flowLayout.style;
    }
    return CWCarouselStyle_Unknow;
}
/**
 Description
 @return ä¸šåŠ¡éœ€æ±‚éœ€è¦å±•ç¤ºè½®æ’­å›¾ä¸ªæ•°
 */
- (NSInteger)numbers {
    if(self.datasource &&
       [self.datasource respondsToSelector:@selector(numbersForCarousel)]) {
        self.pageControl.numberOfPages = [self.datasource numbersForCarousel];
        return self.pageControl.numberOfPages;
    }
    return 0;
}
/**
 è½®æ’­å›¾å®žé™…加载视图个数
 @return è½®æ’­å›¾å®žé™…加载视图个数
 */
- (NSInteger)infactNumbers {
    NSInteger num = [self numbers];
    if ( 0 >= num) {
        return 0;
    }
    [self.carouselView setScrollEnabled:YES];
    if (self.endless)
    {
        if (num < 1) {
            [self.carouselView setScrollEnabled:NO];
            return num;
        }
        // å¦‚果是无限轮播,默认加载300个
        return 300;
    }
    else
    {
        // å¦‚果不是无限轮播,出了第一种样式,其他的样式要加2个占位空cell
        if(self.flowLayout.style == CWCarouselStyle_Normal)
        {
            return [self numbers];
        }
        else
        {
            if (num == 1) {
                [self.carouselView setScrollEnabled:NO];
            }
            // å‰åŽ2个占位cell,所以+2
            return [self numbers] + 2;
        }
    }
}
- (UIPageControl *)pageControl {
    if(!_pageControl) {
        self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 0, 300, 30)];
        CGPoint center = self.center;
        center.y = CGRectGetHeight(self.frame) - 30 * 0.5;
        _pageControl.pageIndicatorTintColor = [UIColor blackColor];
        _pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
        _pageControl.userInteractionEnabled = NO;
        [_pageControl addTarget:self action:@selector(pageControlClick:) forControlEvents:UIControlEventTouchUpInside];
        _pageControl.center = center;
    }
    return _pageControl;
}
- (NSString *)version {
    return @"1.1.7";
}
#pragma mark - Setter
- (void)setCustomPageControl:(UIView<CWCarouselPageControlProtocol> *)customPageControl {
    _customPageControl = customPageControl;
    if(_customPageControl && _customPageControl.superview == nil)
    {
        [self addSubview:_customPageControl];
        [self bringSubviewToFront:_customPageControl];
        if(self.pageControl.superview == _customPageControl.superview)
        {
            [self.pageControl removeFromSuperview];
        }
    }
}
@end
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarouselHeader.h
New file
@@ -0,0 +1,15 @@
//
//  CWCarouselHeader.h
//  CWCarousel
//
//  Created by WangChen on 2018/4/3.
//  Copyright Â© 2018å¹´ ChenWang. All rights reserved.
//
#ifndef CWCarouselHeader_h
#define CWCarouselHeader_h
#import "CWCarousel.h"
#import "CWCarouselProtocol.h"
#endif /* CWCarouselHeader_h */
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWCarouselProtocol.h
New file
@@ -0,0 +1,79 @@
//
//  CWCarouselProtocol.h
//  CWCarousel
//
//  Created by WangChen on 2018/4/3.
//  Copyright Â© 2018å¹´ ChenWang. All rights reserved.
//
#ifndef CWCarouselProtocol_h
#define CWCarouselProtocol_h
@class CWCarousel;
@protocol CWCarouselDelegate<NSObject>
/**
 è½®æ’­å›¾ç‚¹å‡»ä»£ç†
 @param carousel è½®æ’­å›¾å®žä¾‹å¯¹è±¡
 @param index è¢«ç‚¹å‡»çš„下标
 */
- (void)CWCarousel:(CWCarousel *)carousel didSelectedAtIndex:(NSInteger)index;
@optional
/**
将要开始滑动时,会触发该代理
 @param carousel è½®æ’­å›¾æŽ§ä»¶
 @param index å¼€å§‹æ»‘动时,处于中心点图片的下标
 @param indexPathRow å¼€å§‹æ»‘动时,处于中心点图片的在控件内部的实际下标
 */
- (void)CWCarousel:(CWCarousel *)carousel didStartScrollAtIndex:(NSInteger)index indexPathRow:(NSInteger)indexPathRow;
/**
 æ»‘动结束后,会触发该代理
 @param carousel è½®æ’­å›¾æŽ§ä»¶
 @param index ç»“束滑动时,处于中心点图片的下标
 @param indexPathRow ç»“束滑动时,处于中心点图片在控件内部的实际下标
 */
- (void)CWCarousel:(CWCarousel *)carousel didEndScrollAtIndex:(NSInteger)index indexPathRow:(NSInteger)indexPathRow;
@end
@protocol CWCarouselDatasource<NSObject>
/**
 è½®æ’­å›¾æ•°é‡
 @return è½®æ’­å›¾å±•示个数
 */
- (NSInteger)numbersForCarousel;
/**
 è‡ªå®šä¹‰æ¯ä¸ªè½®æ’­å›¾è§†å›¾
 @param carousel è½®æ’­å›¾æŽ§ä»¶
 @param indexPath è½®æ’­å›¾cell实际下标
 @param index ä¸šåŠ¡é€»è¾‘éœ€è¦çš„ä¸‹æ ‡
 @return è‡ªå®šä¹‰è§†å›¾
 */
- (UICollectionViewCell *)viewForCarousel:(CWCarousel *)carousel indexPath:(NSIndexPath *)indexPath index:(NSInteger)index;
@end
@protocol CWCarouselPageControlProtocol<NSObject>
@required
/**
 æ€»é¡µæ•°
 */
@property (nonatomic, assign) NSInteger         pageNumbers;
/**
 å½“前页
 */
@property (nonatomic, assign) NSInteger         currentPage;
- (void)setCurrentPage:(NSInteger)currentPage;
- (void)setPageNumbers:(NSInteger)pageNumbers;
@end
#endif /* CWCarouselProtocol_h */
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWFlowLayout.h
New file
@@ -0,0 +1,66 @@
//
//  CWFlowLayout.h
//  CWCarousel
//
//  Created by WangChen on 2018/4/3.
//  Copyright Â© 2018å¹´ ChenWang. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, CWCarouselStyle) {
    CWCarouselStyle_Unknow = 0,     ///<未知样式
    CWCarouselStyle_Normal,         ///<普通样式,一张图占用整个屏幕宽度
    CWCarouselStyle_H_1,            ///<自定义样式一, ä¸­é—´ä¸€å¼ å±…中,前后2张图有部分内容在屏幕内可以预览到
    CWCarouselStyle_H_2,            ///<自定义样式二, ä¸­é—´ä¸€å¼ å±…中,前后2张图有部分内容在屏幕内可以预览到,并且中间一张图正常大小,前后2张图会缩放
    CWCarouselStyle_H_3,            ///<自定义样式三, ä¸­é—´ä¸€å¼ å±…中,前后2张图有部分内容在屏幕内可以预览到,中间一张有放大效果,前后2张正常大小
};
@interface CWFlowLayout : UICollectionViewFlowLayout
/**
 å½±å“è½®æ’­å›¾é£Žæ ¼
 */
@property (nonatomic, assign) CWCarouselStyle style;
/**
 * æ¨ªå‘滚动时,每张轮播图之间的间距
 * CWCarouselStyle_H_3 æ ·å¼æ—¶è®¾ç½®æ— æ•ˆ
 */
@property (nonatomic, assign) CGFloat itemSpace_H;
/**
 * æ¨ªå‘滚动时,每张轮播图的宽度
 * style = CWCarouselStyle_Normal æ—¶è®¾ç½®æ— æ•ˆ
 */
@property (nonatomic, assign) CGFloat itemWidth;
/**
 * style = CWCarouselStyle_H_2 æœ‰æ•ˆ
 * å‰åŽ2张图的缩小比例 (0.0 ~ 1.0)
 * é»˜è®¤: 0.8
 */
@property (nonatomic, assign) CGFloat minScale;
/**
 * style = CWCarouselStyle_H_3 æœ‰æ•ˆ
 * ä¸­é—´ä¸€å¼ å›¾æ”¾å¤§æ¯”例
 * é»˜è®¤: 1.2
 * 1.1.0版本后,无论设置多少,中间一张的cell的比例始终是原始size, è¿™ä¸ªæ¯”例是相对两边cell的size的相对比例
    ä¹Ÿå°±æ˜¯è¯´,该值越大,那么两边的cell就会相对越小.反之越大.
 */
@property (nonatomic, assign) CGFloat maxScale;
/**
 çºµå‘滚动时,每张轮播图之间的间距(暂未实现)
 */
@property (nonatomic, assign) CGFloat itemSpace_V;
/**
 æž„造方法
 @param style è½®æ’­å›¾é£Žæ ¼
 @return å®žä¾‹å¯¹è±¡
 */
- (instancetype)initWithStyle:(CWCarouselStyle)style;
@end
BuWanVideo2.0/Recommend/lib/OC_CWCarousel/CWFlowLayout.m
New file
@@ -0,0 +1,195 @@
//
//  CWFlowLayout.m
//  CWCarousel
//
//  Created by WangChen on 2018/4/3.
//  Copyright Â© 2018å¹´ ChenWang. All rights reserved.
//
#import "CWFlowLayout.h"
@interface CWFlowLayout () {
}
/**
 é»˜è®¤è½®æ’­å›¾å®½åº¦
 */
@property (nonatomic, assign) CGFloat                   defaultItemWidth;
@property (nonatomic, assign) CGFloat                   factItemSpace;
@end
@implementation CWFlowLayout
- (instancetype)initWithStyle:(CWCarouselStyle)style {
    if(self = [super init]) {
        self.style = style;
        [self initial];
    }
    return self;
}
- (void)dealloc {
    NSLog(@"%s", __func__);
}
- (void)initial {
    self.itemSpace_H = 1;
    self.itemSpace_V = 1;
    self.minScale = 0.8;
    self.maxScale = 1.2;
}
- (void)prepareLayout {
    switch (self.style) {
        case CWCarouselStyle_Normal:
            {
                CGFloat width = CGRectGetWidth(self.collectionView.frame);
                CGFloat height = CGRectGetHeight(self.collectionView.frame);
                self.itemWidth = width;
                self.itemSize = CGSizeMake(width, height);
                self.minimumLineSpacing = self.itemSpace_H;
                self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
            }
            break;
        case CWCarouselStyle_H_1: {
            CGFloat width = self.itemWidth == 0 ? self.defaultItemWidth : self.itemWidth;
            self.itemWidth = width;
            CGFloat height = CGRectGetHeight(self.collectionView.frame);
            self.itemSize = CGSizeMake(width, height);
            self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
            self.minimumLineSpacing = self.itemSpace_H;
            break;
        }
        case CWCarouselStyle_H_2:
        case CWCarouselStyle_H_3: {
            CGFloat width = self.itemWidth == 0 ? self.defaultItemWidth : self.itemWidth;
            self.itemWidth = width;
            CGFloat height = CGRectGetHeight(self.collectionView.frame);
            self.itemSize = CGSizeMake(width, self.style == CWCarouselStyle_H_3 ? height / self.maxScale : height);
            self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
            self.factItemSpace = 0;
            if(width * (1 - self.minScale) * 0.5 < self.itemSpace_H) {
                self.factItemSpace = self.itemSpace_H - width * (1 - self.minScale) * 0.5;
            }
            self.minimumLineSpacing = self.factItemSpace;
        }
            break;
        default:
            break;
    }
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    if(self.style != CWCarouselStyle_Normal &&
       self.style != CWCarouselStyle_Unknow &&
       self.style != CWCarouselStyle_H_1) {
        NSArray<UICollectionViewLayoutAttributes *> *arr = [[NSArray alloc] initWithArray:[super layoutAttributesForElementsInRect:rect] copyItems:YES];
        CGFloat centerX = self.collectionView.contentOffset.x + CGRectGetWidth(self.collectionView.frame) * 0.5;
        CGFloat width = self.itemWidth;
        __block CGFloat maxScale = 0;
        __block UICollectionViewLayoutAttributes *attri = nil;
        [arr enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            CGFloat space = ABS(obj.center.x - centerX);
            if(space >= 0) {
                CGFloat scale = 1;
                if (self.style == CWCarouselStyle_H_2) {
                    scale = (self.minScale - 1) / (self.itemWidth + self.factItemSpace) * space + 1;
                }else {
                    scale = -((self.maxScale - 1) / width) * space + self.maxScale;
                }
                obj.transform = CGAffineTransformMakeScale(scale, scale);
                if(maxScale < scale) {
                    maxScale = scale;
                    attri = obj;
                }
            }
            obj.zIndex = 0;
        }];
        if (attri) {
            attri.zIndex = 1;
        }
        return arr;
    }else {
        return [super layoutAttributesForElementsInRect:rect];
    }
}
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
//    CGRect rect;
//    _adjustIndexPath = nil;
//    rect.origin.x = proposedContentOffset.x;
//    rect.origin.y = 0;
//    rect.size.width = CGRectGetWidth(self.collectionView.frame);
//    rect.size.height = CGRectGetHeight(self.collectionView.frame);
//
//    CGFloat centerX = proposedContentOffset.x + CGRectGetWidth(self.collectionView.frame) * 0.5;
//    NSArray <UICollectionViewLayoutAttributes *>  *tempArr = [super layoutAttributesForElementsInRect:rect];
//    __block CGFloat minSpace = MAXFLOAT;
//    __block UICollectionViewLayoutAttributes *attributes = nil;
//    [tempArr enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//        obj.zIndex = 0;
//        if(ABS(minSpace) > ABS(obj.center.x - centerX)) {
//            minSpace = obj.center.x - centerX;
//            attributes = obj;
//        }
//    }];
//    attributes.zIndex = 1;
//    _currentAttri = attributes;
//    if(velocity.x == 0) {
//        proposedContentOffset.x += minSpace;
//        _adjustIndexPath = nil;
//    }else if(attributes) {
//        if(ABS(minSpace) >= attributes.size.width * 0.15) {
//            NSInteger der = attributes.indexPath.row;
//            if(velocity.x > 0) {
//                der = (minSpace < 0 && velocity.x > 0) ? 1 : 0;
//            }else {
//                der = (minSpace > 0 && velocity.x < 0) ? -1 : 0;
//            }
//            _adjustIndexPath = [NSIndexPath indexPathForRow:attributes.indexPath.row + der inSection:attributes.indexPath.section];
//        }else {
//            _adjustIndexPath = attributes.indexPath;
//        }
//    }
    return proposedContentOffset;
}
#pragma mark - Property
- (CGFloat)defaultItemWidth {
    switch (self.style) {
        case CWCarouselStyle_Unknow:
        case CWCarouselStyle_Normal:
            return self.collectionView.frame.size.width;
            break;
        case CWCarouselStyle_H_1:
        case CWCarouselStyle_H_2:
        case CWCarouselStyle_H_3:
            return self.collectionView.frame.size.width * 0.75;
            break;
        default:
            break;
    }
}
- (void)setMaxScale:(CGFloat)maxScale {
    _maxScale = maxScale;
    if(maxScale < 1) {
        _maxScale = 1;
    }
}
- (void)setMinScale:(CGFloat)minScale {
    _minScale = minScale;
    if(minScale < 0) {
        _minScale = 0.1;
    }
    if (minScale >= 1) {
        _minScale = 1;
    }
}
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAbstractDotView.h
New file
@@ -0,0 +1,24 @@
//
//  TAAbstractDotView.h
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-22.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TAAbstractDotView : UIView
/**
 *  A method call let view know which state appearance it should take. Active meaning it's current page. Inactive not the current page.
 *
 *  @param active BOOL to tell if view is active or not
 */
- (void)changeActivityState:(BOOL)active;
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAbstractDotView.m
New file
@@ -0,0 +1,30 @@
//
//  TAAbstractDotView.m
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-22.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAbstractDotView.h"
@implementation TAAbstractDotView
- (id)init
{
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                   reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
                                 userInfo:nil];
}
- (void)changeActivityState:(BOOL)active
{
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                   reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
                                 userInfo:nil];
}
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAnimatedDotView.h
New file
@@ -0,0 +1,15 @@
//
//  TAAnimatedDotView.h
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-22.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAbstractDotView.h"
@interface TAAnimatedDotView : TAAbstractDotView
@property (nonatomic, strong) UIColor *dotColor;
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAAnimatedDotView.m
New file
@@ -0,0 +1,88 @@
//
//  TAAnimatedDotView.m
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-22.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAnimatedDotView.h"
static CGFloat const kAnimateDuration = 1;
@implementation TAAnimatedDotView
- (instancetype)init
{
    self = [super init];
    if (self) {
        [self initialization];
    }
    return self;
}
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialization];
    }
    return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initialization];
    }
    return self;
}
- (void)setDotColor:(UIColor *)dotColor
{
    _dotColor = dotColor;
    self.layer.borderColor  = dotColor.CGColor;
}
- (void)initialization
{
    _dotColor = [UIColor whiteColor];
    self.backgroundColor    = [UIColor clearColor];
    self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2;
    self.layer.borderColor  = [UIColor whiteColor].CGColor;
    self.layer.borderWidth  = 2;
}
- (void)changeActivityState:(BOOL)active
{
    if (active) {
        [self animateToActiveState];
    } else {
        [self animateToDeactiveState];
    }
}
- (void)animateToActiveState
{
    [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:-20 options:UIViewAnimationOptionCurveLinear animations:^{
        self.backgroundColor = self->_dotColor;
        self.transform = CGAffineTransformMakeScale(1.4, 1.4);
    } completion:nil];
}
- (void)animateToDeactiveState
{
    [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
        self.backgroundColor = [UIColor clearColor];
        self.transform = CGAffineTransformIdentity;
    } completion:nil];
}
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TADotView.h
New file
@@ -0,0 +1,13 @@
//
//  TADotView.h
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-22.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAbstractDotView.h"
@interface TADotView : TAAbstractDotView
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TADotView.m
New file
@@ -0,0 +1,63 @@
//
//  TADotView.m
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-22.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TADotView.h"
@implementation TADotView
- (instancetype)init
{
    self = [super init];
    if (self) {
        [self initialization];
    }
    return self;
}
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialization];
    }
    return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initialization];
    }
    return self;
}
- (void)initialization
{
    self.backgroundColor    = [UIColor clearColor];
    self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2;
    self.layer.borderColor  = [UIColor whiteColor].CGColor;
    self.layer.borderWidth  = 2;
}
- (void)changeActivityState:(BOOL)active
{
    if (active) {
        self.backgroundColor = [UIColor whiteColor];
    } else {
        self.backgroundColor = [UIColor clearColor];
    }
}
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAPageControl.h
New file
@@ -0,0 +1,106 @@
//
//  TAPageControl.h
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-21.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol TAPageControlDelegate;
@interface TAPageControl : UIControl
/**
 * Dot view customization properties
 */
/**
 *  The Class of your custom UIView, make sure to respect the TAAbstractDotView class.
 */
@property (nonatomic) Class dotViewClass;
/**
 *  UIImage to represent a dot.
 */
@property (nonatomic) UIImage *dotImage;
/**
 *  UIImage to represent current page dot.
 */
@property (nonatomic) UIImage *currentDotImage;
/**
 *  Dot size for dot views. Default is 8 by 8.
 */
@property (nonatomic) CGSize dotSize;
@property (nonatomic, strong) UIColor *dotColor;
/**
 *  Spacing between two dot views. Default is 8.
 */
@property (nonatomic) NSInteger spacingBetweenDots;
/**
 * Page control setup properties
 */
/**
 * Delegate for TAPageControl
 */
@property(nonatomic,assign) id<TAPageControlDelegate> delegate;
/**
 *  Number of pages for control. Default is 0.
 */
@property (nonatomic) NSInteger numberOfPages;
/**
 *  Current page on which control is active. Default is 0.
 */
@property (nonatomic) NSInteger currentPage;
/**
 *  Hide the control if there is only one page. Default is NO.
 */
@property (nonatomic) BOOL hidesForSinglePage;
/**
 *  Let the control know if should grow bigger by keeping center, or just get longer (right side expanding). By default YES.
 */
@property (nonatomic) BOOL shouldResizeFromCenter;
/**
 *  Return the minimum size required to display control properly for the given page count.
 *
 *  @param pageCount Number of dots that will require display
 *
 *  @return The CGSize being the minimum size required.
 */
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount;
@end
@protocol TAPageControlDelegate <NSObject>
@optional
- (void)TAPageControl:(TAPageControl *)pageControl didSelectPageAtIndex:(NSInteger)index;
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/PageControl/TAPageControl.m
New file
@@ -0,0 +1,364 @@
//
//  TAPageControl.m
//  TAPageControl
//
//  Created by Tanguy Aladenise on 2015-01-21.
//  Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAPageControl.h"
#import "TAAbstractDotView.h"
#import "TAAnimatedDotView.h"
#import "TADotView.h"
/**
 *  Default number of pages for initialization
 */
static NSInteger const kDefaultNumberOfPages = 0;
/**
 *  Default current page for initialization
 */
static NSInteger const kDefaultCurrentPage = 0;
/**
 *  Default setting for hide for single page feature. For initialization
 */
static BOOL const kDefaultHideForSinglePage = NO;
/**
 *  Default setting for shouldResizeFromCenter. For initialiation
 */
static BOOL const kDefaultShouldResizeFromCenter = YES;
/**
 *  Default spacing between dots
 */
static NSInteger const kDefaultSpacingBetweenDots = 8;
/**
 *  Default dot size
 */
static CGSize const kDefaultDotSize = {8, 8};
@interface TAPageControl()
/**
 *  Array of dot views for reusability and touch events.
 */
@property (strong, nonatomic) NSMutableArray *dots;
@end
@implementation TAPageControl
#pragma mark - Lifecycle
- (id)init
{
    self = [super init];
    if (self) {
        [self initialization];
    }
    return self;
}
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialization];
    }
    return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initialization];
    }
    return self;
}
/**
 *  Default setup when initiating control
 */
- (void)initialization
{
    self.dotViewClass           = [TAAnimatedDotView class];
    self.spacingBetweenDots     = kDefaultSpacingBetweenDots;
    self.numberOfPages          = kDefaultNumberOfPages;
    self.currentPage            = kDefaultCurrentPage;
    self.hidesForSinglePage     = kDefaultHideForSinglePage;
    self.shouldResizeFromCenter = kDefaultShouldResizeFromCenter;
}
#pragma mark - Touch event
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    if (touch.view != self) {
        NSInteger index = [self.dots indexOfObject:touch.view];
        if ([self.delegate respondsToSelector:@selector(TAPageControl:didSelectPageAtIndex:)]) {
            [self.delegate TAPageControl:self didSelectPageAtIndex:index];
        }
    }
}
#pragma mark - Layout
/**
 *  Resizes and moves the receiver view so it just encloses its subviews.
 */
- (void)sizeToFit
{
    [self updateFrame:YES];
}
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount
{
    return CGSizeMake((self.dotSize.width + self.spacingBetweenDots) * pageCount - self.spacingBetweenDots , self.dotSize.height);
}
/**
 *  Will update dots display and frame. Reuse existing views or instantiate one if required. Update their position in case frame changed.
 */
- (void)updateDots
{
    if (self.numberOfPages == 0) {
        return;
    }
    for (NSInteger i = 0; i < self.numberOfPages; i++) {
        UIView *dot;
        if (i < self.dots.count) {
            dot = [self.dots objectAtIndex:i];
        } else {
            dot = [self generateDotView];
        }
        [self updateDotFrame:dot atIndex:i];
    }
    [self changeActivity:YES atIndex:self.currentPage];
    [self hideForSinglePage];
}
/**
 *  Update frame control to fit current number of pages. It will apply required size if authorize and required.
 *
 *  @param overrideExistingFrame BOOL to allow frame to be overriden. Meaning the required size will be apply no mattter what.
 */
- (void)updateFrame:(BOOL)overrideExistingFrame
{
    CGPoint center = self.center;
    CGSize requiredSize = [self sizeForNumberOfPages:self.numberOfPages];
    // We apply requiredSize only if authorize to and necessary
    if (overrideExistingFrame || ((CGRectGetWidth(self.frame) < requiredSize.width || CGRectGetHeight(self.frame) < requiredSize.height) && !overrideExistingFrame)) {
        self.frame = CGRectMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame), requiredSize.width, requiredSize.height);
        if (self.shouldResizeFromCenter) {
            self.center = center;
        }
    }
    [self resetDotViews];
}
/**
 *  Update the frame of a specific dot at a specific index
 *
 *  @param dot   Dot view
 *  @param index Page index of dot
 */
- (void)updateDotFrame:(UIView *)dot atIndex:(NSInteger)index
{
    // Dots are always centered within view
    CGFloat x = (self.dotSize.width + self.spacingBetweenDots) * index + ( (CGRectGetWidth(self.frame) - [self sizeForNumberOfPages:self.numberOfPages].width) / 2);
    CGFloat y = (CGRectGetHeight(self.frame) - self.dotSize.height) / 2;
    dot.frame = CGRectMake(x, y, self.dotSize.width, self.dotSize.height);
}
#pragma mark - Utils
/**
 *  Generate a dot view and add it to the collection
 *
 *  @return The UIView object representing a dot
 */
- (UIView *)generateDotView
{
    UIView *dotView;
    if (self.dotViewClass) {
        dotView = [[self.dotViewClass alloc] initWithFrame:CGRectMake(0, 0, self.dotSize.width, self.dotSize.height)];
        if ([dotView isKindOfClass:[TAAnimatedDotView class]] && self.dotColor) {
            ((TAAnimatedDotView *)dotView).dotColor = self.dotColor;
        }
    } else {
        dotView = [[UIImageView alloc] initWithImage:self.dotImage];
        dotView.frame = CGRectMake(0, 0, self.dotSize.width, self.dotSize.height);
    }
    if (dotView) {
        [self addSubview:dotView];
        [self.dots addObject:dotView];
    }
    dotView.userInteractionEnabled = YES;
    return dotView;
}
/**
 *  Change activity state of a dot view. Current/not currrent.
 *
 *  @param active Active state to apply
 *  @param index  Index of dot for state update
 */
- (void)changeActivity:(BOOL)active atIndex:(NSInteger)index
{
    if (self.dotViewClass) {
        TAAbstractDotView *abstractDotView = (TAAbstractDotView *)[self.dots objectAtIndex:index];
        if ([abstractDotView respondsToSelector:@selector(changeActivityState:)]) {
            [abstractDotView changeActivityState:active];
        } else {
            NSLog(@"Custom view : %@ must implement an 'changeActivityState' method or you can subclass %@ to help you.", self.dotViewClass, [TAAbstractDotView class]);
        }
    } else if (self.dotImage && self.currentDotImage) {
        UIImageView *dotView = (UIImageView *)[self.dots objectAtIndex:index];
        dotView.image = (active) ? self.currentDotImage : self.dotImage;
    }
}
- (void)resetDotViews
{
    for (UIView *dotView in self.dots) {
        [dotView removeFromSuperview];
    }
    [self.dots removeAllObjects];
    [self updateDots];
}
- (void)hideForSinglePage
{
    if (self.dots.count == 1 && self.hidesForSinglePage) {
        self.hidden = YES;
    } else {
        self.hidden = NO;
    }
}
#pragma mark - Setters
- (void)setNumberOfPages:(NSInteger)numberOfPages
{
    _numberOfPages = numberOfPages;
    // Update dot position to fit new number of pages
    [self resetDotViews];
}
- (void)setSpacingBetweenDots:(NSInteger)spacingBetweenDots
{
    _spacingBetweenDots = spacingBetweenDots;
    [self resetDotViews];
}
- (void)setCurrentPage:(NSInteger)currentPage
{
    // If no pages, no current page to treat.
    if (self.numberOfPages == 0 || currentPage == _currentPage) {
        _currentPage = currentPage;
        return;
    }
    // Pre set
    [self changeActivity:NO atIndex:_currentPage];
    _currentPage = currentPage;
    // Post set
    [self changeActivity:YES atIndex:_currentPage];
}
- (void)setDotImage:(UIImage *)dotImage
{
    _dotImage = dotImage;
    [self resetDotViews];
    self.dotViewClass = nil;
}
- (void)setCurrentDotImage:(UIImage *)currentDotimage
{
    _currentDotImage = currentDotimage;
    [self resetDotViews];
    self.dotViewClass = nil;
}
- (void)setDotViewClass:(Class)dotViewClass
{
    _dotViewClass = dotViewClass;
    self.dotSize = CGSizeZero;
    [self resetDotViews];
}
#pragma mark - Getters
- (NSMutableArray *)dots
{
    if (!_dots) {
        _dots = [[NSMutableArray alloc] init];
    }
    return _dots;
}
- (CGSize)dotSize
{
    // Dot size logic depending on the source of the dot view
    if (self.dotImage && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
        _dotSize = self.dotImage.size;
    } else if (self.dotViewClass && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
        _dotSize = kDefaultDotSize;
        return _dotSize;
    }
    return _dotSize;
}
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCollectionViewCell.h
New file
@@ -0,0 +1,51 @@
//
//  SDCollectionViewCell.h
//  SDCycleScrollView
//
//  Created by aier on 15-3-22.
//  Copyright (c) 2015å¹´ GSD. All rights reserved.
//
/*
 *********************************************************************************
 *
 * ðŸŒŸðŸŒŸðŸŒŸ æ–°å»ºSDCycleScrollView交流QQ群:185534916 ðŸŒŸðŸŒŸðŸŒŸ
 *
 * åœ¨æ‚¨ä½¿ç”¨æ­¤è‡ªåŠ¨è½®æ’­åº“çš„è¿‡ç¨‹ä¸­å¦‚æžœå‡ºçŽ°bug请及时以以下任意一种方式联系我们,我们会及时修复bugå¹¶
 * å¸®æ‚¨è§£å†³é—®é¢˜ã€‚
 * æ–°æµªå¾®åš:GSD_iOS
 * Email : gsdios@126.com
 * GitHub: https://github.com/gsdios
 *
 * å¦ï¼ˆæˆ‘的自动布局库SDAutoLayout):
 *  ä¸€è¡Œä»£ç æžå®šè‡ªåŠ¨å¸ƒå±€ï¼æ”¯æŒCell和Tableview高度自适应,Label和ScrollView内容自适应,致力于
 *  åšæœ€ç®€å•易用的AutoLayout库。
 * è§†é¢‘教程:http://www.letv.com/ptv/vplay/24038772.html
 * ç”¨æ³•示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
 * GitHub:https://github.com/gsdios/SDAutoLayout
 *********************************************************************************
 */
#import <UIKit/UIKit.h>
@interface SDCollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) UIImageView *imageView;
@property (copy, nonatomic) NSString *title;
@property (nonatomic, strong) UIColor *titleLabelTextColor;
@property (nonatomic, strong) UIFont *titleLabelTextFont;
@property (nonatomic, strong) UIColor *titleLabelBackgroundColor;
@property (nonatomic, assign) CGFloat titleLabelHeight;
@property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment;
@property (nonatomic, assign) BOOL hasConfigured;
/** åªå±•示文字轮播 */
@property (nonatomic, assign) BOOL onlyDisplayText;
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCollectionViewCell.m
New file
@@ -0,0 +1,119 @@
//
//  SDCollectionViewCell.m
//  SDCycleScrollView
//
//  Created by aier on 15-3-22.
//  Copyright (c) 2015å¹´ GSD. All rights reserved.
//
/*
 *********************************************************************************
 *
 * ðŸŒŸðŸŒŸðŸŒŸ æ–°å»ºSDCycleScrollView交流QQ群:185534916 ðŸŒŸðŸŒŸðŸŒŸ
 *
 * åœ¨æ‚¨ä½¿ç”¨æ­¤è‡ªåŠ¨è½®æ’­åº“çš„è¿‡ç¨‹ä¸­å¦‚æžœå‡ºçŽ°bug请及时以以下任意一种方式联系我们,我们会及时修复bugå¹¶
 * å¸®æ‚¨è§£å†³é—®é¢˜ã€‚
 * æ–°æµªå¾®åš:GSD_iOS
 * Email : gsdios@126.com
 * GitHub: https://github.com/gsdios
 *
 * å¦ï¼ˆæˆ‘的自动布局库SDAutoLayout):
 *  ä¸€è¡Œä»£ç æžå®šè‡ªåŠ¨å¸ƒå±€ï¼æ”¯æŒCell和Tableview高度自适应,Label和ScrollView内容自适应,致力于
 *  åšæœ€ç®€å•易用的AutoLayout库。
 * è§†é¢‘教程:http://www.letv.com/ptv/vplay/24038772.html
 * ç”¨æ³•示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
 * GitHub:https://github.com/gsdios/SDAutoLayout
 *********************************************************************************
 */
#import "SDCollectionViewCell.h"
#import "UIView+SDExtension.h"
@implementation SDCollectionViewCell
{
    __weak UILabel *_titleLabel;
}
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setupImageView];
        [self setupTitleLabel];
    }
    return self;
}
- (void)setTitleLabelBackgroundColor:(UIColor *)titleLabelBackgroundColor
{
    _titleLabelBackgroundColor = titleLabelBackgroundColor;
    _titleLabel.backgroundColor = titleLabelBackgroundColor;
}
- (void)setTitleLabelTextColor:(UIColor *)titleLabelTextColor
{
    _titleLabelTextColor = titleLabelTextColor;
    _titleLabel.textColor = titleLabelTextColor;
}
- (void)setTitleLabelTextFont:(UIFont *)titleLabelTextFont
{
    _titleLabelTextFont = titleLabelTextFont;
    _titleLabel.font = titleLabelTextFont;
}
- (void)setupImageView
{
    UIImageView *imageView = [[UIImageView alloc] init];
    [imageView setContentScaleFactor:[[UIScreen mainScreen] scale]];
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    imageView.clipsToBounds = YES;
    _imageView = imageView;
    [self.contentView addSubview:imageView];
}
- (void)setupTitleLabel
{
    UILabel *titleLabel = [[UILabel alloc] init];
    _titleLabel = titleLabel;
    _titleLabel.hidden = YES;
    [self.contentView addSubview:titleLabel];
}
- (void)setTitle:(NSString *)title
{
    _title = [title copy];
    _titleLabel.text = [NSString stringWithFormat:@"   %@", title];
    if (_titleLabel.hidden) {
        _titleLabel.hidden = NO;
    }
}
-(void)setTitleLabelTextAlignment:(NSTextAlignment)titleLabelTextAlignment
{
    _titleLabelTextAlignment = titleLabelTextAlignment;
    _titleLabel.textAlignment = titleLabelTextAlignment;
}
- (void)layoutSubviews
{
    [super layoutSubviews];
    if (self.onlyDisplayText) {
        _titleLabel.frame = self.bounds;
    } else {
        _imageView.frame = self.bounds;
        CGFloat titleLabelW = self.sd_width;
        CGFloat titleLabelH = _titleLabelHeight;
        CGFloat titleLabelX = 0;
        CGFloat titleLabelY = self.sd_height - titleLabelH;
        _titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH);
    }
}
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCycleScrollView.h
New file
@@ -0,0 +1,211 @@
//
//  SDCycleScrollView.h
//  SDCycleScrollView
//
//  Created by aier on 15-3-22.
//  Copyright (c) 2015å¹´ GSD. All rights reserved.
//
/*
 *********************************************************************************
 *
 * ðŸŒŸðŸŒŸðŸŒŸ æ–°å»ºSDCycleScrollView交流QQ群:185534916 ðŸŒŸðŸŒŸðŸŒŸ
 *
 * åœ¨æ‚¨ä½¿ç”¨æ­¤è‡ªåŠ¨è½®æ’­åº“çš„è¿‡ç¨‹ä¸­å¦‚æžœå‡ºçŽ°bug请及时以以下任意一种方式联系我们,我们会及时修复bugå¹¶
 * å¸®æ‚¨è§£å†³é—®é¢˜ã€‚
 * æ–°æµªå¾®åš:GSD_iOS
 * Email : gsdios@126.com
 * GitHub: https://github.com/gsdios
 *
 * å¦ï¼ˆæˆ‘的自动布局库SDAutoLayout):
 *  ä¸€è¡Œä»£ç æžå®šè‡ªåŠ¨å¸ƒå±€ï¼æ”¯æŒCell和Tableview高度自适应,Label和ScrollView内容自适应,致力于
 *  åšæœ€ç®€å•易用的AutoLayout库。
 * è§†é¢‘教程:http://www.letv.com/ptv/vplay/24038772.html
 * ç”¨æ³•示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
 * GitHub:https://github.com/gsdios/SDAutoLayout
 *********************************************************************************
 */
/*
 * å½“前版本为1.62
 * æ›´æ–°æ—¥æœŸï¼š2016.04.21
 */
#import <UIKit/UIKit.h>
typedef enum {
    SDCycleScrollViewPageContolAlimentRight,
    SDCycleScrollViewPageContolAlimentCenter
} SDCycleScrollViewPageContolAliment;
typedef enum {
    SDCycleScrollViewPageContolStyleClassic,        // ç³»ç»Ÿè‡ªå¸¦ç»å…¸æ ·å¼
    SDCycleScrollViewPageContolStyleAnimated,       // åŠ¨ç”»æ•ˆæžœpagecontrol
    SDCycleScrollViewPageContolStyleNone            // ä¸æ˜¾ç¤ºpagecontrol
} SDCycleScrollViewPageContolStyle;
@class SDCycleScrollView;
@protocol SDCycleScrollViewDelegate <NSObject>
@optional
/** ç‚¹å‡»å›¾ç‰‡å›žè°ƒ */
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index;
/** å›¾ç‰‡æ»šåŠ¨å›žè°ƒ */
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didScrollToIndex:(NSInteger)index;
// ä¸éœ€è¦è‡ªå®šä¹‰è½®æ’­cell的请忽略以下两个的代理方法
// ========== è½®æ’­è‡ªå®šä¹‰cell ==========
/** å¦‚果你需要自定义cell样式,请在实现此代理方法返回你的自定义cell的class。 */
- (Class)customCollectionViewCellClassForCycleScrollView:(SDCycleScrollView *)view;
/** å¦‚果你需要自定义cell样式,请在实现此代理方法返回你的自定义cell的Nib。 */
- (UINib *)customCollectionViewCellNibForCycleScrollView:(SDCycleScrollView *)view;
/** å¦‚果你自定义了cell样式,请在实现此代理方法为你的cell填充数据以及其它一系列设置 */
- (void)setupCustomCell:(UICollectionViewCell *)cell forIndex:(NSInteger)index cycleScrollView:(SDCycleScrollView *)view;
@end
@interface SDCycleScrollView : UIView
/** åˆå§‹è½®æ’­å›¾ï¼ˆæŽ¨èä½¿ç”¨ï¼‰ */
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame delegate:(id<SDCycleScrollViewDelegate>)delegate placeholderImage:(UIImage *)placeholderImage;
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageURLStringsGroup:(NSArray *)imageURLStringsGroup;
/** æœ¬åœ°å›¾ç‰‡è½®æ’­åˆå§‹åŒ–方式 */
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageNamesGroup:(NSArray *)imageNamesGroup;
/** æœ¬åœ°å›¾ç‰‡è½®æ’­åˆå§‹åŒ–方式2,infiniteLoop:是否无限循环 */
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame shouldInfiniteLoop:(BOOL)infiniteLoop imageNamesGroup:(NSArray *)imageNamesGroup;
//////////////////////  æ•°æ®æºAPI //////////////////////
/** ç½‘络图片 url string æ•°ç»„ */
@property (nonatomic, strong) NSArray *imageURLStringsGroup;
/** æ¯å¼ å›¾ç‰‡å¯¹åº”要显示的文字数组 */
@property (nonatomic, strong) NSArray *titlesGroup;
/** æœ¬åœ°å›¾ç‰‡æ•°ç»„ */
@property (nonatomic, strong) NSArray *localizationImageNamesGroup;
//////////////////////  æ»šåŠ¨æŽ§åˆ¶API //////////////////////
/** è‡ªåŠ¨æ»šåŠ¨é—´éš”æ—¶é—´,默认2s */
@property (nonatomic, assign) CGFloat autoScrollTimeInterval;
/** æ˜¯å¦æ— é™å¾ªçޝ,默认Yes */
@property (nonatomic,assign) BOOL infiniteLoop;
/** æ˜¯å¦è‡ªåŠ¨æ»šåŠ¨,默认Yes */
@property (nonatomic,assign) BOOL autoScroll;
/** å›¾ç‰‡æ»šåŠ¨æ–¹å‘ï¼Œé»˜è®¤ä¸ºæ°´å¹³æ»šåŠ¨ */
@property (nonatomic, assign) UICollectionViewScrollDirection scrollDirection;
@property (nonatomic, weak) id<SDCycleScrollViewDelegate> delegate;
/** block方式监听点击 */
@property (nonatomic, copy) void (^clickItemOperationBlock)(NSInteger currentIndex);
/** block方式监听滚动 */
@property (nonatomic, copy) void (^itemDidScrollOperationBlock)(NSInteger currentIndex);
/** å¯ä»¥è°ƒç”¨æ­¤æ–¹æ³•手动控制滚动到哪一个index */
- (void)makeScrollViewScrollToIndex:(NSInteger)index;
/** è§£å†³viewWillAppear时出现时轮播图卡在一半的问题,在控制器viewWillAppear时调用此方法 */
- (void)adjustWhenControllerViewWillAppera;
//////////////////////  è‡ªå®šä¹‰æ ·å¼API  //////////////////////
/** è½®æ’­å›¾ç‰‡çš„ContentMode,默认为 UIViewContentModeScaleToFill */
@property (nonatomic, assign) UIViewContentMode bannerImageViewContentMode;
/** å ä½å›¾ï¼Œç”¨äºŽç½‘络未加载到图片时 */
@property (nonatomic, strong) UIImage *placeholderImage;
/** æ˜¯å¦æ˜¾ç¤ºåˆ†é¡µæŽ§ä»¶ */
@property (nonatomic, assign) BOOL showPageControl;
/** æ˜¯å¦åœ¨åªæœ‰ä¸€å¼ å›¾æ—¶éšè—pagecontrol,默认为YES */
@property(nonatomic) BOOL hidesForSinglePage;
/** åªå±•示文字轮播 */
@property (nonatomic, assign) BOOL onlyDisplayText;
/** pagecontrol æ ·å¼ï¼Œé»˜è®¤ä¸ºåŠ¨ç”»æ ·å¼ */
@property (nonatomic, assign) SDCycleScrollViewPageContolStyle pageControlStyle;
/** åˆ†é¡µæŽ§ä»¶ä½ç½® */
@property (nonatomic, assign) SDCycleScrollViewPageContolAliment pageControlAliment;
/** åˆ†é¡µæŽ§ä»¶è·ç¦»è½®æ’­å›¾çš„底部间距(在默认间距基础上)的偏移量 */
@property (nonatomic, assign) CGFloat pageControlBottomOffset;
/** åˆ†é¡µæŽ§ä»¶è·ç¦»è½®æ’­å›¾çš„右边间距(在默认间距基础上)的偏移量 */
@property (nonatomic, assign) CGFloat pageControlRightOffset;
/** åˆ†é¡µæŽ§ä»¶å°åœ†æ ‡å¤§å° */
@property (nonatomic, assign) CGSize pageControlDotSize;
/** å½“前分页控件小圆标颜色 */
@property (nonatomic, strong) UIColor *currentPageDotColor;
/** å…¶ä»–分页控件小圆标颜色 */
@property (nonatomic, strong) UIColor *pageDotColor;
/** å½“前分页控件小圆标图片 */
@property (nonatomic, strong) UIImage *currentPageDotImage;
/** å…¶ä»–分页控件小圆标图片 */
@property (nonatomic, strong) UIImage *pageDotImage;
/** è½®æ’­æ–‡å­—label字体颜色 */
@property (nonatomic, strong) UIColor *titleLabelTextColor;
/** è½®æ’­æ–‡å­—label字体大小 */
@property (nonatomic, strong) UIFont  *titleLabelTextFont;
/** è½®æ’­æ–‡å­—label背景颜色 */
@property (nonatomic, strong) UIColor *titleLabelBackgroundColor;
/** è½®æ’­æ–‡å­—label高度 */
@property (nonatomic, assign) CGFloat titleLabelHeight;
/** è½®æ’­æ–‡å­—label对齐方式 */
@property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment;
/** æ»šåŠ¨æ‰‹åŠ¿ç¦ç”¨ï¼ˆæ–‡å­—è½®æ’­è¾ƒå®žç”¨ï¼‰ */
- (void)disableScrollGesture;
//////////////////////  æ¸…除缓存API  //////////////////////
/** æ¸…除图片缓存(此次升级后统一使用SDWebImage管理图片加载和缓存)  */
+ (void)clearImagesCache;
/** æ¸…除图片缓存(兼容旧版本方法) */
- (void)clearCache;
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/SDCycleScrollView.m
New file
@@ -0,0 +1,706 @@
//
//  SDCycleScrollView.m
//  SDCycleScrollView
//
//  Created by aier on 15-3-22.
//  Copyright (c) 2015å¹´ GSD. All rights reserved.
//
/*
 *********************************************************************************
 *
 * ðŸŒŸðŸŒŸðŸŒŸ æ–°å»ºSDCycleScrollView交流QQ群:185534916 ðŸŒŸðŸŒŸðŸŒŸ
 *
 * åœ¨æ‚¨ä½¿ç”¨æ­¤è‡ªåŠ¨è½®æ’­åº“çš„è¿‡ç¨‹ä¸­å¦‚æžœå‡ºçŽ°bug请及时以以下任意一种方式联系我们,我们会及时修复bugå¹¶
 * å¸®æ‚¨è§£å†³é—®é¢˜ã€‚
 * æ–°æµªå¾®åš:GSD_iOS
 * Email : gsdios@126.com
 * GitHub: https://github.com/gsdios
 *
 * å¦ï¼ˆæˆ‘的自动布局库SDAutoLayout):
 *  ä¸€è¡Œä»£ç æžå®šè‡ªåŠ¨å¸ƒå±€ï¼æ”¯æŒCell和Tableview高度自适应,Label和ScrollView内容自适应,致力于
 *  åšæœ€ç®€å•易用的AutoLayout库。
 * è§†é¢‘教程:http://www.letv.com/ptv/vplay/24038772.html
 * ç”¨æ³•示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
 * GitHub:https://github.com/gsdios/SDAutoLayout
 *********************************************************************************
 */
#import "SDCycleScrollView.h"
#import "SDCollectionViewCell.h"
#import "UIView+SDExtension.h"
#import "TAPageControl.h"
#import "SDWebImageManager.h"
#import "UIImageView+WebCache.h"
#define kCycleScrollViewInitialPageControlDotSize CGSizeMake(10, 10)
NSString * const ID = @"SDCycleScrollViewCell";
@interface SDCycleScrollView () <UICollectionViewDataSource, UICollectionViewDelegate>
@property (nonatomic, weak) UICollectionView *mainView; // æ˜¾ç¤ºå›¾ç‰‡çš„collectionView
@property (nonatomic, weak) UICollectionViewFlowLayout *flowLayout;
@property (nonatomic, strong) NSArray *imagePathsGroup;
@property (nonatomic, weak) NSTimer *timer;
@property (nonatomic, assign) NSInteger totalItemsCount;
@property (nonatomic, weak) UIControl *pageControl;
@property (nonatomic, strong) UIImageView *backgroundImageView; // å½“imageURLs为空时的背景图
@end
@implementation SDCycleScrollView
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self initialization];
        [self setupMainView];
    }
    return self;
}
- (void)awakeFromNib
{
    [super awakeFromNib];
    [self initialization];
    [self setupMainView];
}
- (void)initialization
{
    _pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
    _autoScrollTimeInterval = 2.0;
    _titleLabelTextColor = [UIColor whiteColor];
    _titleLabelTextFont= [UIFont systemFontOfSize:14];
    _titleLabelBackgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    _titleLabelHeight = 30;
    _titleLabelTextAlignment = NSTextAlignmentLeft;
    _autoScroll = YES;
    _infiniteLoop = YES;
    _showPageControl = YES;
    _pageControlDotSize = kCycleScrollViewInitialPageControlDotSize;
    _pageControlBottomOffset = 0;
    _pageControlRightOffset = 0;
    _pageControlStyle = SDCycleScrollViewPageContolStyleClassic;
    _hidesForSinglePage = YES;
    _currentPageDotColor = [UIColor whiteColor];
    _pageDotColor = [UIColor lightGrayColor];
    _bannerImageViewContentMode = UIViewContentModeScaleToFill;
    self.backgroundColor = [UIColor lightGrayColor];
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageNamesGroup:(NSArray *)imageNamesGroup
{
    SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
    cycleScrollView.localizationImageNamesGroup = [NSMutableArray arrayWithArray:imageNamesGroup];
    return cycleScrollView;
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame shouldInfiniteLoop:(BOOL)infiniteLoop imageNamesGroup:(NSArray *)imageNamesGroup
{
    SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
    cycleScrollView.infiniteLoop = infiniteLoop;
    cycleScrollView.localizationImageNamesGroup = [NSMutableArray arrayWithArray:imageNamesGroup];
    return cycleScrollView;
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageURLStringsGroup:(NSArray *)imageURLsGroup
{
    SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
    cycleScrollView.imageURLStringsGroup = [NSMutableArray arrayWithArray:imageURLsGroup];
    return cycleScrollView;
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame delegate:(id<SDCycleScrollViewDelegate>)delegate placeholderImage:(UIImage *)placeholderImage
{
    SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
    cycleScrollView.delegate = delegate;
    cycleScrollView.placeholderImage = placeholderImage;
    return cycleScrollView;
}
// è®¾ç½®æ˜¾ç¤ºå›¾ç‰‡çš„collectionView
- (void)setupMainView
{
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    flowLayout.minimumLineSpacing = 0;
    flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    _flowLayout = flowLayout;
    UICollectionView *mainView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:flowLayout];
    mainView.backgroundColor = [UIColor clearColor];
    mainView.pagingEnabled = YES;
    mainView.showsHorizontalScrollIndicator = NO;
    mainView.showsVerticalScrollIndicator = NO;
    [mainView registerClass:[SDCollectionViewCell class] forCellWithReuseIdentifier:ID];
    mainView.dataSource = self;
    mainView.delegate = self;
    mainView.scrollsToTop = NO;
    [self addSubview:mainView];
    _mainView = mainView;
}
#pragma mark - properties
- (void)setDelegate:(id<SDCycleScrollViewDelegate>)delegate
{
    _delegate = delegate;
    if ([self.delegate respondsToSelector:@selector(customCollectionViewCellClassForCycleScrollView:)] && [self.delegate customCollectionViewCellClassForCycleScrollView:self]) {
        [self.mainView registerClass:[self.delegate customCollectionViewCellClassForCycleScrollView:self] forCellWithReuseIdentifier:ID];
    }else if ([self.delegate respondsToSelector:@selector(customCollectionViewCellNibForCycleScrollView:)] && [self.delegate customCollectionViewCellNibForCycleScrollView:self]) {
        [self.mainView registerNib:[self.delegate customCollectionViewCellNibForCycleScrollView:self] forCellWithReuseIdentifier:ID];
    }
}
- (void)setPlaceholderImage:(UIImage *)placeholderImage
{
    _placeholderImage = placeholderImage;
    if (!self.backgroundImageView) {
        UIImageView *bgImageView = [UIImageView new];
        [bgImageView setContentScaleFactor:[[UIScreen mainScreen] scale]];
        bgImageView.contentMode =  UIViewContentModeScaleAspectFill;
        bgImageView.clipsToBounds  = YES;
        [self insertSubview:bgImageView belowSubview:self.mainView];
        self.backgroundImageView = bgImageView;
    }
    self.backgroundImageView.image = placeholderImage;
}
- (void)setPageControlDotSize:(CGSize)pageControlDotSize
{
    _pageControlDotSize = pageControlDotSize;
    [self setupPageControl];
    if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
        TAPageControl *pageContol = (TAPageControl *)_pageControl;
        pageContol.dotSize = pageControlDotSize;
    }
}
- (void)setShowPageControl:(BOOL)showPageControl
{
    _showPageControl = showPageControl;
    _pageControl.hidden = !showPageControl;
}
- (void)setCurrentPageDotColor:(UIColor *)currentPageDotColor
{
    _currentPageDotColor = currentPageDotColor;
    if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
        TAPageControl *pageControl = (TAPageControl *)_pageControl;
        pageControl.dotColor = currentPageDotColor;
    } else {
        UIPageControl *pageControl = (UIPageControl *)_pageControl;
        pageControl.currentPageIndicatorTintColor = currentPageDotColor;
    }
}
- (void)setPageDotColor:(UIColor *)pageDotColor
{
    _pageDotColor = pageDotColor;
    if ([self.pageControl isKindOfClass:[UIPageControl class]]) {
        UIPageControl *pageControl = (UIPageControl *)_pageControl;
        pageControl.pageIndicatorTintColor = pageDotColor;
    }
}
- (void)setCurrentPageDotImage:(UIImage *)currentPageDotImage
{
    _currentPageDotImage = currentPageDotImage;
    if (self.pageControlStyle != SDCycleScrollViewPageContolStyleAnimated) {
        self.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;
    }
    [self setCustomPageControlDotImage:currentPageDotImage isCurrentPageDot:YES];
}
- (void)setPageDotImage:(UIImage *)pageDotImage
{
    _pageDotImage = pageDotImage;
    if (self.pageControlStyle != SDCycleScrollViewPageContolStyleAnimated) {
        self.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;
    }
    [self setCustomPageControlDotImage:pageDotImage isCurrentPageDot:NO];
}
- (void)setCustomPageControlDotImage:(UIImage *)image isCurrentPageDot:(BOOL)isCurrentPageDot
{
    if (!image || !self.pageControl) return;
    if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
        TAPageControl *pageControl = (TAPageControl *)_pageControl;
        if (isCurrentPageDot) {
            pageControl.currentDotImage = image;
        } else {
            pageControl.dotImage = image;
        }
    }
}
- (void)setInfiniteLoop:(BOOL)infiniteLoop
{
    _infiniteLoop = infiniteLoop;
    if (self.imagePathsGroup.count) {
        self.imagePathsGroup = self.imagePathsGroup;
    }
}
-(void)setAutoScroll:(BOOL)autoScroll{
    _autoScroll = autoScroll;
    [self invalidateTimer];
    if (_autoScroll) {
        [self setupTimer];
    }
}
- (void)setScrollDirection:(UICollectionViewScrollDirection)scrollDirection
{
    _scrollDirection = scrollDirection;
    _flowLayout.scrollDirection = scrollDirection;
}
- (void)setAutoScrollTimeInterval:(CGFloat)autoScrollTimeInterval
{
    _autoScrollTimeInterval = autoScrollTimeInterval;
    [self setAutoScroll:self.autoScroll];
}
- (void)setPageControlStyle:(SDCycleScrollViewPageContolStyle)pageControlStyle
{
    _pageControlStyle = pageControlStyle;
    [self setupPageControl];
}
- (void)setImagePathsGroup:(NSArray *)imagePathsGroup
{
    [self invalidateTimer];
    _imagePathsGroup = imagePathsGroup;
    _totalItemsCount = self.infiniteLoop ? self.imagePathsGroup.count * 100 : self.imagePathsGroup.count;
    if (imagePathsGroup.count > 1) { // ç”±äºŽ !=1 åŒ…含count == 0等情况
        self.mainView.scrollEnabled = YES;
        [self setAutoScroll:self.autoScroll];
    } else {
        self.mainView.scrollEnabled = NO;
        [self invalidateTimer];
    }
    [self setupPageControl];
    [self.mainView reloadData];
}
- (void)setImageURLStringsGroup:(NSArray *)imageURLStringsGroup
{
    _imageURLStringsGroup = imageURLStringsGroup;
    NSMutableArray *temp = [NSMutableArray new];
    [_imageURLStringsGroup enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * stop) {
        NSString *urlString;
        if ([obj isKindOfClass:[NSString class]]) {
            urlString = obj;
        } else if ([obj isKindOfClass:[NSURL class]]) {
            NSURL *url = (NSURL *)obj;
            urlString = [url absoluteString];
        }
        if (urlString) {
            [temp addObject:urlString];
        }
    }];
    self.imagePathsGroup = [temp copy];
}
- (void)setLocalizationImageNamesGroup:(NSArray *)localizationImageNamesGroup
{
    _localizationImageNamesGroup = localizationImageNamesGroup;
    self.imagePathsGroup = [localizationImageNamesGroup copy];
}
- (void)setTitlesGroup:(NSArray *)titlesGroup
{
    _titlesGroup = titlesGroup;
    if (self.onlyDisplayText) {
        NSMutableArray *temp = [NSMutableArray new];
        for (int i = 0; i < _titlesGroup.count; i++) {
            [temp addObject:@""];
        }
        self.backgroundColor = [UIColor clearColor];
        self.imageURLStringsGroup = [temp copy];
    }
}
- (void)disableScrollGesture {
    self.mainView.canCancelContentTouches = NO;
    for (UIGestureRecognizer *gesture in self.mainView.gestureRecognizers) {
        if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
            [self.mainView removeGestureRecognizer:gesture];
        }
    }
}
#pragma mark - actions
- (void)setupTimer
{
    [self invalidateTimer]; // åˆ›å»ºå®šæ—¶å™¨å‰å…ˆåœæ­¢å®šæ—¶å™¨ï¼Œä¸ç„¶ä¼šå‡ºçŽ°åƒµå°¸å®šæ—¶å™¨ï¼Œå¯¼è‡´è½®æ’­é¢‘çŽ‡é”™è¯¯
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:self.autoScrollTimeInterval target:self selector:@selector(automaticScroll) userInfo:nil repeats:YES];
    _timer = timer;
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)invalidateTimer
{
    [_timer invalidate];
    _timer = nil;
}
- (void)setupPageControl
{
    if (_pageControl) [_pageControl removeFromSuperview]; // é‡æ–°åŠ è½½æ•°æ®æ—¶è°ƒæ•´
    if (self.imagePathsGroup.count == 0 || self.onlyDisplayText) return;
    if ((self.imagePathsGroup.count == 1) && self.hidesForSinglePage) return;
    int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:[self currentIndex]];
    switch (self.pageControlStyle) {
        case SDCycleScrollViewPageContolStyleAnimated:
        {
            TAPageControl *pageControl = [[TAPageControl alloc] init];
            pageControl.numberOfPages = self.imagePathsGroup.count;
            pageControl.dotColor = self.currentPageDotColor;
            pageControl.userInteractionEnabled = NO;
            pageControl.currentPage = indexOnPageControl;
            [self addSubview:pageControl];
            _pageControl = pageControl;
        }
            break;
        case SDCycleScrollViewPageContolStyleClassic:
        {
            UIPageControl *pageControl = [[UIPageControl alloc] init];
            pageControl.numberOfPages = self.imagePathsGroup.count;
            pageControl.currentPageIndicatorTintColor = self.currentPageDotColor;
            pageControl.pageIndicatorTintColor = self.pageDotColor;
            pageControl.userInteractionEnabled = NO;
            pageControl.currentPage = indexOnPageControl;
            [self addSubview:pageControl];
            _pageControl = pageControl;
        }
            break;
        default:
            break;
    }
    // é‡è®¾pagecontroldot图片
    if (self.currentPageDotImage) {
        self.currentPageDotImage = self.currentPageDotImage;
    }
    if (self.pageDotImage) {
        self.pageDotImage = self.pageDotImage;
    }
}
- (void)automaticScroll
{
    if (0 == _totalItemsCount) return;
    int currentIndex = [self currentIndex];
    int targetIndex = currentIndex + 1;
    [self scrollToIndex:targetIndex];
}
- (void)scrollToIndex:(int)targetIndex
{
    if (targetIndex >= _totalItemsCount) {
        if (self.infiniteLoop) {
            targetIndex = _totalItemsCount * 0.5;
            [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
        }
        return;
    }
    [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}
- (int)currentIndex
{
    if (_mainView.sd_width == 0 || _mainView.sd_height == 0) {
        return 0;
    }
    int index = 0;
    if (_flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
        index = (_mainView.contentOffset.x + _flowLayout.itemSize.width * 0.5) / _flowLayout.itemSize.width;
    } else {
        index = (_mainView.contentOffset.y + _flowLayout.itemSize.height * 0.5) / _flowLayout.itemSize.height;
    }
    return MAX(0, index);
}
- (int)pageControlIndexWithCurrentCellIndex:(NSInteger)index
{
    return (int)index % self.imagePathsGroup.count;
}
- (void)clearCache
{
    [[self class] clearImagesCache];
}
+ (void)clearImagesCache
{
    //[[[SDWebImageManager sharedManager] imageCache] clearWithCacheType:SDImageCacheTypeDisk completion:nil ];
    [[[SDWebImageManager sharedManager] imageCache] clearDiskOnCompletion:^{}];
}
#pragma mark - life circles
- (void)layoutSubviews
{
    self.delegate = self.delegate;
    [super layoutSubviews];
    _flowLayout.itemSize = self.frame.size;
    _mainView.frame = self.bounds;
    if (_mainView.contentOffset.x == 0 &&  _totalItemsCount) {
        int targetIndex = 0;
        if (self.infiniteLoop) {
            targetIndex = _totalItemsCount * 0.5;
        }else{
            targetIndex = 0;
        }
        [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
    }
    CGSize size = CGSizeZero;
    if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
        TAPageControl *pageControl = (TAPageControl *)_pageControl;
        if (!(self.pageDotImage && self.currentPageDotImage && CGSizeEqualToSize(kCycleScrollViewInitialPageControlDotSize, self.pageControlDotSize))) {
            pageControl.dotSize = self.pageControlDotSize;
        }
        size = [pageControl sizeForNumberOfPages:self.imagePathsGroup.count];
    } else {
        size = CGSizeMake(self.imagePathsGroup.count * self.pageControlDotSize.width * 1.5, self.pageControlDotSize.height);
        // ios14 éœ€è¦æŒ‰ç…§ç³»ç»Ÿè§„则适配pageControl size
        if (@available(iOS 14.0, *)) {
            if ([self.pageControl isKindOfClass:[UIPageControl class]]) {
                UIPageControl *pageControl = (UIPageControl *)_pageControl;
                size.width = [pageControl sizeForNumberOfPages:self.imagePathsGroup.count].width;
            }
        }
    }
    CGFloat x = (self.sd_width - size.width) * 0.5;
    if (self.pageControlAliment == SDCycleScrollViewPageContolAlimentRight) {
        x = self.mainView.sd_width - size.width - 10;
    }
    CGFloat y = self.mainView.sd_height - size.height - 10;
    if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
        TAPageControl *pageControl = (TAPageControl *)_pageControl;
        [pageControl sizeToFit];
    }
    CGRect pageControlFrame = CGRectMake(x, y, size.width, size.height);
    pageControlFrame.origin.y -= self.pageControlBottomOffset;
    pageControlFrame.origin.x -= self.pageControlRightOffset;
    self.pageControl.frame = pageControlFrame;
    self.pageControl.hidden = !_showPageControl;
    if (self.backgroundImageView) {
        self.backgroundImageView.frame = self.bounds;
    }
}
//解决当父View释放时,当前视图因为被Timer强引用而不能释放的问题
- (void)willMoveToSuperview:(UIView *)newSuperview
{
    if (!newSuperview) {
        [self invalidateTimer];
    }
}
//解决当timer释放后 å›žè°ƒscrollViewDidScroll时访问野指针导致崩溃
- (void)dealloc {
    _mainView.delegate = nil;
    _mainView.dataSource = nil;
}
#pragma mark - public actions
- (void)adjustWhenControllerViewWillAppera
{
    long targetIndex = [self currentIndex];
    if (targetIndex < _totalItemsCount) {
        [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
    }
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return _totalItemsCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    SDCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
    long itemIndex = [self pageControlIndexWithCurrentCellIndex:indexPath.item];
    if ([self.delegate respondsToSelector:@selector(setupCustomCell:forIndex:cycleScrollView:)] &&
        [self.delegate respondsToSelector:@selector(customCollectionViewCellClassForCycleScrollView:)] && [self.delegate customCollectionViewCellClassForCycleScrollView:self]) {
        [self.delegate setupCustomCell:cell forIndex:itemIndex cycleScrollView:self];
        return cell;
    }else if ([self.delegate respondsToSelector:@selector(setupCustomCell:forIndex:cycleScrollView:)] &&
              [self.delegate respondsToSelector:@selector(customCollectionViewCellNibForCycleScrollView:)] && [self.delegate customCollectionViewCellNibForCycleScrollView:self]) {
        [self.delegate setupCustomCell:cell forIndex:itemIndex cycleScrollView:self];
        return cell;
    }
    NSString *imagePath = self.imagePathsGroup[itemIndex];
    if (!self.onlyDisplayText && [imagePath isKindOfClass:[NSString class]]) {
        if ([imagePath hasPrefix:@"http"]) {
            [cell.imageView sd_setImageWithURL:[NSURL URLWithString:imagePath] placeholderImage:self.placeholderImage];
        } else {
            UIImage *image = [UIImage imageNamed:imagePath];
            if (!image) {
                image = [UIImage imageWithContentsOfFile:imagePath];
            }
            cell.imageView.image = image;
        }
    } else if (!self.onlyDisplayText && [imagePath isKindOfClass:[UIImage class]]) {
        cell.imageView.image = (UIImage *)imagePath;
    }
    if (_titlesGroup.count && itemIndex < _titlesGroup.count) {
        cell.title = _titlesGroup[itemIndex];
    }
    if (!cell.hasConfigured) {
        cell.titleLabelBackgroundColor = self.titleLabelBackgroundColor;
        cell.titleLabelHeight = self.titleLabelHeight;
        cell.titleLabelTextAlignment = self.titleLabelTextAlignment;
        cell.titleLabelTextColor = self.titleLabelTextColor;
        cell.titleLabelTextFont = self.titleLabelTextFont;
        cell.hasConfigured = YES;
        cell.imageView.contentMode = self.bannerImageViewContentMode;
        [cell.imageView setContentScaleFactor:[[UIScreen mainScreen] scale]];
        cell.imageView.contentMode =  UIViewContentModeScaleAspectFill;
        cell.imageView.clipsToBounds  = YES;
        cell.clipsToBounds = YES;
        cell.onlyDisplayText = self.onlyDisplayText;
    }
    return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self.delegate respondsToSelector:@selector(cycleScrollView:didSelectItemAtIndex:)]) {
        [self.delegate cycleScrollView:self didSelectItemAtIndex:[self pageControlIndexWithCurrentCellIndex:indexPath.item]];
    }
    if (self.clickItemOperationBlock) {
        self.clickItemOperationBlock([self pageControlIndexWithCurrentCellIndex:indexPath.item]);
    }
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (!self.imagePathsGroup.count) return; // è§£å†³æ¸…除timer时偶尔会出现的问题
    int itemIndex = [self currentIndex];
    int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:itemIndex];
    if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
        TAPageControl *pageControl = (TAPageControl *)_pageControl;
        pageControl.currentPage = indexOnPageControl;
    } else {
        UIPageControl *pageControl = (UIPageControl *)_pageControl;
        pageControl.currentPage = indexOnPageControl;
    }
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    if (self.autoScroll) {
        [self invalidateTimer];
    }
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (self.autoScroll) {
        [self setupTimer];
    }
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self scrollViewDidEndScrollingAnimation:self.mainView];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    if (!self.imagePathsGroup.count) return; // è§£å†³æ¸…除timer时偶尔会出现的问题
    int itemIndex = [self currentIndex];
    int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:itemIndex];
    if ([self.delegate respondsToSelector:@selector(cycleScrollView:didScrollToIndex:)]) {
        [self.delegate cycleScrollView:self didScrollToIndex:indexOnPageControl];
    } else if (self.itemDidScrollOperationBlock) {
        self.itemDidScrollOperationBlock(indexOnPageControl);
    }
}
- (void)makeScrollViewScrollToIndex:(NSInteger)index{
    if (self.autoScroll) {
        [self invalidateTimer];
    }
    if (0 == _totalItemsCount) return;
    [self scrollToIndex:(int)(_totalItemsCount * 0.5 + index)];
    if (self.autoScroll) {
        [self setupTimer];
    }
}
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/UIView+SDExtension.h
New file
@@ -0,0 +1,44 @@
//
//  UIView+SDExtension.h
//  SDRefreshView
//
//  Created by aier on 15-2-23.
//  Copyright (c) 2015å¹´ GSD. All rights reserved.
//
/*
 *********************************************************************************
 *
 * ðŸŒŸðŸŒŸðŸŒŸ æ–°å»ºSDCycleScrollView交流QQ群:185534916 ðŸŒŸðŸŒŸðŸŒŸ
 *
 * åœ¨æ‚¨ä½¿ç”¨æ­¤è‡ªåŠ¨è½®æ’­åº“çš„è¿‡ç¨‹ä¸­å¦‚æžœå‡ºçŽ°bug请及时以以下任意一种方式联系我们,我们会及时修复bugå¹¶
 * å¸®æ‚¨è§£å†³é—®é¢˜ã€‚
 * æ–°æµªå¾®åš:GSD_iOS
 * Email : gsdios@126.com
 * GitHub: https://github.com/gsdios
 *
 * å¦ï¼ˆæˆ‘的自动布局库SDAutoLayout):
 *  ä¸€è¡Œä»£ç æžå®šè‡ªåŠ¨å¸ƒå±€ï¼æ”¯æŒCell和Tableview高度自适应,Label和ScrollView内容自适应,致力于
 *  åšæœ€ç®€å•易用的AutoLayout库。
 * è§†é¢‘教程:http://www.letv.com/ptv/vplay/24038772.html
 * ç”¨æ³•示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
 * GitHub:https://github.com/gsdios/SDAutoLayout
 *********************************************************************************
 */
#import <UIKit/UIKit.h>
#define SDColorCreater(r, g, b, a) [UIColor colorWithRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:a]
@interface UIView (SDExtension)
@property (nonatomic, assign) CGFloat sd_height;
@property (nonatomic, assign) CGFloat sd_width;
@property (nonatomic, assign) CGFloat sd_y;
@property (nonatomic, assign) CGFloat sd_x;
@end
BuWanVideo2.0/Recommend/lib/SDCycleScrollView/UIView+SDExtension.m
New file
@@ -0,0 +1,107 @@
//
//  UIView+SDExtension.m
//  SDRefreshView
//
//  Created by aier on 15-2-23.
//  Copyright (c) 2015å¹´ GSD. All rights reserved.
//
/*
 *********************************************************************************
 *
 * ðŸŒŸðŸŒŸðŸŒŸ æ–°å»ºSDCycleScrollView交流QQ群:185534916 ðŸŒŸðŸŒŸðŸŒŸ
 *
 * åœ¨æ‚¨ä½¿ç”¨æ­¤è‡ªåŠ¨è½®æ’­åº“çš„è¿‡ç¨‹ä¸­å¦‚æžœå‡ºçŽ°bug请及时以以下任意一种方式联系我们,我们会及时修复bugå¹¶
 * å¸®æ‚¨è§£å†³é—®é¢˜ã€‚
 * æ–°æµªå¾®åš:GSD_iOS
 * Email : gsdios@126.com
 * GitHub: https://github.com/gsdios
 *
 * å¦ï¼ˆæˆ‘的自动布局库SDAutoLayout):
 *  ä¸€è¡Œä»£ç æžå®šè‡ªåŠ¨å¸ƒå±€ï¼æ”¯æŒCell和Tableview高度自适应,Label和ScrollView内容自适应,致力于
 *  åšæœ€ç®€å•易用的AutoLayout库。
 * è§†é¢‘教程:http://www.letv.com/ptv/vplay/24038772.html
 * ç”¨æ³•示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
 * GitHub:https://github.com/gsdios/SDAutoLayout
 *********************************************************************************
 */
/*
 *********************************************************************************
 *
 * åœ¨æ‚¨ä½¿ç”¨æ­¤è‡ªåŠ¨è½®æ’­åº“çš„è¿‡ç¨‹ä¸­å¦‚æžœå‡ºçŽ°bug请及时以以下任意一种方式联系我们,我们会及时修复bugå¹¶
 * å¸®æ‚¨è§£å†³é—®é¢˜ã€‚
 * æ–°æµªå¾®åš:GSD_iOS
 * Email : gsdios@126.com
 * GitHub: https://github.com/gsdios
 *
 * å¦ï¼ˆæˆ‘的自动布局库SDAutoLayout):
 *  ä¸€è¡Œä»£ç æžå®šè‡ªåŠ¨å¸ƒå±€ï¼æ”¯æŒCell和Tableview高度自适应,Label和ScrollView内容自适应,致力于
 *  åšæœ€ç®€å•易用的AutoLayout库。
 * è§†é¢‘教程:http://www.letv.com/ptv/vplay/24038772.html
 * ç”¨æ³•示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
 * GitHub:https://github.com/gsdios/SDAutoLayout
 *********************************************************************************
 */
#import "UIView+SDExtension.h"
@implementation UIView (SDExtension)
- (CGFloat)sd_height
{
    return self.frame.size.height;
}
- (void)setSd_height:(CGFloat)sd_height
{
    CGRect temp = self.frame;
    temp.size.height = sd_height;
    self.frame = temp;
}
- (CGFloat)sd_width
{
    return self.frame.size.width;
}
- (void)setSd_width:(CGFloat)sd_width
{
    CGRect temp = self.frame;
    temp.size.width = sd_width;
    self.frame = temp;
}
- (CGFloat)sd_y
{
    return self.frame.origin.y;
}
- (void)setSd_y:(CGFloat)sd_y
{
    CGRect temp = self.frame;
    temp.origin.y = sd_y;
    self.frame = temp;
}
- (CGFloat)sd_x
{
    return self.frame.origin.x;
}
- (void)setSd_x:(CGFloat)sd_x
{
    CGRect temp = self.frame;
    temp.origin.x = sd_x;
    self.frame = temp;
}
@end
BuWanVideo2.0/Recommend/lib/UICollectionViewLeftAlignedLayout/UICollectionViewLeftAlignedLayout.h
New file
@@ -0,0 +1,40 @@
// Copyright (c) 2014 Giovanni Lodi
//
// 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.
/**
 *  Simple UICollectionViewFlowLayout that aligns the cells to the left rather than justify them
 *
 *  Based on http://stackoverflow.com/questions/13017257/how-do-you-determine-spacing-between-cells-in-uicollectionview-flowlayout
 */
#import <UIKit/UIKit.h>
@interface UICollectionViewLeftAlignedLayout : UICollectionViewFlowLayout
@end
/**
 *  Just a convenience protocol to keep things consistent.
 *  Someone could find it confusing for a delegate object to conform to UICollectionViewDelegateFlowLayout
 *  while using UICollectionViewLeftAlignedLayout.
 */
@protocol UICollectionViewDelegateLeftAlignedLayout <UICollectionViewDelegateFlowLayout>
@end
BuWanVideo2.0/Recommend/lib/UICollectionViewLeftAlignedLayout/UICollectionViewLeftAlignedLayout.m
New file
@@ -0,0 +1,117 @@
// Copyright (c) 2014 Giovanni Lodi
//
// 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 "UICollectionViewLeftAlignedLayout.h"
@interface UICollectionViewLayoutAttributes (LeftAligned)
- (void)leftAlignFrameWithSectionInset:(UIEdgeInsets)sectionInset;
@end
@implementation UICollectionViewLayoutAttributes (LeftAligned)
- (void)leftAlignFrameWithSectionInset:(UIEdgeInsets)sectionInset
{
    CGRect frame = self.frame;
    frame.origin.x = sectionInset.left;
    self.frame = frame;
}
@end
#pragma mark -
@implementation UICollectionViewLeftAlignedLayout
#pragma mark - UICollectionViewLayout
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *originalAttributes = [super layoutAttributesForElementsInRect:rect];
    NSMutableArray *updatedAttributes = [NSMutableArray arrayWithArray:originalAttributes];
    for (UICollectionViewLayoutAttributes *attributes in originalAttributes) {
        if (!attributes.representedElementKind) {
            NSUInteger index = [updatedAttributes indexOfObject:attributes];
            updatedAttributes[index] = [self layoutAttributesForItemAtIndexPath:attributes.indexPath];
        }
    }
    return updatedAttributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes* currentItemAttributes = [[super layoutAttributesForItemAtIndexPath:indexPath] copy];
    UIEdgeInsets sectionInset = [self evaluatedSectionInsetForItemAtIndex:indexPath.section];
    BOOL isFirstItemInSection = indexPath.item == 0;
    CGFloat layoutWidth = CGRectGetWidth(self.collectionView.frame) - sectionInset.left - sectionInset.right;
    if (isFirstItemInSection) {
        [currentItemAttributes leftAlignFrameWithSectionInset:sectionInset];
        return currentItemAttributes;
    }
    NSIndexPath* previousIndexPath = [NSIndexPath indexPathForItem:indexPath.item-1 inSection:indexPath.section];
    CGRect previousFrame = [self layoutAttributesForItemAtIndexPath:previousIndexPath].frame;
    CGFloat previousFrameRightPoint = previousFrame.origin.x + previousFrame.size.width;
    CGRect currentFrame = currentItemAttributes.frame;
    CGRect strecthedCurrentFrame = CGRectMake(sectionInset.left,
                                              currentFrame.origin.y,
                                              layoutWidth,
                                              currentFrame.size.height);
    // if the current frame, once left aligned to the left and stretched to the full collection view
    // width intersects the previous frame then they are on the same line
    BOOL isFirstItemInRow = !CGRectIntersectsRect(previousFrame, strecthedCurrentFrame);
    if (isFirstItemInRow) {
        // make sure the first item on a line is left aligned
        [currentItemAttributes leftAlignFrameWithSectionInset:sectionInset];
        return currentItemAttributes;
    }
    CGRect frame = currentItemAttributes.frame;
    frame.origin.x = previousFrameRightPoint + [self evaluatedMinimumInteritemSpacingForSectionAtIndex:indexPath.section];
    currentItemAttributes.frame = frame;
    return currentItemAttributes;
}
- (CGFloat)evaluatedMinimumInteritemSpacingForSectionAtIndex:(NSInteger)sectionIndex
{
    if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {
        id<UICollectionViewDelegateLeftAlignedLayout> delegate = (id<UICollectionViewDelegateLeftAlignedLayout>)self.collectionView.delegate;
        return [delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:sectionIndex];
    } else {
        return self.minimumInteritemSpacing;
    }
}
- (UIEdgeInsets)evaluatedSectionInsetForItemAtIndex:(NSInteger)index
{
    if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
        id<UICollectionViewDelegateLeftAlignedLayout> delegate = (id<UICollectionViewDelegateLeftAlignedLayout>)self.collectionView.delegate;
        return [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:index];
    } else {
        return self.sectionInset;
    }
}
@end
BuWanVideo2.0/SearchController.h
New file
@@ -0,0 +1,19 @@
//
//  SearchController.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SearchController : UIViewController
@property (nonatomic, nullable, copy) NSString *ptitle;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/SearchController.m
New file
@@ -0,0 +1,242 @@
//
//  SearchController.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "SearchController.h"
#import "SearchNavView.h"
#import "SearchHotCell.h"
#import "SearchRecordCell.h"
#import "SearchHotSearchCell.h"
#import "SearchRecordHeaderView.h"
#import "UICollectionViewLeftAlignedLayout.h"
@interface SearchController () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) SearchNavView *viewSearchNav;
@property (nonatomic, nullable, strong) UICollectionView *collectionView;
@property (nonatomic, nullable, strong) NSMutableArray *arrayHot;
@property (nonatomic, nullable, strong) NSMutableArray *arrayRecord;
@property (nonatomic, nullable, strong) NSDictionary *dictionaryHotSerch;
@end
@implementation SearchController
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    self.navigationController.navigationBar.translucent = NO;
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupDataConfig];
    [self setupViewConfig];
    [self loadData];
}
- (void)setupDataConfig {
    for (int i = 0; i < 10; i++) {
        [self.arrayRecord addObject:@"二十不惑"];
    }
}
- (void)loadData {
    [[YTHNetInterface startInterface] fetchHotSerchListWithUid:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            self.dictionaryHotSerch = result[@"Data"][@"data"];
            __weak typeof(self) weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf.collectionView reloadData];
            });
        }
    }];
}
- (void)setupViewConfig {
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.viewSearchNav];
    self.viewSearchNav.title = self.ptitle;
    __weak typeof(self) weakSelf = self;
    self.viewSearchNav.onCacel = ^{
        [weakSelf.view endEditing:YES];
        [weakSelf.navigationController popViewControllerAnimated:YES];
    };
    [self.view addSubview:self.collectionView];
}
- (CGFloat)calculateRowWidth:(NSString *)string fontSize:(float)fontSize height:(float)height {
    NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
    CGRect rect = [string boundingRectWithSize:CGSizeMake(0, height)options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:dic context:nil];
    return rect.size.width;
}
#pragma mark UICollectionViewDelegate, UICollectionViewDataSource
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    //[self cellClick:indexPath];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 3;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section == 0) {
        return 0;
    } else if (section == 1) {
        return _arrayRecord.count;
    } else {
        return 1;
    }
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        SearchHotCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SearchHotCell" forIndexPath:indexPath];
        return cell;
    }  else if (indexPath.section == 1) {
        SearchRecordCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SearchRecordCell" forIndexPath:indexPath];
        cell.name = self.arrayRecord[indexPath.row];
        return cell;
    } else {
        SearchHotSearchCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SearchHotSearchCell" forIndexPath:indexPath];
        cell.data = _dictionaryHotSerch;
        return cell;
    }
}
// å®šåˆ¶collectionView的head和foot
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    if (kind == UICollectionElementKindSectionHeader) {
        if (indexPath.section == 1) {
            SearchRecordHeaderView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"SearchRecordHeaderView" forIndexPath:indexPath];
            return view;
        }
    }
    UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView" forIndexPath:indexPath];
    return view;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
    //宽度随便定,系统会自动取collectionView的宽度
    //高度为分组头的高度
    if (section == 0) {
        return CGSizeMake(KScreenW, 10);
    } else if (section == 1) {
        return CGSizeMake(KScreenW, 20 + 16 + 16);
    }
    return CGSizeMake(KScreenW, 28);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return CGSizeMake(KScreenW, CGFLOAT_MIN);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        return  CGSizeMake(KScreenW, 36);
    } else if (indexPath.section == 1) {
        NSString *IntroductionStr = nil;
        IntroductionStr = _arrayRecord[indexPath.row];
        CGFloat width = [self calculateRowWidth:IntroductionStr fontSize:13 height:29];
        CGSize titleSize = CGSizeMake(width + 30, 29);
        return titleSize;
    } else {
        return  CGSizeMake(KScreenW, 198);
    }
}
//协议中的方法,用于返回整个CollectionView上、左、下、右距四边的间距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    if (section == 1) {
        return UIEdgeInsetsMake(0, 11, 0, 11);
    }
    return UIEdgeInsetsMake(0, 0, 0, 0);
}
//两行cell之间的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 1) {
        return 14;
    }
    return CGFLOAT_MIN;
}
//同一行两个cell的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    if (section == 1) {
        return 16;
    }
    return 0;
}
- (UICollectionView *)collectionView {
    if (!_collectionView) {
        UICollectionViewLeftAlignedLayout *flow = [[UICollectionViewLeftAlignedLayout alloc] init];
        //指定布局方式为垂直
        flow.scrollDirection = UICollectionViewScrollDirectionVertical;
        // STATUSBAR_HEIGHT + 27
        //创建CollectionView并指定布局对象
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, kStatusBarH + ALNavBarH,  KScreenW, KScreenH  - kStatusBarH - ALNavBarH) collectionViewLayout:flow];
        _collectionView.backgroundColor = [UIColor whiteColor];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        _collectionView.delaysContentTouches = NO;
        _collectionView.showsVerticalScrollIndicator = NO;
        [_collectionView registerClass:[SearchHotCell class] forCellWithReuseIdentifier:@"SearchHotCell"];
        [_collectionView registerClass:[SearchRecordCell class] forCellWithReuseIdentifier:@"SearchRecordCell"];
        [_collectionView registerClass:[SearchHotSearchCell class] forCellWithReuseIdentifier:@"SearchHotSearchCell"];
        [_collectionView registerClass:[SearchRecordHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"SearchRecordHeaderView"];
        [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"UICollectionReusableView"];
    }
    return _collectionView;
}
- (SearchNavView *)viewSearchNav {
    if (!_viewSearchNav) {
        _viewSearchNav = [[SearchNavView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, kStatusBarH + ALNavBarH)];
    }
    return _viewSearchNav;
}
- (NSMutableArray *)arrayRecord {
    if (!_arrayRecord) {
        _arrayRecord = [[NSMutableArray alloc] init];
    }
    return _arrayRecord;
}
- (NSMutableArray *)arrayHot {
    if (!_arrayHot) {
        _arrayHot = [[NSMutableArray alloc] init];
    }
    return _arrayHot;
}
@end
BuWanVideo2.0/SearchHotCell.h
New file
@@ -0,0 +1,17 @@
//
//  SearchHotCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SearchHotCell : UICollectionViewCell
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/SearchHotCell.m
New file
@@ -0,0 +1,60 @@
//
//  SearchHotCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "SearchHotCell.h"
@interface SearchHotCell ()
@property (nonatomic, nullable, strong) UIImageView *imaegViewIcon;
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@end
@implementation SearchHotCell
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self.contentView addSubview:self.imaegViewIcon];
    [self.contentView addSubview:self.labelTitle];
    self.imaegViewIcon.sd_layout.leftSpaceToView(self.contentView, 12).topSpaceToView(self.contentView, 17).widthIs(14).heightIs(18);
    self.labelTitle.sd_layout.leftSpaceToView(self.imaegViewIcon, 10).centerYEqualToView(self.imaegViewIcon).rightSpaceToView(self.contentView, 0).heightIs(14);
}
- (UIImageView *)imaegViewIcon {
    if (!_imaegViewIcon) {
        _imaegViewIcon = [[UIImageView alloc] init];
        [_imaegViewIcon setContentScaleFactor:[[UIScreen mainScreen] scale]];
        _imaegViewIcon.contentMode =  UIViewContentModeScaleAspectFill;
        _imaegViewIcon.clipsToBounds  = YES;
        _imaegViewIcon.image = [UIImage imageNamed:@"search_hot"];
    }
    return _imaegViewIcon;
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.text = @"新·福音战士剧场版:│▌ / Evangelion: 3.0+1.0";
        _labelTitle.textColor = UICOLOR_FROM_RGB(0x000000, 1);
        _labelTitle.font = [UIFont systemFontOfSize:14];
        _labelTitle.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTitle;
}
@end
BuWanVideo2.0/SearchHotSearchCell.h
New file
@@ -0,0 +1,19 @@
//
//  SearcHotSearchViewCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SearchHotSearchCell : UICollectionViewCell
@property (nonatomic, nullable, strong) NSDictionary *data;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/SearchHotSearchCell.m
New file
@@ -0,0 +1,126 @@
//
//  SearcHotSearchViewCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "SearchHotSearchCell.h"
@interface SearchHotSearchCell ()
@property (nonatomic, nullable, strong) UIScrollView *scrollView;
@end
@implementation SearchHotSearchCell
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self addSubview:self.scrollView];
    self.scrollView.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, 0).rightSpaceToView(self, 0).bottomSpaceToView(self, 0);
}
- (void)setData:(NSDictionary *)data {
    _data = data;
    if (data) {
        if ([[self.scrollView subviews] count] > 1) {
            return;
        }
        NSUInteger count = [data allKeys].count;
        for (int i = 0; i < count; i++) {
            NSString *title = [data allKeys][i];
            UIView *viewBG = [[UIView alloc] initWithFrame:CGRectMake(10 + 10 * i + 284 * i, 0, 284, 198)];
            [self.scrollView addSubview:viewBG];
            viewBG.layer.masksToBounds = YES;
            viewBG.layer.cornerRadius = 6;
            viewBG.layer.borderWidth = 0.5;
            viewBG.layer.borderColor = [UIColor colorWithRed:255/255.0 green:236/255.0 blue:197/255.0 alpha:1.0].CGColor;
            UIView *viewTop = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 284, 32)];
            [viewBG addSubview:viewTop];
            CAGradientLayer *layer = [CAGradientLayer layer];
            layer.startPoint = CGPointMake(0, 0);//(0,0)表示从左上角开始变化。默认值是(0.5,0.0)表示从x轴为中间,y为顶端的开始变化
            layer.endPoint = CGPointMake(1, 1);//(1,1)表示到右下角变化结束。默认值是(0.5,1.0)  è¡¨ç¤ºä»Žx轴为中间,y为低端的结束变化
            layer.colors = [NSArray arrayWithObjects:UICOLOR_FROM_RGB(0xFFF8E5, 0.8).CGColor, UIColorFromRGBValue(0xFFFFFF).CGColor, nil];
            layer.locations = @[@0.0f, @1.0f];//渐变颜色的区间分布,locations的数组长度和color一致,这个值一般不用管它,默认是nil,会平均分布
            layer.frame = viewTop.layer.bounds;
            [viewTop.layer insertSublayer:layer atIndex:0];
            UILabel *labelTitle = [[UILabel alloc] initWithFrame:CGRectMake(18, 18, 200, 14)];
            labelTitle.text = title;
            labelTitle.textAlignment = NSTextAlignmentLeft;
            labelTitle.textColor = [UIColor blackColor];
            labelTitle.font = [UIFont boldSystemFontOfSize:14];
            [viewBG addSubview:labelTitle];
            NSUInteger nCount = [_data[title] count];
            for (int j = 0; j < nCount; j++) {
                NSString *name = _data[title][j];
                UILabel *labelNumber = [[UILabel alloc] init];
                labelNumber.text = [NSString stringWithFormat:@"%d", j + 1];
                labelNumber.textAlignment = NSTextAlignmentCenter;
                labelNumber.textColor = [UIColor whiteColor];
                labelNumber.font = [UIFont boldSystemFontOfSize:11];
                [viewBG addSubview:labelNumber];
                if (j == 0) {
                    labelNumber.backgroundColor = UICOLOR_FROM_RGB(0xFE3E3C, 1);
                } else if (j == 1) {
                    labelNumber.backgroundColor = UICOLOR_FROM_RGB(0xFE853C, 1);
                } else if (j == 2) {
                    labelNumber.backgroundColor = UICOLOR_FROM_RGB(0xFEC03C, 1);
                } else {
                        labelNumber.backgroundColor = UICOLOR_FROM_RGB(0xC2C2C2, 1);
                }
                labelNumber.sd_layout.leftSpaceToView(viewBG, 16).topSpaceToView(viewBG, 49 + 17 * j + 11 * j).widthIs(17).heightIs(17);
                UILabel *labelName = [[UILabel alloc] init];
                labelName.text = name;
                labelName.textAlignment = NSTextAlignmentLeft;
                labelName.textColor = [UIColor blackColor];
                labelName.font = [UIFont boldSystemFontOfSize:12];
                [viewBG addSubview:labelName];
                if (j > 4) {
                    labelNumber.sd_layout.leftSpaceToView(viewBG, 152).topSpaceToView(viewBG, 49 + 17 * (j - 5) + 11 * (j - 5)).widthIs(17).heightIs(17);
                    labelName.sd_layout.leftSpaceToView(labelNumber, 13).centerYEqualToView(labelNumber).widthIs(90).heightIs(17);
                } else {
                    labelNumber.sd_layout.leftSpaceToView(viewBG, 16).topSpaceToView(viewBG, 49 + 17 * j + 11 * j).widthIs(17).heightIs(17);
                    labelName.sd_layout.leftSpaceToView(labelNumber, 13).centerYEqualToView(labelNumber).widthIs(100).heightIs(17);
                }
                labelNumber.sd_cornerRadius = @4;
            }
        }
        self.scrollView.contentSize = CGSizeMake(10 + 10 * (count-1) + 284 * (count) + 10, 198);
    }
}
- (UIScrollView *)scrollView {
    if (!_scrollView) {
        _scrollView = [[UIScrollView alloc] init];
        _scrollView.showsHorizontalScrollIndicator = NO;
    }
    return _scrollView;
}
@end
BuWanVideo2.0/SearchNavView.h
New file
@@ -0,0 +1,22 @@
//
//  SearchNavView.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef void(^onCacel)(void);
@interface SearchNavView : UIView
@property (nonatomic, nullable, copy) NSString *title;
@property (nonatomic) onCacel onCacel;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/SearchNavView.m
New file
@@ -0,0 +1,95 @@
//
//  SearchNavView.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "SearchNavView.h"
@interface SearchNavView ()
@property (nonatomic, strong) UIView *viewNav;
@property (nonatomic, strong) UIView *viewSearch;
@property (nonatomic, nullable, strong) UITextField *textField;
@end
@implementation SearchNavView
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self addSubview:self.viewNav];
    self.viewNav.sd_layout.topSpaceToView(self, kStatusBarH).leftEqualToView(self).rightEqualToView(self).heightIs(44);
    UIButton *buttonCancel = [[UIButton alloc] init];
    [buttonCancel setTitle:@"取消" forState:UIControlStateNormal];
    [buttonCancel setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    buttonCancel.titleLabel.font = [UIFont systemFontOfSize:14];
    [self addSubview:buttonCancel];
    buttonCancel.sd_layout.rightSpaceToView(self, 20).centerYEqualToView(_viewNav).widthIs(30).heightIs(30);
    [buttonCancel addTarget:self action:@selector(touchCacel) forControlEvents:UIControlEventTouchUpInside];
    [self.viewNav addSubview:self.viewSearch];
    self.viewSearch.sd_layout.leftSpaceToView(self.viewNav, 20).centerYEqualToView(self.viewNav).rightSpaceToView(buttonCancel, 21).heightIs(34);
    self.viewSearch.sd_cornerRadius = @17;
    UIImageView *imageViewSearch = [[UIImageView alloc] init];
    imageViewSearch.image = [UIImage imageNamed:@"home_search"];
    [_viewSearch addSubview:imageViewSearch];
    imageViewSearch.sd_layout.leftSpaceToView(_viewSearch, 13).centerYEqualToView(_viewSearch).widthIs(19).heightIs(19);
    [self.viewSearch addSubview:self.textField];
    self.textField.sd_layout.leftSpaceToView(imageViewSearch, 8).centerYEqualToView(self.viewSearch).rightSpaceToView(self.viewSearch, 0).heightIs(34);
}
- (void)touchCacel {
    !self.onCacel?:self.onCacel();
}
- (void)setTitle:(NSString *)title {
    _title = title;
    if (title) {
        NSString *string = title;
        NSMutableAttributedString *placeholder = [[NSMutableAttributedString alloc] initWithString:string];
        [placeholder addAttribute:NSForegroundColorAttributeName
                            value:UICOLOR_FROM_RGB(0x787878, 1.0)
                            range:NSMakeRange(0, string.length)];
        _textField.attributedPlaceholder = placeholder;
    }
}
- (UIView *)viewNav {
    if (!_viewNav) {
        _viewNav = [[UIView alloc] init];
    }
    return _viewNav;
}
- (UIView *)viewSearch {
    if (!_viewSearch) {
        _viewSearch = [[UIView alloc] init];
        _viewSearch.backgroundColor = UICOLOR_FROM_RGB(0xEBEBEB, 1);
    }
    return _viewSearch;
}
- (UITextField *)textField {
    if (!_textField) {
        _textField = [[UITextField alloc] init];
        _textField.font = [UIFont systemFontOfSize:14];
        _textField.textAlignment = NSTextAlignmentLeft;
        _textField.textColor = [UIColor blackColor];
    }
    return _textField;
}
@end
BuWanVideo2.0/SearchRecordCell.h
New file
@@ -0,0 +1,19 @@
//
//  SearchRecordCell.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SearchRecordCell : UICollectionViewCell
@property (nonatomic, nullable, copy) NSString *name;
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/SearchRecordCell.m
New file
@@ -0,0 +1,48 @@
//
//  SearchRecordCell.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "SearchRecordCell.h"
@interface SearchRecordCell ()
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@end
@implementation SearchRecordCell
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self.contentView addSubview:self.labelTitle];
    self.labelTitle.sd_layout.leftSpaceToView(self.contentView, 0).topSpaceToView(self.contentView, 0).rightSpaceToView(self.contentView, 0).bottomSpaceToView(self.contentView, 0);
    self.labelTitle.sd_cornerRadius = @14.5;
}
- (void)setName:(NSString *)name {
    self.labelTitle.text = name;
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.textAlignment = NSTextAlignmentCenter;
        _labelTitle.textColor = [UIColor blackColor];
        _labelTitle.font = [UIFont systemFontOfSize:13];
        _labelTitle.backgroundColor = UICOLOR_FROM_RGB(0xF7F7F7, 1);
    }
    return _labelTitle;
}
@end
BuWanVideo2.0/SearchRecordHeaderView.h
New file
@@ -0,0 +1,17 @@
//
//  SearchRecordHeaderView.h
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SearchRecordHeaderView : UICollectionReusableView
@end
NS_ASSUME_NONNULL_END
BuWanVideo2.0/SearchRecordHeaderView.m
New file
@@ -0,0 +1,55 @@
//
//  SearchRecordHeaderView.m
//  BuWanVideo2.0
//
//  Created by Aeline on 2021/5/30.
//  Copyright Â© 2021 com.yeshi.buwansheque.ios. All rights reserved.
//
#import "SearchRecordHeaderView.h"
@interface SearchRecordHeaderView ()
@property (nonatomic, nullable, strong) UIButton *buttonDelete;
@property (nonatomic, nullable, strong) UILabel *labelTitle;
@end
@implementation SearchRecordHeaderView
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupViewConfig];
    }
    return self;
}
- (void)setupViewConfig {
    [self addSubview:self.labelTitle];
    [self addSubview:self.buttonDelete];
    self.labelTitle.sd_layout.leftSpaceToView(self, 12).topSpaceToView(self, 20).widthIs(100).heightIs(16);
    self.buttonDelete.sd_layout.rightSpaceToView(self, 10).centerYEqualToView(self.labelTitle).widthIs(30).heightIs(30);
}
- (UILabel *)labelTitle {
    if (!_labelTitle) {
        _labelTitle = [[UILabel alloc] init];
        _labelTitle.text = @"搜索记录";
        _labelTitle.textColor = UICOLOR_FROM_RGB(0x333333, 1);
        _labelTitle.font = [UIFont boldSystemFontOfSize:16];
        _labelTitle.textAlignment = NSTextAlignmentLeft;
    }
    return _labelTitle;
}
- (UIButton *)buttonDelete {
    if (!_buttonDelete) {
        _buttonDelete = [UIButton buttonWithType:UIButtonTypeCustom];
        [_buttonDelete setImage:[UIImage imageNamed:@"search_delete"] forState:UIControlStateNormal];
    }
    return _buttonDelete;
}
@end
BuWanVideo2.0/YTHNetInterface.h
@@ -120,7 +120,7 @@
/**
 *  æŽ¨èåˆ†ç±»
 */
- (void)getHomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system  withBlock:(YthNetWorkBlock)block;
- (void)getHomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system DataKey:(NSString *)DataKey PageSize:(NSUInteger)PageSize Page:(NSUInteger)Page withBlock:(YthNetWorkBlock)block;
/**
 *  ç‚¹å‡»ä¸Šä¼ å‘现页面的广告
@@ -578,4 +578,8 @@
- (void)fetchCommenConfig:(NSMutableDictionary *)dic WithBlock:(YthNetWorkBlock)block;
-(void)getVideoRecommendWithUid:(NSString *)vid Page:(NSUInteger)Page WithSystem:(NSString *)system withBlock:(YthNetWorkBlock)block;
/// çƒ­æœæ¦œ
- (void)fetchHotSerchListWithUid:(YthNetWorkBlock)block;
@end
BuWanVideo2.0/YTHNetInterface.m
@@ -168,6 +168,19 @@
}
- (void)postClaseeChangeRequestDataWith:(NSMutableDictionary *)dic withBlock:(YthNetWorkBlock)block{
    NSString *url = [NSString stringWithFormat:@"%@/recommend",domainHTTP];
    [self mangerPostWithURL:url WithMutableDictionary:dic withBlock:block];
}
- (void)postHotSerchRequestDataWith:(NSMutableDictionary *)dic withBlock:(YthNetWorkBlock)block{
    NSString *url = [NSString stringWithFormat:@"%@/user",domainHTTP];
    [self mangerPostWithURL:url WithMutableDictionary:dic withBlock:block];
}
#pragma mark AFNetwork PSOT User ç”¨æˆ·ç›¸å…³
- (void)postUserRequestDataWith:(NSMutableDictionary *)dic withBlock:(YthNetWorkBlock)block{
    
@@ -485,8 +498,8 @@
    }];
}
#pragma mark æŽ¨èåˆ†ç±»
- (void)getHomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system  withBlock:(YthNetWorkBlock)block{
    NSMutableDictionary *dic = [YTHNetdata HomeTypeWithUid:uid vtid:vtid withSystem:system ];
- (void)getHomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system DataKey:(NSString *)DataKey PageSize:(NSUInteger)PageSize Page:(NSUInteger)Page withBlock:(YthNetWorkBlock)block {
    NSMutableDictionary *dic = [YTHNetdata HomeTypeWithUid:uid vtid:vtid withSystem:system DataKey:DataKey PageSize:PageSize Page:Page];
    
    [self postRecommendRequestDataWith:dic withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
@@ -501,7 +514,39 @@
    }];
}
- (void)getVideoRecommendWithUid:(NSString *)vid Page:(NSUInteger)Page WithSystem:(NSString *)system withBlock:(YthNetWorkBlock)block {
    NSMutableDictionary *dic = [YTHNetdata videoClassChangeWithUid:[YTHsharedManger startManger].Uid vtid:vid withSystem:@"1" Page:Page];
    [self postClaseeChangeRequestDataWith:dic withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            NSDictionary *data = (NSDictionary *)result;
            block(TRUE , data , nil);
        }else{
            block(FALSE , nil , error);
        }
    }];
}
- (void)fetchHotSerchListWithUid:(YthNetWorkBlock)block {
    NSMutableDictionary *dic = [YTHNetdata hotSearch:[YTHsharedManger startManger].Uid withSystem:@"1"];
    [self postHotSerchRequestDataWith:dic withBlock:^(BOOL isSuccessful, id result, NSString *error) {
        if (isSuccessful) {
            NSDictionary *data = (NSDictionary *)result;
            block(TRUE , data , nil);
        }else{
            block(FALSE , nil , error);
        }
    }];
}
#pragma mark æ›´å¤šè§†é¢‘
- (void)getMoreVideoWithUid:(NSString *)uid withType:(NSString *)type withSystem:(NSString *)system withPage:(NSString *)page withBlock:(YthNetWorkBlock)block{
BuWanVideo2.0/YTHNetdata.h
@@ -101,7 +101,8 @@
/**
 *  æŽ¨èåˆ†ç±»
 */
+ (NSMutableDictionary *)HomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system;
+ (NSMutableDictionary *)HomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system DataKey:(NSString *)DataKey PageSize:(NSUInteger)PageSize Page:(NSUInteger)Page;
//首页底部明星
+(NSMutableDictionary *)getHotStarMainList:(NSString *)uid  WithSystem:(NSString *)system;
@@ -614,4 +615,8 @@
//首页精选
+ (NSMutableDictionary *)videoClassWithUid:(NSString *)uid withSystem:(NSString *)system;
+ (NSMutableDictionary *)videoClassChangeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system Page:(NSUInteger)Page ;
+ (NSMutableDictionary *)hotSearch:(NSString *)uid withSystem:(NSString *)system;
@end
BuWanVideo2.0/YTHNetdata.m
@@ -381,8 +381,12 @@
}
#pragma mark æŽ¨èåˆ†ç±»
+ (NSMutableDictionary *)HomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system{
+ (NSMutableDictionary *)HomeTypeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system DataKey:(NSString *)DataKey PageSize:(NSUInteger)PageSize Page:(NSUInteger)Page {
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithCapacity:0];
    dic[@"DataKey"] = DataKey;
    dic[@"PageSize"] = @(PageSize);
    dic[@"Page"] = @(Page);
    
    [dic setObject:GetHomeType forKey:@"Method"];
    [dic setObject:@"ios" forKey:@"Platform"];
@@ -403,6 +407,51 @@
    return dic;
}
+ (NSMutableDictionary *)videoClassChangeWithUid:(NSString *)uid vtid:(NSString *)vtid withSystem:(NSString *)system Page:(NSUInteger)Page
{
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithCapacity:0];
    dic[@"Page"] = @(Page);
    dic[@"Id"] = vtid;
    [dic setObject:@"getHomeVideoList" forKey:@"Method"];
    [dic setObject:@"ios" forKey:@"Platform"];
    [dic setObject:Version forKey:@"Version"];
    [dic setObject:Package forKey:@"Package"];
    [dic setObject:system forKey:@"System"];
    NSString *sign;
    if (uid!=nil) {
        [dic setObject:uid forKey:@"Uid"];
        sign = [NSString stringWithFormat:@"%@%@%@",@"getHomeVideoList",uid,system];
    }else{
        sign = [NSString stringWithFormat:@"%@%@%@",@"getHomeVideoList",[[UIDevice currentDevice].identifierForVendor UUIDString],system];
    }
    [dic setObject:[NSString md5:sign] forKey:@"Sign"];
    [dic setObject:[[UIDevice currentDevice].identifierForVendor UUIDString] forKey:@"Device"];
    NSLog(@"%@",dic);
    return dic;
}
+ (NSMutableDictionary *)hotSearch:(NSString *)uid withSystem:(NSString *)system {
    NSMutableDictionary *parms = [[NSMutableDictionary alloc] initWithCapacity:0];
    [parms setObject:@"getSearchRank" forKey:@"Method"];
    [parms setObject:@"ios" forKey:@"Platform"];
    [parms setObject:Version forKey:@"Version"];
    [parms setObject:Package forKey:@"Package"];
    [parms setObject:system forKey:@"System"];
    NSString *sign;
    if (uid!=nil) {
        [parms setObject:uid forKey:@"Uid"];
        sign = [NSString stringWithFormat:@"%@%@%@",@"getSearchRank",uid,system];
    }else{
        sign = [NSString stringWithFormat:@"%@%@%@",@"getSearchRank",[[UIDevice currentDevice].identifierForVendor UUIDString],system];
    }
    [parms setObject:[NSString md5:sign] forKey:@"Sign"];
    [parms setObject:[[UIDevice currentDevice].identifierForVendor UUIDString] forKey:@"Device"];
    return parms;
}
#pragma mark æ›´å¤šè§†é¢‘
+ (NSMutableDictionary *)MoreVideoWithUid:(NSString *)uid withType:(NSString *)type withSystem:(NSString *)system withPage:(NSString *)page{
@@ -660,14 +709,14 @@
+ (NSMutableDictionary *)videoClassWithUid:(NSString *)uid withSystem:(NSString *)system{
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithCapacity:0];
    
    [dic setObject:@"getVideoClass" forKey:@"Method"];
    [dic setObject:@"getHomeClass" forKey:@"Method"];
    [dic setObject:@"ios" forKey:@"Platform"];
    NSString *sign;
    if (uid!=nil) {
        [dic setObject:uid forKey:@"Uid"];
        sign = [NSString stringWithFormat:@"%@%@%@",@"getVideoClass",uid,system];
        sign = [NSString stringWithFormat:@"%@%@%@",@"getHomeClass",uid,system];
    }else{
        sign = [NSString stringWithFormat:@"%@%@%@",@"getVideoClass",[[UIDevice currentDevice].identifierForVendor UUIDString],system];
        sign = [NSString stringWithFormat:@"%@%@%@",@"getHomeClass",[[UIDevice currentDevice].identifierForVendor UUIDString],system];
    }
    [dic setObject:Version forKey:@"Version"];
    [dic setObject:Package forKey:@"Package"];
BuWanVideo2.0/YTHsharedManger.h
@@ -13,19 +13,19 @@
/**
 *  æ•´ä¸ªç¨‹åºçš„Uid
 */
@property (nonatomic , strong) NSString *Uid;
@property (nonatomic , nullable, strong) NSString *Uid;
/**
 *  ç½‘络状态 1:不可用    2:2g或3g   3:wifi环境
 */
@property (nonatomic , assign) NSInteger NetworkStatus;
@property (nonatomic , strong) NSString *searchTitle;
@property (nonatomic , nullable, copy) NSString *searchTitle;
@property (nonatomic , strong) UIViewController *preController;
@property (nonatomic , nullable, strong) UIViewController *preController;
/// é¦–页广告位配置
@property (nonatomic , strong) NSDictionary *ad;
@property (nonatomic , nullable, strong) NSDictionary *ad;
+ (YTHsharedManger *)startManger;
+ (YTHsharedManger *_Nonnull)startManger;
@end
BuWanVideo2.0/ZJScrollPageView/UIView+ZJFrame.h
New file
@@ -0,0 +1,21 @@
//
//  UIView+Frame.h
//  BuDeJie
//
//  Created by yz on 15/10/29.
//  Copyright Â© 2015å¹´ yz. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (ZJFrame)
@property (nonatomic, assign) CGFloat zj_centerX;
@property (nonatomic, assign) CGFloat zj_centerY;
@property (nonatomic, assign) CGFloat zj_x;
@property (nonatomic, assign) CGFloat zj_y;
@property (nonatomic, assign) CGFloat zj_width;
@property (nonatomic, assign) CGFloat zj_height;
@end
BuWanVideo2.0/ZJScrollPageView/UIView+ZJFrame.m
New file
@@ -0,0 +1,82 @@
//
//  UIView+Frame.m
//  BuDeJie
//
//  Created by yz on 15/10/29.
//  Copyright Â© 2015å¹´ yz. All rights reserved.
//
#import "UIView+ZJFrame.h"
@implementation UIView (ZJFrame)
- (CGFloat)zj_height
{
    return self.frame.size.height;
}
- (CGFloat)zj_width
{
    return self.frame.size.width;
}
- (void)setZj_height:(CGFloat)zj_height {
    CGRect frame = self.frame;
    frame.size.height = zj_height;
    self.frame = frame;
}
- (void)setZj_width:(CGFloat)zj_width {
    CGRect frame = self.frame;
    frame.size.width = zj_width;
    self.frame = frame;
}
- (CGFloat)zj_x
{
    return self.frame.origin.x;
}
- (void)setZj_x:(CGFloat)zj_x {
    CGRect frame = self.frame;
    frame.origin.x = zj_x;
    self.frame = frame;
}
- (CGFloat)zj_y
{
    return self.frame.origin.y;
}
- (void)setZj_y:(CGFloat)zj_y {
    CGRect frame = self.frame;
    frame.origin.y = zj_y;
    self.frame = frame;
}
- (void)setZj_centerX:(CGFloat)zj_centerX {
    CGPoint center = self.center;
    center.x = zj_centerX;
    self.center = center;
}
- (CGFloat)zj_centerX
{
    return self.center.x;
}
- (void)setZj_centerY:(CGFloat)zj_centerY {
    CGPoint center = self.center;
    center.y = zj_centerY;
    self.center = center;
}
- (CGFloat)zj_centerY
{
    return self.center.y;
}
@end
BuWanVideo2.0/ZJScrollPageView/UIViewController+ZJScrollPageController.h
New file
@@ -0,0 +1,22 @@
//
//  UIViewController+UIViewController_ZJScrollPageController.h
//  ZJScrollPageView
//
//  Created by jasnig on 16/6/7.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIViewController (ZJScrollPageController)
/**
 *  æ‰€æœ‰å­æŽ§åˆ¶çš„父控制器, æ–¹ä¾¿åœ¨æ¯ä¸ªå­æŽ§åˆ¶é¡µé¢ç›´æŽ¥èŽ·å–åˆ°çˆ¶æŽ§åˆ¶å™¨è¿›è¡Œå…¶ä»–æ“ä½œ
 */
@property (nonatomic, weak, readonly) UIViewController *zj_scrollViewController;
@property (nonatomic, assign) NSInteger zj_currentIndex;
@end
BuWanVideo2.0/ZJScrollPageView/UIViewController+ZJScrollPageController.m
New file
@@ -0,0 +1,37 @@
//
//  UIViewController+UIViewController_ZJScrollPageController.m
//  ZJScrollPageView
//
//  Created by jasnig on 16/6/7.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import "UIViewController+ZJScrollPageController.h"
#import "ZJScrollPageViewDelegate.h"
#import <objc/runtime.h>
char ZJIndexKey;
@implementation UIViewController (ZJScrollPageController)
//@dynamic zj_scrollViewController;
- (UIViewController *)zj_scrollViewController {
    UIViewController *controller = self;
    while (controller) {
        if ([controller conformsToProtocol:@protocol(ZJScrollPageViewDelegate)]) {
            break;
        }
        controller = controller.parentViewController;
    }
    return controller;
}
- (void)setZj_currentIndex:(NSInteger)zj_currentIndex {
    objc_setAssociatedObject(self, &ZJIndexKey, [NSNumber numberWithInteger:zj_currentIndex], OBJC_ASSOCIATION_ASSIGN);
}
- (NSInteger)zj_currentIndex {
    return [objc_getAssociatedObject(self, &ZJIndexKey) integerValue];
}
@end
BuWanVideo2.0/ZJScrollPageView/ZJCollectionView.h
New file
@@ -0,0 +1,17 @@
//
//  ZJScrollView.h
//  ZJScrollPageView
//
//  Created by ZeroJ on 16/10/24.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ZJCollectionView : UICollectionView
typedef BOOL(^ZJScrollViewShouldBeginPanGestureHandler)(ZJCollectionView *collectionView, UIPanGestureRecognizer *panGesture);
- (void)setupScrollViewShouldBeginPanGestureHandler:(ZJScrollViewShouldBeginPanGestureHandler)gestureBeginHandler;
@end
BuWanVideo2.0/ZJScrollPageView/ZJCollectionView.m
New file
@@ -0,0 +1,31 @@
//
//  ZJScrollView.m
//  ZJScrollPageView
//
//  Created by ZeroJ on 16/10/24.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import "ZJCollectionView.h"
@interface ZJCollectionView ()
@property (copy, nonatomic) ZJScrollViewShouldBeginPanGestureHandler gestureBeginHandler;
@end
@implementation ZJCollectionView
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (_gestureBeginHandler && gestureRecognizer == self.panGestureRecognizer) {
        return _gestureBeginHandler(self, (UIPanGestureRecognizer *)gestureRecognizer);
    }
    else {
        return [super gestureRecognizerShouldBegin:gestureRecognizer];
    }
}
- (void)setupScrollViewShouldBeginPanGestureHandler:(ZJScrollViewShouldBeginPanGestureHandler)gestureBeginHandler {
    _gestureBeginHandler = [gestureBeginHandler copy];
}
@end
BuWanVideo2.0/ZJScrollPageView/ZJContentView.h
New file
@@ -0,0 +1,36 @@
//
//  ZJContentView.h
//  ZJScrollPageView
//
//  Created by jasnig on 16/5/6.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ZJScrollPageViewDelegate.h"
#import "ZJCollectionView.h"
#import "ZJScrollSegmentView.h"
#import "UIViewController+ZJScrollPageController.h"
@interface ZJContentView : UIView
/** å¿…须设置代理和实现相关的方法*/
@property(weak, nonatomic)id<ZJScrollPageViewDelegate> delegate;
@property (strong, nonatomic, readonly) ZJCollectionView *collectionView;
// å½“前控制器
@property (strong, nonatomic, readonly) UIViewController<ZJScrollPageViewChildVcDelegate> *currentChildVc;
/**初始化方法
 *
 */
- (instancetype)initWithFrame:(CGRect)frame segmentView:(ZJScrollSegmentView *)segmentView parentViewController:(UIViewController *)parentViewController delegate:(id<ZJScrollPageViewDelegate>) delegate;
/** ç»™å¤–界可以设置ContentOffSet的方法 */
- (void)setContentOffSet:(CGPoint)offset animated:(BOOL)animated;
/** ç»™å¤–界 é‡æ–°åŠ è½½å†…å®¹çš„æ–¹æ³• */
- (void)reload;
@end
BuWanVideo2.0/ZJScrollPageView/ZJContentView.m
New file
@@ -0,0 +1,574 @@
//
//  ZJContentView.m
//  ZJScrollPageView
//
//  Created by jasnig on 16/5/6.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import "ZJContentView.h"
@interface ZJContentView ()<UIScrollViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource> {
    CGFloat   _oldOffSetX;
    BOOL _isLoadFirstView;
    NSInteger _sysVersion;
}
@property (weak, nonatomic) ZJScrollSegmentView *segmentView;
// ç”¨äºŽå¤„理重用和内容的显示
@property (strong, nonatomic) ZJCollectionView *collectionView;
// collectionView的布局
@property (strong, nonatomic) UICollectionViewFlowLayout *collectionViewLayout;
// çˆ¶ç±» ç”¨äºŽå¤„理添加子控制器  ä½¿ç”¨weak避免循环引用
@property (weak, nonatomic) UIViewController *parentViewController;
// å½“这个属性设置为YES的时候 å°±ä¸ç”¨å¤„理 scrollView滚动的计算
@property (assign, nonatomic) BOOL forbidTouchToAdjustPosition;
@property (assign, nonatomic) NSInteger itemsCount;
// æ‰€æœ‰çš„子控制器
@property (strong, nonatomic) NSMutableDictionary<NSString *, UIViewController<ZJScrollPageViewChildVcDelegate> *> *childVcsDic;
// å½“前控制器
@property (strong, nonatomic) UIViewController<ZJScrollPageViewChildVcDelegate> *currentChildVc;
/// å¦‚果类似cell缓存一样, è™½ç„¶åˆ›å»ºçš„æŽ§åˆ¶å™¨å°‘了, ä½†æ˜¯æ¯ä¸ªé¡µé¢æ¯æ¬¡éƒ½è¦é‡æ–°åŠ è½½æ•°æ®, å¦åˆ™æ˜¾ç¤ºçš„内容就会出错, è²Œä¼¼è¿˜ä¸å¦‚每个页面创建一个控制器好
//@property (strong, nonatomic) NSCache *cacheChildVcs;
@property (assign, nonatomic) NSInteger currentIndex;
@property (assign, nonatomic) NSInteger oldIndex;
// æ˜¯å¦éœ€è¦æ‰‹åŠ¨ç®¡ç†ç”Ÿå‘½å‘¨æœŸæ–¹æ³•çš„è°ƒç”¨
@property (assign, nonatomic) BOOL needManageLifeCycle;
// æ»šåŠ¨è¶…è¿‡é¡µé¢(直接设置contentOffSet导致)
@property (assign, nonatomic) BOOL scrollOverOnePage;
@end
@implementation ZJContentView
#define cellID @"cellID"
#pragma mark - life cycle
- (instancetype)initWithFrame:(CGRect)frame segmentView:(ZJScrollSegmentView *)segmentView parentViewController:(UIViewController *)parentViewController delegate:(id<ZJScrollPageViewDelegate>) delegate {
    if (self = [super initWithFrame:frame]) {
        self.segmentView = segmentView;
        self.delegate = delegate;
        self.parentViewController = parentViewController;
        _needManageLifeCycle = ![parentViewController shouldAutomaticallyForwardAppearanceMethods];
        if (!_needManageLifeCycle) {
#if DEBUG
            NSLog(@"\n请注意: å¦‚果你希望所有的子控制器的view的系统生命周期方法被正确的调用\n请重写%@的'shouldAutomaticallyForwardAppearanceMethods'方法 å¹¶ä¸”返回NO\n当然如果你不做这个操作, å­æŽ§åˆ¶å™¨çš„生命周期方法将不会被正确的调用\n如果你仍然想利用子控制器的生命周期方法, è¯·ä½¿ç”¨'ZJScrollPageViewChildVcDelegate'提供的代理方法\n或者'ZJScrollPageViewDelegate'提供的代理方法", [parentViewController class]);
#endif
        }
        [self commonInit];
        [self addSubview:self.collectionView];
        [self addNotification];
    }
    return self;
}
- (void)commonInit {
    _oldIndex = -1;
    _currentIndex = 0;
    _oldOffSetX = 0.0f;
    _forbidTouchToAdjustPosition = NO;
    _isLoadFirstView = YES;
    _sysVersion = [[[UIDevice currentDevice] systemVersion] integerValue];
    if ([_delegate respondsToSelector:@selector(numberOfChildViewControllers)]) {
        self.itemsCount = [_delegate numberOfChildViewControllers];
    }
    else {
        NSAssert(NO, @"必须实现的代理方法");
    }
    UINavigationController *navi = (UINavigationController *)self.parentViewController.parentViewController;
    if ([navi isKindOfClass:[UINavigationController class]]) {
        if (navi.viewControllers.count == 1) return;
        if (navi.interactivePopGestureRecognizer) {
            __weak typeof(self) weakSelf = self;
            [_collectionView setupScrollViewShouldBeginPanGestureHandler:^BOOL(ZJCollectionView *collectionView, UIPanGestureRecognizer *panGesture) {
                CGFloat transionX = [panGesture translationInView:panGesture.view].x;
                if (collectionView.contentOffset.x == 0 && transionX > 0) {
                    navi.interactivePopGestureRecognizer.enabled = YES;
                }
                else {
                    navi.interactivePopGestureRecognizer.enabled = NO;
                }
                if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(scrollPageController:contentScrollView:shouldBeginPanGesture:)]) {
                    return [weakSelf.delegate scrollPageController:weakSelf.parentViewController contentScrollView:collectionView shouldBeginPanGesture:panGesture];
                }
                else return YES;
            }];
        }
    }
}
- (void)addNotification {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMemoryWarningHander:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
}
- (void)receiveMemoryWarningHander:(NSNotificationCenter *)noti {
    __weak typeof(self) weakSelf = self;
    [_childVcsDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, UIViewController<ZJScrollPageViewChildVcDelegate> * _Nonnull childVc, BOOL * _Nonnull stop) {
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf) {
            if (childVc != strongSelf.currentChildVc) {
                [_childVcsDic removeObjectForKey:key];
                [ZJContentView removeChildVc:childVc];
            }
        }
    }];
}
- (void)layoutSubviews {
    [super layoutSubviews];
    if (self.currentChildVc) {
        self.currentChildVc.view.frame = self.bounds;
    }
}
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
#if DEBUG
    NSLog(@"ZJContentView---销毁");
#endif
}
// å¤„理当前子控制器的生命周期 : å·²çŸ¥é—®é¢˜, å½“push的时候会被调用两次
- (void)willMoveToWindow:(nullable UIWindow *)newWindow {
    [super willMoveToWindow:newWindow];
    if (newWindow == nil) {
        [self willDisappearWithIndex:_currentIndex];
    }
    else {
        [self willAppearWithIndex:_currentIndex];
    }
}
- (void)didMoveToWindow {
    [super didMoveToWindow];
    if (self.window == nil) {
        [self didDisappearWithIndex:_currentIndex];
    }
    else {
        [self didAppearWithIndex:_currentIndex];
    }
}
#pragma mark - public helper
/** ç»™å¤–界可以设置ContentOffSet的方法 */
- (void)setContentOffSet:(CGPoint)offset animated:(BOOL)animated {
    self.forbidTouchToAdjustPosition = YES;
    NSInteger currentIndex = offset.x/self.collectionView.bounds.size.width;
    _oldIndex = _currentIndex;
    self.currentIndex = currentIndex;
    _scrollOverOnePage = NO;
    NSInteger page = labs(_currentIndex-_oldIndex);
    if (page>=2) {// éœ€è¦æ»šåŠ¨ä¸¤é¡µä»¥ä¸Šçš„æ—¶å€™, è·³è¿‡ä¸­é—´é¡µçš„动画
        _scrollOverOnePage = YES;
    }
    [self.collectionView setContentOffset:offset animated:animated];
}
/** ç»™å¤–界刷新视图的方法 */
- (void)reload {
    [self.childVcsDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, UIViewController<ZJScrollPageViewChildVcDelegate> * _Nonnull childVc, BOOL * _Nonnull stop) {
        [ZJContentView removeChildVc:childVc];
        childVc = nil;
    }];
    self.childVcsDic = nil;
    [self commonInit];
    [self.collectionView reloadData];
    [self setContentOffSet:CGPointZero animated:NO];
}
+ (void)removeChildVc:(UIViewController *)childVc {
    [childVc willMoveToParentViewController:nil];
    [childVc.view removeFromSuperview];
    [childVc removeFromParentViewController];
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (self.forbidTouchToAdjustPosition || // ç‚¹å‡»æ ‡é¢˜æ»šåЍ
        scrollView.contentOffset.x <= 0 || // first or last
        scrollView.contentOffset.x >= scrollView.contentSize.width - scrollView.bounds.size.width) {
        return;
    }
    CGFloat tempProgress = scrollView.contentOffset.x / self.bounds.size.width;
    NSInteger tempIndex = tempProgress;
    CGFloat progress = tempProgress - floor(tempProgress);
    CGFloat deltaX = scrollView.contentOffset.x - _oldOffSetX;
    if (deltaX > 0) {// å‘å·¦
        if (progress == 0.0) {
            return;
        }
        self.currentIndex = tempIndex+1;
        self.oldIndex = tempIndex;
    }
    else if (deltaX < 0) {
        progress = 1.0 - progress;
        self.oldIndex = tempIndex+1;
        self.currentIndex = tempIndex;
    }
    else {
         return;
    }
//    NSLog(@"old ---- %ld current --- %ld", _oldIndex, _currentIndex);
    [self contentViewDidMoveFromIndex:_oldIndex toIndex:_currentIndex progress:progress];
}
/** æ»šåŠ¨å‡é€Ÿå®Œæˆæ—¶å†æ›´æ–°title的位置 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    NSInteger currentIndex = (scrollView.contentOffset.x / self.bounds.size.width);
    [self contentViewDidMoveFromIndex:currentIndex toIndex:currentIndex progress:1.0];
    // è°ƒæ•´title
    [self adjustSegmentTitleOffsetToCurrentIndex:currentIndex];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    _oldOffSetX = scrollView.contentOffset.x;
    self.forbidTouchToAdjustPosition = NO;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    UINavigationController *navi = (UINavigationController *)self.parentViewController.parentViewController;
    if ([navi isKindOfClass:[UINavigationController class]] && navi.interactivePopGestureRecognizer) {
        navi.interactivePopGestureRecognizer.enabled = YES;
    }
}
#pragma mark - private helper
- (void)contentViewDidMoveFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress {
    if(self.segmentView) {
        [self.segmentView adjustUIWithProgress:progress oldIndex:fromIndex currentIndex:toIndex];
    }
}
- (void)adjustSegmentTitleOffsetToCurrentIndex:(NSInteger)index {
    if(self.segmentView) {
        [self.segmentView adjustTitleOffSetToCurrentIndex:index];
    }
}
- (void)willAppearWithIndex:(NSInteger)index {
    UIViewController<ZJScrollPageViewChildVcDelegate> *controller = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", index]];
    if (controller) {
        if ([controller respondsToSelector:@selector(zj_viewWillAppearForIndex:)]) {
            [controller zj_viewWillAppearForIndex:index];
        }
        if (_needManageLifeCycle) {
            [controller beginAppearanceTransition:YES animated:NO];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllWillAppear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllWillAppear:controller forIndex:index];
        }
    }
}
- (void)didAppearWithIndex:(NSInteger)index {
    UIViewController<ZJScrollPageViewChildVcDelegate> *controller = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", index]];
    if (controller) {
        if ([controller respondsToSelector:@selector(zj_viewDidAppearForIndex:)]) {
            [controller zj_viewDidAppearForIndex:index];
        }
        if (_needManageLifeCycle) {
            [controller endAppearanceTransition];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllDidAppear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllDidAppear:controller forIndex:index];
        }
    }
}
- (void)willDisappearWithIndex:(NSInteger)index {
    UIViewController<ZJScrollPageViewChildVcDelegate> *controller = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", index]];
    if (controller) {
        if ([controller respondsToSelector:@selector(zj_viewWillDisappearForIndex:)]) {
            [controller zj_viewWillDisappearForIndex:index];
        }
        if (_needManageLifeCycle) {
            [controller beginAppearanceTransition:NO animated:NO];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllWillDisappear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllWillDisappear:controller forIndex:index];
        }
    }
}
- (void)didDisappearWithIndex:(NSInteger)index {
    UIViewController<ZJScrollPageViewChildVcDelegate> *controller = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", index]];
    if (controller) {
        if ([controller respondsToSelector:@selector(zj_viewDidDisappearForIndex:)]) {
            [controller zj_viewDidDisappearForIndex:index];
        }
        if (_needManageLifeCycle) {
            [controller endAppearanceTransition];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllDidDisappear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllDidDisappear:controller forIndex:index];
        }
    }
}
#pragma mark - UICollectionViewDelegate --- UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return _itemsCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
    // ç§»é™¤subviews é¿å…é‡ç”¨å†…容显示错误
    [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    if (_sysVersion < 8) {
        [self setupChildVcForCell:cell atIndexPath:indexPath];
    }
    return cell;
}
- (void)setupChildVcForCell:(UICollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    if (_currentIndex != indexPath.row) {
        return; // è·³è¿‡ä¸­é—´çš„多页
    }
    _currentChildVc = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", (long)indexPath.row]];
    BOOL isFirstLoaded = _currentChildVc == nil;
    if (_delegate && [_delegate respondsToSelector:@selector(childViewController:forIndex:)]) {
        if (_currentChildVc == nil) {
            _currentChildVc = [_delegate childViewController:nil forIndex:indexPath.row];
            if (!_currentChildVc || ![_currentChildVc conformsToProtocol:@protocol(ZJScrollPageViewChildVcDelegate)]) {
                NSAssert(NO, @"子控制器必须遵守ZJScrollPageViewChildVcDelegate协议");
            }
            // è®¾ç½®å½“前下标
            _currentChildVc.zj_currentIndex = indexPath.row;
            [self.childVcsDic setValue:_currentChildVc forKey:[NSString stringWithFormat:@"%ld", (long)indexPath.row]];
        } else {
            [_delegate childViewController:_currentChildVc forIndex:indexPath.row];
        }
    } else {
        NSAssert(NO, @"必须设置代理和实现代理方法");
    }
    // è¿™é‡Œå»ºç«‹å­æŽ§åˆ¶å™¨å’Œçˆ¶æŽ§åˆ¶å™¨çš„关系
    if ([_currentChildVc isKindOfClass:[UINavigationController class]]) {
        NSAssert(NO, @"不要添加UINavigationController包装后的子控制器");
    }
    if (_currentChildVc.zj_scrollViewController != self.parentViewController) {
        [self.parentViewController addChildViewController:_currentChildVc];
    }
    _currentChildVc.view.frame = cell.contentView.bounds;
    [cell.contentView addSubview:_currentChildVc.view];
    [_currentChildVc didMoveToParentViewController:self.parentViewController];
    //    NSLog(@"当前的index:%ld", indexPath.row);
    if (_isLoadFirstView) { // ç¬¬ä¸€æ¬¡åŠ è½½cell? ä¸ä¼šè°ƒç”¨endDisplayCell
        [self willAppearWithIndex:indexPath.row];
        if (isFirstLoaded) {
            // viewDidLoad
            if ([_currentChildVc respondsToSelector:@selector(zj_viewDidLoadForIndex:)]) {
                [_currentChildVc zj_viewDidLoadForIndex:indexPath.row];
            }
        }
        [self didAppearWithIndex:indexPath.row];
        _isLoadFirstView = NO;
    }
    else {
        [self willAppearWithIndex:indexPath.row];
        if (isFirstLoaded) {
            // viewDidLoad
            if ([_currentChildVc respondsToSelector:@selector(zj_viewDidLoadForIndex:)]) {
                [_currentChildVc zj_viewDidLoadForIndex:indexPath.row];
            }
        }
        [self willDisappearWithIndex:_oldIndex];
    }
}
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
//    NSLog(@"出现出现:current:---- %ld   old ----- %ld indexpathRow----%ld ", _currentIndex, _oldIndex, indexPath.row);
    if (_sysVersion >= 8) {
        [self setupChildVcForCell:cell atIndexPath:indexPath];
    }
}
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
//    NSLog(@"消失消失:current:---- %ld   old ----- %ld indexpathRow----%ld ", _currentIndex, _oldIndex, indexPath.row);
    if (!self.forbidTouchToAdjustPosition) {
        if (_currentIndex == indexPath.row) {// æ²¡æœ‰æ»šåŠ¨å®Œæˆ
            if (_needManageLifeCycle) {
                UIViewController<ZJScrollPageViewChildVcDelegate> *currentVc = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", _oldIndex]];
                // å¼€å§‹å‡ºçް
                [currentVc beginAppearanceTransition:YES animated:NO];
                UIViewController<ZJScrollPageViewChildVcDelegate> *oldVc = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", indexPath.row]];
                // å¼€å§‹æ¶ˆå¤±
                [oldVc beginAppearanceTransition:NO animated:NO];
            }
            [self didAppearWithIndex:_oldIndex];
            [self didDisappearWithIndex:indexPath.row];
        }
        else {
            if (_oldIndex == indexPath.row) {
                // æ»šåŠ¨å®Œæˆ
                [self didAppearWithIndex:_currentIndex];
                [self didDisappearWithIndex:indexPath.row];
            }
            else {
                // æ»šåŠ¨æ²¡æœ‰å®Œæˆåˆå¿«é€Ÿçš„åå‘æ‰“å¼€äº†å¦ä¸€é¡µ
                if (_needManageLifeCycle) {
                    UIViewController<ZJScrollPageViewChildVcDelegate> *currentVc = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", _oldIndex]];
                    // å¼€å§‹å‡ºçް
                    [currentVc beginAppearanceTransition:YES animated:NO];
                    UIViewController<ZJScrollPageViewChildVcDelegate> *oldVc = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%ld", indexPath.row]];
                    // å¼€å§‹æ¶ˆå¤±
                    [oldVc beginAppearanceTransition:NO animated:NO];
                    // æ¶ˆå¤±
                }
                [self didAppearWithIndex:_oldIndex];
                [self didDisappearWithIndex:indexPath.row];
            }
        }
    }
    else {
        if (_scrollOverOnePage) {
            if (labs(_currentIndex-indexPath.row) == 1) { //滚动完成
                [self didAppearWithIndex:_currentIndex];
                [self didDisappearWithIndex:_oldIndex];
            }
        }
        else {
            [self didDisappearWithIndex:_oldIndex];
            [self didAppearWithIndex:_currentIndex];
        }
    }
}
#pragma mark - getter --- setter
- (void)setCurrentIndex:(NSInteger)currentIndex {
    if (_currentIndex != currentIndex) {
        _currentIndex = currentIndex;
        if (self.segmentView.segmentStyle.isAdjustTitleWhenBeginDrag) {
            [self adjustSegmentTitleOffsetToCurrentIndex:currentIndex];
        }
    }
}
- (ZJCollectionView *)collectionView {
    if (_collectionView == nil) {
        ZJCollectionView *collectionView = [[ZJCollectionView alloc] initWithFrame:self.bounds collectionViewLayout:self.collectionViewLayout];
        [collectionView setBackgroundColor:[UIColor whiteColor]];
        collectionView.pagingEnabled = YES;
        collectionView.scrollsToTop = NO;
        collectionView.showsHorizontalScrollIndicator = NO;
        collectionView.delegate = self;
        collectionView.dataSource = self;
        collectionView.bounces = YES;
        [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellID];
        collectionView.bounces = self.segmentView.segmentStyle.isContentViewBounces;
        collectionView.scrollEnabled = self.segmentView.segmentStyle.isScrollContentView;
        [self addSubview:collectionView];
        _collectionView = collectionView;
    }
    return _collectionView;
}
- (UICollectionViewFlowLayout *)collectionViewLayout {
    if (_collectionViewLayout == nil) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        layout.itemSize = self.bounds.size;
        layout.minimumLineSpacing = 0.0;
        layout.minimumInteritemSpacing = 0.0;
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        _collectionViewLayout = layout;
    }
    return _collectionViewLayout;
}
- (NSMutableDictionary<NSString *,UIViewController<ZJScrollPageViewChildVcDelegate> *> *)childVcsDic {
    if (!_childVcsDic) {
        NSMutableDictionary *dic = [NSMutableDictionary dictionary];
        _childVcsDic = dic;
    }
    return _childVcsDic;
}
@end
BuWanVideo2.0/ZJScrollPageView/ZJScrollPageView.h
New file
@@ -0,0 +1,33 @@
//
//  ZJScrollPageView.h
//  ZJScrollPageView
//
//  Created by jasnig on 16/5/6.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "UIView+ZJFrame.h"
#import "ZJContentView.h"
#import "ZJTitleView.h"
@interface ZJScrollPageView : UIView
typedef void(^ExtraBtnOnClick)(UIButton *extraBtn);
@property (copy, nonatomic) ExtraBtnOnClick extraBtnOnClick;
@property (weak, nonatomic, readonly) ZJContentView *contentView;
@property (weak, nonatomic, readonly) ZJScrollSegmentView *segmentView;
/** å¿…须设置代理并且实现相应的方法*/
@property(weak, nonatomic)id<ZJScrollPageViewDelegate> delegate;
- (instancetype)initWithFrame:(CGRect)frame segmentStyle:(ZJSegmentStyle *)segmentStyle titles:(NSArray<NSString *> *)titles parentViewController:(UIViewController *)parentViewController delegate:(id<ZJScrollPageViewDelegate>) delegate ;
/** ç»™å¤–界设置选中的下标的方法 */
- (void)setSelectedIndex:(NSInteger)selectedIndex animated:(BOOL)animated;
/**  ç»™å¤–界重新设置的标题的方法(同时会重新加载页面的内容) */
- (void)reloadWithNewTitles:(NSArray<NSString *> *)newTitles;
@end
BuWanVideo2.0/ZJScrollPageView/ZJScrollPageView.m
New file
@@ -0,0 +1,113 @@
//
//  ZJScrollPageView.m
//  ZJScrollPageView
//
//  Created by jasnig on 16/5/6.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import "ZJScrollPageView.h"
@interface ZJScrollPageView ()
@property (strong, nonatomic) ZJSegmentStyle *segmentStyle;
@property (weak, nonatomic) ZJScrollSegmentView *segmentView;
@property (weak, nonatomic) ZJContentView *contentView;
@property (weak, nonatomic) UIViewController *parentViewController;
@property (strong, nonatomic) NSArray *childVcs;
@property (strong, nonatomic) NSArray *titlesArray;
@end
@implementation ZJScrollPageView
#pragma mark - life cycle
- (instancetype)initWithFrame:(CGRect)frame segmentStyle:(ZJSegmentStyle *)segmentStyle titles:(NSArray<NSString *> *)titles parentViewController:(UIViewController *)parentViewController delegate:(id<ZJScrollPageViewDelegate>) delegate {
    if (self = [super initWithFrame:frame]) {
        self.segmentStyle = segmentStyle;
        self.delegate = delegate;
        self.parentViewController = parentViewController;
        self.titlesArray = titles.copy;
        [self commonInit];
    }
    return self;
}
- (void)commonInit {
    // è§¦å‘懒加载
    self.segmentView.backgroundColor = [UIColor whiteColor];
    self.contentView.backgroundColor = [UIColor whiteColor];
}
- (void)dealloc {
    NSLog(@"ZJScrollPageView--销毁");
}
#pragma mark - public helper
/** ç»™å¤–界设置选中的下标的方法 */
- (void)setSelectedIndex:(NSInteger)selectedIndex animated:(BOOL)animated {
    [self.segmentView setSelectedIndex:selectedIndex animated:animated];
}
/**  ç»™å¤–界重新设置视图内容的标题的方法 */
- (void)reloadWithNewTitles:(NSArray<NSString *> *)newTitles {
    self.titlesArray = nil;
    self.titlesArray = newTitles.copy;
    [self.segmentView reloadTitlesWithNewTitles:self.titlesArray];
    [self.contentView reload];
}
#pragma mark - getter ---- setter
- (ZJContentView *)contentView {
    if (!_contentView) {
        ZJContentView *content = [[ZJContentView alloc] initWithFrame:CGRectMake(0.0, CGRectGetMaxY(self.segmentView.frame), self.bounds.size.width, self.bounds.size.height - CGRectGetMaxY(self.segmentView.frame)) segmentView:self.segmentView parentViewController:self.parentViewController delegate:self.delegate];
        [self addSubview:content];
        _contentView = content;
    }
    return  _contentView;
}
- (ZJScrollSegmentView *)segmentView {
    if (!_segmentView) {
        __weak typeof(self) weakSelf = self;
        ZJScrollSegmentView *segment = [[ZJScrollSegmentView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.segmentStyle.segmentHeight) segmentStyle:self.segmentStyle delegate:self.delegate titles:self.titlesArray titleDidClick:^(ZJTitleView *titleView, NSInteger index) {
            [weakSelf.contentView setContentOffSet:CGPointMake(weakSelf.contentView.bounds.size.width * index, 0.0) animated:weakSelf.segmentStyle.isAnimatedContentViewWhenTitleClicked];
        }];
        [self addSubview:segment];
        _segmentView = segment;
    }
    return _segmentView;
}
- (NSArray *)childVcs {
    if (!_childVcs) {
        _childVcs = [NSArray array];
    }
    return _childVcs;
}
- (NSArray *)titlesArray {
    if (!_titlesArray) {
        _titlesArray = [NSArray array];
    }
    return _titlesArray;
}
- (void)setExtraBtnOnClick:(ExtraBtnOnClick)extraBtnOnClick {
    _extraBtnOnClick = extraBtnOnClick;
    self.segmentView.extraBtnOnClick = extraBtnOnClick;
}
@end
BuWanVideo2.0/ZJScrollPageView/ZJScrollPageViewDelegate.h
New file
@@ -0,0 +1,77 @@
//
//  ZJScrollPageViewDelegate.h
//  ZJScrollPageView
//
//  Created by ZeroJ on 16/6/30.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import <UIKit/UIKit.h>
@class ZJContentView;
@class ZJTitleView;
@class ZJCollectionView;
@protocol ZJScrollPageViewChildVcDelegate <NSObject>
@optional
/**
 * è¯·æ³¨æ„: å¦‚果你希望所有的子控制器的view的系统生命周期方法被正确的调用
 * è¯·é‡å†™çˆ¶æŽ§åˆ¶å™¨çš„'shouldAutomaticallyForwardAppearanceMethods'方法 å¹¶ä¸”返回NO
 * å½“然如果你不做这个操作, å­æŽ§åˆ¶å™¨çš„生命周期方法将不会被正确的调用
 * å¦‚果你仍然想利用子控制器的生命周期方法, è¯·ä½¿ç”¨'ZJScrollPageViewChildVcDelegate'提供的代理方法
 * æˆ–者'ZJScrollPageViewDelegate'提供的代理方法
 */
- (void)zj_viewWillAppearForIndex:(NSInteger)index;
- (void)zj_viewDidAppearForIndex:(NSInteger)index;
- (void)zj_viewWillDisappearForIndex:(NSInteger)index;
- (void)zj_viewDidDisappearForIndex:(NSInteger)index;
- (void)zj_viewDidLoadForIndex:(NSInteger)index;
@end
@protocol ZJScrollPageViewDelegate <NSObject>
/** å°†è¦æ˜¾ç¤ºçš„子页面的总数 */
- (NSInteger)numberOfChildViewControllers;
/** èŽ·å–åˆ°å°†è¦æ˜¾ç¤ºçš„é¡µé¢çš„æŽ§åˆ¶å™¨
 * -reuseViewController : è¿™ä¸ªæ˜¯è¿”回给你的controller, ä½ åº”该首先判断这个是否为nil, å¦‚果为nil åˆ›å»ºå¯¹åº”的控制器并返回, å¦‚果不为nil直接使用并返回
 * -index : å¯¹åº”的下标
 */
- (UIViewController<ZJScrollPageViewChildVcDelegate> *)childViewController:(UIViewController<ZJScrollPageViewChildVcDelegate> *)reuseViewController forIndex:(NSInteger)index;
@optional
- (BOOL)scrollPageController:(UIViewController *)scrollPageController contentScrollView:(ZJCollectionView *)scrollView shouldBeginPanGesture:(UIPanGestureRecognizer *)panGesture;
- (void)setUpTitleView:(ZJTitleView *)titleView forIndex:(NSInteger)index;
/**
 *  é¡µé¢å°†è¦å‡ºçް
 *
 *  @param scrollPageController
 *  @param childViewController
 *  @param index
 */
- (void)scrollPageController:(UIViewController *)scrollPageController childViewControllWillAppear:(UIViewController *)childViewController forIndex:(NSInteger)index;
/**
 *  é¡µé¢å·²ç»å‡ºçް
 *
 *  @param scrollPageController
 *  @param childViewController
 *  @param index
 */
- (void)scrollPageController:(UIViewController *)scrollPageController childViewControllDidAppear:(UIViewController *)childViewController forIndex:(NSInteger)index;
- (void)scrollPageController:(UIViewController *)scrollPageController childViewControllWillDisappear:(UIViewController *)childViewController forIndex:(NSInteger)index;
- (void)scrollPageController:(UIViewController *)scrollPageController childViewControllDidDisappear:(UIViewController *)childViewController forIndex:(NSInteger)index;
/**
 *  é¡µé¢æ·»åŠ åˆ°çˆ¶è§†å›¾æ—¶ï¼Œåœ¨çˆ¶è§†å›¾ä¸­æ˜¾ç¤ºçš„ä½ç½®
 *  @param  containerView   childController çš„ self.view çˆ¶è§†å›¾
 *  @return è¿”回最终显示的位置
 */
- (CGRect)frameOfChildControllerForContainer:(UIView *)containerView;
@end
BuWanVideo2.0/ZJScrollPageView/ZJScrollSegmentView.h
New file
@@ -0,0 +1,40 @@
//
//  ZJScrollSegmentView.h
//  ZJScrollPageView
//
//  Created by jasnig on 16/5/6.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ZJSegmentStyle.h"
#import "ZJScrollPageViewDelegate.h"
@class ZJSegmentStyle;
@class ZJTitleView;
typedef void(^TitleBtnOnClickBlock)(ZJTitleView *titleView, NSInteger index);
typedef void(^ExtraBtnOnClick)(UIButton *extraBtn);
@interface ZJScrollSegmentView : UIView
// æ‰€æœ‰çš„æ ‡é¢˜
@property (strong, nonatomic) NSArray *titles;
// æ‰€æœ‰æ ‡é¢˜çš„设置
@property (strong, nonatomic) ZJSegmentStyle *segmentStyle;
@property (copy, nonatomic) ExtraBtnOnClick extraBtnOnClick;
@property (weak, nonatomic) id<ZJScrollPageViewDelegate> delegate;
@property (strong, nonatomic) UIImage *backgroundImage;
- (instancetype)initWithFrame:(CGRect )frame segmentStyle:(ZJSegmentStyle *)segmentStyle delegate:(id<ZJScrollPageViewDelegate>)delegate titles:(NSArray *)titles titleDidClick:(TitleBtnOnClickBlock)titleDidClick;
/** åˆ‡æ¢ä¸‹æ ‡çš„æ—¶å€™æ ¹æ®progress同步设置UI*/
- (void)adjustUIWithProgress:(CGFloat)progress oldIndex:(NSInteger)oldIndex currentIndex:(NSInteger)currentIndex;
/** è®©é€‰ä¸­çš„æ ‡é¢˜å±…中*/
- (void)adjustTitleOffSetToCurrentIndex:(NSInteger)currentIndex;
/** è®¾ç½®é€‰ä¸­çš„下标*/
- (void)setSelectedIndex:(NSInteger)index animated:(BOOL)animated;
/** é‡æ–°åˆ·æ–°æ ‡é¢˜çš„内容*/
- (void)reloadTitlesWithNewTitles:(NSArray *)titles;
@end
BuWanVideo2.0/ZJScrollPageView/ZJScrollSegmentView.m
New file
@@ -0,0 +1,738 @@
//
//  ZJScrollSegmentView.m
//  ZJScrollPageView
//
//  Created by jasnig on 16/5/6.
//  Copyright Â© 2016å¹´ ZeroJ. All rights reserved.
//
#import "ZJScrollSegmentView.h"
#import "ZJTitleView.h"
#import "UIView+ZJFrame.h"
@interface ZJScrollSegmentView ()<UIScrollViewDelegate> {
    CGFloat _currentWidth;
    NSUInteger _currentIndex;
    NSUInteger _oldIndex;
//    BOOL _isScroll;
}
// æ»šåŠ¨æ¡
@property (strong, nonatomic) UIView *scrollLine;
// é®ç›–
@property (strong, nonatomic) UIView *coverLayer;
// æ»šåЍscrollView
@property (strong, nonatomic) UIScrollView *scrollView;
// èƒŒæ™¯ImageView
@property (strong, nonatomic) UIImageView *backgroundImageView;
// é™„加的按钮
@property (strong, nonatomic) UIButton *extraBtn;
// ç”¨äºŽæ‡’加载计算文字的rgba差值, ç”¨äºŽé¢œè‰²æ¸å˜çš„æ—¶å€™è®¾ç½®
@property (strong, nonatomic) NSArray *deltaRGBA;
@property (strong, nonatomic) NSArray *selectedColorRGBA;
@property (strong, nonatomic) NSArray *normalColorRGBA;
/** ç¼“存所有标题label */
@property (nonatomic, strong) NSMutableArray *titleViews;
// ç¼“存计算出来的每个标题的宽度
@property (nonatomic, strong) NSMutableArray *titleWidths;
// å“åº”标题点击
@property (copy, nonatomic) TitleBtnOnClickBlock titleBtnOnClick;
@end
@implementation ZJScrollSegmentView
static CGFloat const xGap = 5.0;
static CGFloat const wGap = 2*xGap;
static CGFloat const contentSizeXOff = 20.0;
#pragma mark - life cycle
- (instancetype)initWithFrame:(CGRect )frame segmentStyle:(ZJSegmentStyle *)segmentStyle delegate:(id<ZJScrollPageViewDelegate>)delegate titles:(NSArray *)titles titleDidClick:(TitleBtnOnClickBlock)titleDidClick {
    if (self = [super initWithFrame:frame]) {
        self.segmentStyle = segmentStyle;
        self.titles = titles;
        self.titleBtnOnClick = titleDidClick;
        self.delegate = delegate;
        _currentIndex = 0;
        _oldIndex = 0;
        _currentWidth = frame.size.width;
        if (!self.segmentStyle.isScrollTitle) { // ä¸èƒ½æ»šåŠ¨çš„æ—¶å€™å°±ä¸è¦æŠŠç¼©æ”¾å’Œé®ç›–æˆ–è€…æ»šåŠ¨æ¡åŒæ—¶ä½¿ç”¨, å¦åˆ™æ˜¾ç¤ºæ•ˆæžœä¸å¥½
            self.segmentStyle.scaleTitle = !(self.segmentStyle.isShowCover || self.segmentStyle.isShowLine);
        }
        if (self.segmentStyle.isShowImage) {//不要有以下的显示效果
            self.segmentStyle.scaleTitle = NO;
            self.segmentStyle.showCover = NO;
            self.segmentStyle.gradualChangeTitleColor = NO;
        }
        // è®¾ç½®äº†frame之后可以直接设置其他的控件的frame了, ä¸éœ€è¦åœ¨layoutsubView()里面设置
        [self setupSubviews];
        [self setupUI];
    }
    return self;
}
- (void)setupSubviews {
    [self addSubview:self.scrollView];
    [self addScrollLineOrCoverOrExtraBtn];
    [self setupTitles];
}
- (void)addScrollLineOrCoverOrExtraBtn {
    if (self.segmentStyle.isShowLine) {
        [self.scrollView addSubview:self.scrollLine];
    }
    if (self.segmentStyle.isShowCover) {
        [self.scrollView insertSubview:self.coverLayer atIndex:0];
    }
    if (self.segmentStyle.isShowExtraButton) {
        [self addSubview:self.extraBtn];
    }
}
- (void)dealloc
{
#if DEBUG
    NSLog(@"ZJScrollSegmentView ---- é”€æ¯");
#endif
}
#pragma mark - button action
- (void)titleLabelOnClick:(UITapGestureRecognizer *)tapGes {
    ZJTitleView *currentLabel = (ZJTitleView *)tapGes.view;
    if (!currentLabel) {
        return;
    }
    _currentIndex = currentLabel.tag;
    [self adjustUIWhenBtnOnClickWithAnimate:true taped:YES];
}
- (void)extraBtnOnClick:(UIButton *)extraBtn {
    if (self.extraBtnOnClick) {
        self.extraBtnOnClick(extraBtn);
    }
}
#pragma mark - private helper
- (void)setupTitles {
    if (self.titles.count == 0) return;
    NSInteger index = 0;
    for (NSString *title in self.titles) {
        ZJTitleView *titleView = [[ZJTitleView alloc] initWithFrame:CGRectZero];
        titleView.tag = index;
        titleView.font = self.segmentStyle.titleFont;
        titleView.text = title;
        titleView.textColor = self.segmentStyle.normalTitleColor;
        titleView.imagePosition = self.segmentStyle.imagePosition;
        if (self.delegate && [self.delegate respondsToSelector:@selector(setUpTitleView:forIndex:)]) {
            [self.delegate setUpTitleView:titleView forIndex:index];
        }
        UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(titleLabelOnClick:)];
        [titleView addGestureRecognizer:tapGes];
        CGFloat titleViewWidth = [titleView titleViewWidth];
        [self.titleWidths addObject:@(titleViewWidth)];
        [self.titleViews addObject:titleView];
        [self.scrollView addSubview:titleView];
        index++;
    }
}
- (void)setupUI {
    if (self.titles.count == 0) return;
    [self setupScrollViewAndExtraBtn];
    [self setUpTitleViewsPosition];
    [self setupScrollLineAndCover];
    if (self.segmentStyle.isScrollTitle) { // è®¾ç½®æ»šåŠ¨åŒºåŸŸ
        ZJTitleView *lastTitleView = (ZJTitleView *)self.titleViews.lastObject;
        if (lastTitleView) {
            self.scrollView.contentSize = CGSizeMake(CGRectGetMaxX(lastTitleView.frame) + contentSizeXOff, 0.0);
        }
    }
}
- (void)setupScrollViewAndExtraBtn {
    CGFloat extraBtnW = 44.0;
    CGFloat extraBtnY = 5.0;
    //    UILabel *lastLabel = _titleLabels.lastObject;
    //    CGFloat maxX = CGRectGetMaxX(lastLabel.frame) + 8;
    CGFloat scrollW = self.extraBtn ? _currentWidth - extraBtnW : _currentWidth;
    //    if (maxX < _currentWidth) {
    //        scrollW = maxX;
    //    }
    self.scrollView.frame = CGRectMake(0.0, 0.0, scrollW, self.zj_height);
    if (self.extraBtn) {
        self.extraBtn.frame = CGRectMake(scrollW , extraBtnY, extraBtnW, self.zj_height - 2*extraBtnY);
    }
}
- (void)setUpTitleViewsPosition {
    CGFloat titleX = 0.0;
    CGFloat titleY = 0.0;
    CGFloat titleW = 0.0;
    CGFloat titleH = self.zj_height - self.segmentStyle.scrollLineHeight;
    if (!self.segmentStyle.isScrollTitle) {// æ ‡é¢˜ä¸èƒ½æ»šåЍ, å¹³åˆ†å®½åº¦
        titleW = self.scrollView.bounds.size.width / self.titles.count;
        NSInteger index = 0;
        for (ZJTitleView *titleView in self.titleViews) {
            titleX = index * titleW;
            titleView.frame = CGRectMake(titleX, titleY, titleW, titleH);
            if (self.segmentStyle.isShowImage) {
                [titleView adjustSubviewFrame];
            }
            index++;
        }
    } else {
        NSInteger index = 0;
        float lastLableMaxX = self.segmentStyle.titleMargin;
        float addedMargin = 0.0f;
        if (self.segmentStyle.isAutoAdjustTitlesWidth) {
            float allTitlesWidth = self.segmentStyle.titleMargin;
            for (int i = 0; i<self.titleWidths.count; i++) {
                allTitlesWidth = allTitlesWidth + [self.titleWidths[i] floatValue] + self.segmentStyle.titleMargin;
            }
            addedMargin = allTitlesWidth < self.scrollView.bounds.size.width ? (self.scrollView.bounds.size.width - allTitlesWidth)/self.titleWidths.count : 0 ;
        }
        for (ZJTitleView *titleView in self.titleViews) {
            titleW = [self.titleWidths[index] floatValue];
            titleX = lastLableMaxX + addedMargin/2;
            lastLableMaxX += (titleW + addedMargin + self.segmentStyle.titleMargin);
            titleView.frame = CGRectMake(titleX, titleY, titleW, titleH);
            if (self.segmentStyle.isShowImage) {
                [titleView adjustSubviewFrame];
            }
            index++;
        }
    }
    ZJTitleView *currentTitleView = (ZJTitleView *)self.titleViews[_currentIndex];
    currentTitleView.currentTransformSx = 1.0;
    if (currentTitleView) {
        // ç¼©æ”¾, è®¾ç½®åˆå§‹çš„label的transform
        if (self.segmentStyle.isScaleTitle) {
            currentTitleView.currentTransformSx = self.segmentStyle.titleBigScale;
        }
        // è®¾ç½®åˆå§‹çŠ¶æ€æ–‡å­—çš„é¢œè‰²
        currentTitleView.textColor = self.segmentStyle.selectedTitleColor;
        if (self.segmentStyle.isShowImage) {
            currentTitleView.selected = YES;
        }
    }
}
- (void)setupScrollLineAndCover {
    ZJTitleView *firstLabel = (ZJTitleView *)self.titleViews[0];
    CGFloat coverX = firstLabel.zj_x;
    CGFloat coverW = firstLabel.zj_width;
    CGFloat coverH = self.segmentStyle.coverHeight;
    CGFloat coverY = (self.bounds.size.height - coverH) * 0.5;
    if (self.scrollLine) {
        if (self.segmentStyle.isScrollTitle) {
            self.scrollLine.frame = CGRectMake(coverX , self.zj_height - self.segmentStyle.scrollLineHeight, coverW , self.segmentStyle.scrollLineHeight);
        } else {
            if (self.segmentStyle.isAdjustCoverOrLineWidth) {
                coverW = [self.titleWidths[_currentIndex] floatValue] + wGap;
                coverX = (firstLabel.zj_width - coverW) * 0.5;
            }
            self.scrollLine.frame = CGRectMake(coverX , self.zj_height - self.segmentStyle.scrollLineHeight, coverW , self.segmentStyle.scrollLineHeight);
        }
    }
    if (self.coverLayer) {
        if (self.segmentStyle.isScrollTitle) {
            self.coverLayer.frame = CGRectMake(coverX - xGap, coverY, coverW + wGap, coverH);
        } else {
            if (self.segmentStyle.isAdjustCoverOrLineWidth) {
                coverW = [self.titleWidths[_currentIndex] floatValue] + wGap;
                coverX = (firstLabel.zj_width - coverW) * 0.5;
            }
            self.coverLayer.frame = CGRectMake(coverX, coverY, coverW, coverH);
        }
    }
}
#pragma mark - public helper
- (void)adjustUIWhenBtnOnClickWithAnimate:(BOOL)animated taped:(BOOL)taped {
    if (_currentIndex == _oldIndex && taped) { return; }
    ZJTitleView *oldTitleView = (ZJTitleView *)self.titleViews[_oldIndex];
    ZJTitleView *currentTitleView = (ZJTitleView *)self.titleViews[_currentIndex];
    CGFloat animatedTime = animated ? 0.30 : 0.0;
    __weak typeof(self) weakSelf = self;
    [UIView animateWithDuration:animatedTime animations:^{
        oldTitleView.textColor = weakSelf.segmentStyle.normalTitleColor;
        currentTitleView.textColor = weakSelf.segmentStyle.selectedTitleColor;
        oldTitleView.selected = NO;
        currentTitleView.selected = YES;
        if (weakSelf.segmentStyle.isScaleTitle) {
            oldTitleView.currentTransformSx = 1.0;
            currentTitleView.currentTransformSx = weakSelf.segmentStyle.titleBigScale;
        }
        if (weakSelf.scrollLine) {
            if (weakSelf.segmentStyle.isScrollTitle) {
                weakSelf.scrollLine.zj_x = currentTitleView.zj_x;
                weakSelf.scrollLine.zj_width = currentTitleView.zj_width;
            } else {
                if (self.segmentStyle.isAdjustCoverOrLineWidth) {
                    CGFloat scrollLineW = [self.titleWidths[_currentIndex] floatValue] + wGap;
                    CGFloat scrollLineX = currentTitleView.zj_x + (currentTitleView.zj_width - scrollLineW) * 0.5;
                    weakSelf.scrollLine.zj_x = scrollLineX;
                    weakSelf.scrollLine.zj_width = scrollLineW;
                } else {
                    weakSelf.scrollLine.zj_x = currentTitleView.zj_x;
                    weakSelf.scrollLine.zj_width = currentTitleView.zj_width;
                }
            }
        }
        if (weakSelf.coverLayer) {
            if (weakSelf.segmentStyle.isScrollTitle) {
                weakSelf.coverLayer.zj_x = currentTitleView.zj_x - xGap;
                weakSelf.coverLayer.zj_width = currentTitleView.zj_width + wGap;
            } else {
                if (self.segmentStyle.isAdjustCoverOrLineWidth) {
                    CGFloat coverW = [self.titleWidths[_currentIndex] floatValue] + wGap;
                    CGFloat coverX = currentTitleView.zj_x + (currentTitleView.zj_width - coverW) * 0.5;
                    weakSelf.coverLayer.zj_x = coverX;
                    weakSelf.coverLayer.zj_width = coverW;
                } else {
                    weakSelf.coverLayer.zj_x = currentTitleView.zj_x;
                    weakSelf.coverLayer.zj_width = currentTitleView.zj_width;
                }
            }
        }
    } completion:^(BOOL finished) {
        [weakSelf adjustTitleOffSetToCurrentIndex:_currentIndex];
    }];
    _oldIndex = _currentIndex;
    if (self.titleBtnOnClick) {
        self.titleBtnOnClick(currentTitleView, _currentIndex);
    }
}
- (void)adjustUIWithProgress:(CGFloat)progress oldIndex:(NSInteger)oldIndex currentIndex:(NSInteger)currentIndex {
    if (oldIndex < 0 ||
        oldIndex >= self.titles.count ||
        currentIndex < 0 ||
        currentIndex >= self.titles.count
        ) {
        return;
    }
    _oldIndex = currentIndex;
    ZJTitleView *oldTitleView = (ZJTitleView *)self.titleViews[oldIndex];
    ZJTitleView *currentTitleView = (ZJTitleView *)self.titleViews[currentIndex];
    CGFloat xDistance = currentTitleView.zj_x - oldTitleView.zj_x;
    CGFloat wDistance = currentTitleView.zj_width - oldTitleView.zj_width;
    if (self.scrollLine) {
        if (self.segmentStyle.isScrollTitle) {
            self.scrollLine.zj_x = oldTitleView.zj_x + xDistance * progress;
            self.scrollLine.zj_width = oldTitleView.zj_width + wDistance * progress;
        } else {
            if (self.segmentStyle.isAdjustCoverOrLineWidth) {
                CGFloat oldScrollLineW = [self.titleWidths[oldIndex] floatValue] + wGap;
                CGFloat currentScrollLineW = [self.titleWidths[currentIndex] floatValue] + wGap;
                wDistance = currentScrollLineW - oldScrollLineW;
                CGFloat oldScrollLineX = oldTitleView.zj_x + (oldTitleView.zj_width - oldScrollLineW) * 0.5;
                CGFloat currentScrollLineX = currentTitleView.zj_x + (currentTitleView.zj_width - currentScrollLineW) * 0.5;
                xDistance = currentScrollLineX - oldScrollLineX;
                self.scrollLine.zj_x = oldScrollLineX + xDistance * progress;
                self.scrollLine.zj_width = oldScrollLineW + wDistance * progress;
            } else {
                self.scrollLine.zj_x = oldTitleView.zj_x + xDistance * progress;
                self.scrollLine.zj_width = oldTitleView.zj_width + wDistance * progress;
            }
        }
    }
    if (self.coverLayer) {
        if (self.segmentStyle.isScrollTitle) {
            self.coverLayer.zj_x = oldTitleView.zj_x + xDistance * progress - xGap;
            self.coverLayer.zj_width = oldTitleView.zj_width + wDistance * progress + wGap;
        } else {
            if (self.segmentStyle.isAdjustCoverOrLineWidth) {
                CGFloat oldCoverW = [self.titleWidths[oldIndex] floatValue] + wGap;
                CGFloat currentCoverW = [self.titleWidths[currentIndex] floatValue] + wGap;
                wDistance = currentCoverW - oldCoverW;
                CGFloat oldCoverX = oldTitleView.zj_x + (oldTitleView.zj_width - oldCoverW) * 0.5;
                CGFloat currentCoverX = currentTitleView.zj_x + (currentTitleView.zj_width - currentCoverW) * 0.5;
                xDistance = currentCoverX - oldCoverX;
                self.coverLayer.zj_x = oldCoverX + xDistance * progress;
                self.coverLayer.zj_width = oldCoverW + wDistance * progress;
            } else {
                self.coverLayer.zj_x = oldTitleView.zj_x + xDistance * progress;
                self.coverLayer.zj_width = oldTitleView.zj_width + wDistance * progress;
            }
        }
    }
    // æ¸å˜
    if (self.segmentStyle.isGradualChangeTitleColor) {
        oldTitleView.textColor = [UIColor
                                  colorWithRed:[self.selectedColorRGBA[0] floatValue] + [self.deltaRGBA[0] floatValue] * progress
                                  green:[self.selectedColorRGBA[1] floatValue] + [self.deltaRGBA[1] floatValue] * progress
                                  blue:[self.selectedColorRGBA[2] floatValue] + [self.deltaRGBA[2] floatValue] * progress
                                  alpha:[self.selectedColorRGBA[3] floatValue] + [self.deltaRGBA[3] floatValue] * progress];
        currentTitleView.textColor = [UIColor
                                      colorWithRed:[self.normalColorRGBA[0] floatValue] - [self.deltaRGBA[0] floatValue] * progress
                                      green:[self.normalColorRGBA[1] floatValue] - [self.deltaRGBA[1] floatValue] * progress
                                      blue:[self.normalColorRGBA[2] floatValue] - [self.deltaRGBA[2] floatValue] * progress
                                      alpha:[self.normalColorRGBA[3] floatValue] - [self.deltaRGBA[3] floatValue] * progress];
    }
    if (!self.segmentStyle.isScaleTitle) {
        return;
    }
    CGFloat deltaScale = self.segmentStyle.titleBigScale - 1.0;
    oldTitleView.currentTransformSx = self.segmentStyle.titleBigScale - deltaScale * progress;
    currentTitleView.currentTransformSx = 1.0 + deltaScale * progress;
}
- (void)adjustTitleOffSetToCurrentIndex:(NSInteger)currentIndex {
    _oldIndex = currentIndex;
    // é‡ç½®æ¸å˜/缩放效果附近其他item的缩放和颜色
    int index = 0;
    for (ZJTitleView *titleView in _titleViews) {
        if (index != currentIndex) {
            titleView.textColor = self.segmentStyle.normalTitleColor;
            titleView.currentTransformSx = 1.0;
            titleView.selected = NO;
        }
        else {
            titleView.textColor = self.segmentStyle.selectedTitleColor;
            if (self.segmentStyle.isScaleTitle) {
                titleView.currentTransformSx = self.segmentStyle.titleBigScale;
            }
            titleView.selected = YES;
        }
        index++;
    }
//
    if (self.scrollView.contentSize.width != self.scrollView.bounds.size.width + contentSizeXOff) {// éœ€è¦æ»šåЍ
        ZJTitleView *currentTitleView = (ZJTitleView *)_titleViews[currentIndex];
        CGFloat offSetx = currentTitleView.center.x - _currentWidth * 0.5;
        if (offSetx < 0) {
            offSetx = 0;
        }
        CGFloat extraBtnW = self.extraBtn ? self.extraBtn.zj_width : 0.0;
        CGFloat maxOffSetX = self.scrollView.contentSize.width - (_currentWidth - extraBtnW);
        if (maxOffSetX < 0) {
            maxOffSetX = 0;
        }
        if (offSetx > maxOffSetX) {
            offSetx = maxOffSetX;
        }
//        if (!self.segmentStyle.isGradualChangeTitleColor) {
//            int index = 0;
//            for (ZJTitleView *titleView in _titleViews) {
//                if (index != currentIndex) {
//                    titleView.textColor = self.segmentStyle.normalTitleColor;
//                    titleView.currentTransformSx = 1.0;
//                    titleView.selected = NO;
//                }
//                else {
//                    titleView.textColor = self.segmentStyle.selectedTitleColor;
//                    if (self.segmentStyle.isScaleTitle) {
//                        titleView.currentTransformSx = self.segmentStyle.titleBigScale;
//                    }
//                    titleView.selected = YES;
//
//                }
//
//                index++;
//            }
//        }
        [self.scrollView setContentOffset:CGPointMake(offSetx, 0.0) animated:YES];
    }
}
- (void)setSelectedIndex:(NSInteger)index animated:(BOOL)animated {
    NSAssert(index >= 0 && index < self.titles.count, @"设置的下标不合法!!");
    if (index < 0 || index >= self.titles.count) {
        return;
    }
    _currentIndex = index;
    [self adjustUIWhenBtnOnClickWithAnimate:animated taped:NO];
}
- (void)reloadTitlesWithNewTitles:(NSArray *)titles {
    [self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    _currentIndex = 0;
    _oldIndex = 0;
    self.titleWidths = nil;
    self.titleViews = nil;
    self.titles = nil;
    self.titles = [titles copy];
    if (self.titles.count == 0) return;
    for (UIView *subview in self.subviews) {
        [subview removeFromSuperview];
    }
    [self setupSubviews];
    [self setupUI];
    [self setSelectedIndex:0 animated:YES];
}
#pragma mark - getter --- setter
- (UIView *)scrollLine {
    if (!self.segmentStyle.isShowLine) {
        return nil;
    }
    if (!_scrollLine) {
        UIView *lineView = [[UIView alloc] init];
        lineView.backgroundColor = self.segmentStyle.scrollLineColor;
        _scrollLine = lineView;
    }
    return _scrollLine;
}
- (UIView *)coverLayer {
    if (!self.segmentStyle.isShowCover) {
        return nil;
    }
    if (_coverLayer == nil) {
        UIView *coverView = [[UIView alloc] init];
        coverView.backgroundColor = self.segmentStyle.coverBackgroundColor;
        coverView.layer.cornerRadius = self.segmentStyle.coverCornerRadius;
        coverView.layer.masksToBounds = YES;
        _coverLayer = coverView;
    }
    return _coverLayer;
}
- (UIButton *)extraBtn {
    if (!self.segmentStyle.showExtraButton) {
        return nil;
    }
    if (!_extraBtn) {
        UIButton *btn = [UIButton new];
        [btn addTarget:self action:@selector(extraBtnOnClick:) forControlEvents:UIControlEventTouchUpInside];
        NSString *imageName = self.segmentStyle.extraBtnBackgroundImageName ? self.segmentStyle.extraBtnBackgroundImageName : @"";
        [btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
        btn.backgroundColor = [UIColor whiteColor];
        // è®¾ç½®è¾¹ç¼˜çš„阴影效果
        btn.layer.shadowColor = [UIColor whiteColor].CGColor;
        btn.layer.shadowOffset = CGSizeMake(-5, 0);
        btn.layer.shadowOpacity = 1;
        _extraBtn = btn;
    }
    return _extraBtn;
}
- (UIScrollView *)scrollView {
    if (!_scrollView) {
        UIScrollView *scrollView = [[UIScrollView alloc] init];
        scrollView.showsHorizontalScrollIndicator = NO;
        scrollView.scrollsToTop = NO;
        scrollView.bounces = self.segmentStyle.isSegmentViewBounces;
        scrollView.pagingEnabled = NO;
        scrollView.delegate = self;
        _scrollView = scrollView;
    }
    return _scrollView;
}
- (UIImageView *)backgroundImageView {
    if (!_backgroundImageView) {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        [self insertSubview:imageView atIndex:0];
        _backgroundImageView = imageView;
    }
    return _backgroundImageView;
}
- (void)setBackgroundImage:(UIImage *)backgroundImage {
    _backgroundImage = backgroundImage;
    if (backgroundImage) {
        self.backgroundImageView.image = backgroundImage;
    }
}
- (NSMutableArray *)titleViews
{
    if (_titleViews == nil) {
        _titleViews = [NSMutableArray array];
    }
    return _titleViews;
}
- (NSMutableArray *)titleWidths
{
    if (_titleWidths == nil) {
        _titleWidths = [NSMutableArray array];
    }
    return _titleWidths;
}
- (NSArray *)deltaRGBA {
    if (_deltaRGBA == nil) {
        NSArray *normalColorRgb = self.normalColorRGBA;
        NSArray *selectedColorRgb = self.selectedColorRGBA;
        NSArray *delta;
        if (normalColorRgb && selectedColorRgb) {
            CGFloat deltaR = [normalColorRgb[0] floatValue] - [selectedColorRgb[0] floatValue];
            CGFloat deltaG = [normalColorRgb[1] floatValue] - [selectedColorRgb[1] floatValue];
            CGFloat deltaB = [normalColorRgb[2] floatValue] - [selectedColorRgb[2] floatValue];
            CGFloat deltaA = [normalColorRgb[3] floatValue] - [selectedColorRgb[3] floatValue];
            delta = [NSArray arrayWithObjects:@(deltaR), @(deltaG), @(deltaB), @(deltaA), nil];
            _deltaRGBA = delta;
        }
    }
    return _deltaRGBA;
}
- (NSArray *)normalColorRGBA {
    if (!_normalColorRGBA) {
        NSArray *normalColorRGBA = [self getColorRGBA:self.segmentStyle.normalTitleColor];
        NSAssert(normalColorRGBA, @"设置普通状态的文字颜色时 è¯·ä½¿ç”¨RGBA空间的颜色值");
        _normalColorRGBA = normalColorRGBA;
    }
    return  _normalColorRGBA;
}
- (NSArray *)selectedColorRGBA {
    if (!_selectedColorRGBA) {
        NSArray *selectedColorRGBA = [self getColorRGBA:self.segmentStyle.selectedTitleColor];
        NSAssert(selectedColorRGBA, @"设置选中状态的文字颜色时 è¯·ä½¿ç”¨RGBA空间的颜色值");
        _selectedColorRGBA = selectedColorRGBA;
    }
    return  _selectedColorRGBA;
}
- (NSArray *)getColorRGBA:(UIColor *)color {
    CGFloat numOfcomponents = CGColorGetNumberOfComponents(color.CGColor);
    NSArray *rgbaComponents;
    if (numOfcomponents == 4) {
        const CGFloat *components = CGColorGetComponents(color.CGColor);
        rgbaComponents = [NSArray arrayWithObjects:@(components[0]), @(components[1]), @(components[2]), @(components[3]), nil];
    }
    return rgbaComponents;
}
@end
Diff truncated after the above file
BuWanVideo2.0/ZJScrollPageView/ZJSegmentStyle.h BuWanVideo2.0/ZJScrollPageView/ZJSegmentStyle.m BuWanVideo2.0/ZJScrollPageView/ZJTitleView.h BuWanVideo2.0/ZJScrollPageView/ZJTitleView.m BuWanVideo2.0/discoverView.m BuWanVideo2.0/discoverViewController.h BuWanVideo2.0/discoverViewController.m BuWanVideo2.0/dsbridge/DSCallInfo.h BuWanVideo2.0/dsbridge/DSCallInfo.m BuWanVideo2.0/dsbridge/DWKWebView.h BuWanVideo2.0/dsbridge/DWKWebView.m BuWanVideo2.0/dsbridge/InternalApis.h BuWanVideo2.0/dsbridge/InternalApis.m BuWanVideo2.0/dsbridge/JSBUtil.h BuWanVideo2.0/dsbridge/JSBUtil.m BuWanVideo2.0/dsbridge/dsbridge.h BuWanVideo2.0/recommendView.m BuWanVideo2.0/searchViewController.m BuWanVideo2.0/subregionView.m BuWanVideo2.0/subregionViewController.h BuWanVideo2.0/subregionViewController.m BuWanVideo2.0/猜你喜欢/GuessLikeViewController.h BuWanVideo2.0/猜你喜欢/GuessLikeViewController.m Podfile Podfile.lock Pods/Manifest.lock Pods/Pods.xcodeproj/project.pbxproj Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/SDAutoLayout.xcscheme Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/xcschememanagement.plist Pods/SDAutoLayout/LICENSE Pods/SDAutoLayout/README.md Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/SDAutoLayout.h Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UITableView+SDAutoTableViewCellHeight.h Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UITableView+SDAutoTableViewCellHeight.m Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UIView+SDAutoLayout.h Pods/SDAutoLayout/SDAutoLayoutDemo/SDAutoLayout/UIView+SDAutoLayout.m Pods/Target Support Files/AFNetworking/AFNetworking.debug.xcconfig Pods/Target Support Files/AFNetworking/AFNetworking.release.xcconfig Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-acknowledgements.markdown Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-acknowledgements.plist Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.debug.xcconfig Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.release.xcconfig Pods/Target Support Files/SDAutoLayout/SDAutoLayout-Info.plist Pods/Target Support Files/SDAutoLayout/SDAutoLayout-dummy.m Pods/Target Support Files/SDAutoLayout/SDAutoLayout-prefix.pch Pods/Target Support Files/SDAutoLayout/SDAutoLayout-umbrella.h Pods/Target Support Files/SDAutoLayout/SDAutoLayout.debug.xcconfig Pods/Target Support Files/SDAutoLayout/SDAutoLayout.modulemap Pods/Target Support Files/SDAutoLayout/SDAutoLayout.release.xcconfig Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig Pods/Target Support Files/SVProgressHUD/SVProgressHUD.debug.xcconfig Pods/Target Support Files/SVProgressHUD/SVProgressHUD.release.xcconfig Pods/Target Support Files/UMCCommon/UMCCommon.debug.xcconfig Pods/Target Support Files/UMCCommon/UMCCommon.release.xcconfig Pods/Target Support Files/YYCache/YYCache.debug.xcconfig Pods/Target Support Files/YYCache/YYCache.release.xcconfig Pods/Target Support Files/YYImage/YYImage.debug.xcconfig Pods/Target Support Files/YYImage/YYImage.release.xcconfig Pods/Target Support Files/YYModel/YYModel.debug.xcconfig Pods/Target Support Files/YYModel/YYModel.release.xcconfig Pods/Target Support Files/YYWebImage/YYWebImage.debug.xcconfig Pods/Target Support Files/YYWebImage/YYWebImage.release.xcconfig