302个文件已添加
64个文件已修改
60 文件已重命名
55个文件已删除
| | |
| | | 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 */; }; |
| | |
| | | 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 */; }; |
| | |
| | | 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>"; }; |
| | |
| | | 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>"; }; |
| | |
| | | 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>"; }; |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 18A8D14C1DC32CFD00A03FB7 /* æ¨è */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 704C148D265A93E2009DAB98 /* Recommend */, |
| | | 18E943E42057656C0019FD04 /* recommendViewController.h */, |
| | | 18E943E52057656C0019FD04 /* recommendViewController.m */, |
| | | 7B32BD2D1D4F259300E96E75 /* recommendView.h */, |
| | |
| | | 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 */ = { |
| | |
| | | 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 */ = { |
| | |
| | | 7BC600A01D63F134005CE8FD /* searchView(æç´¢) */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 7034AC8B2663A0200056133F /* SearchNew */, |
| | | 705951F12516112D008E0CDF /* View */, |
| | | 7BC600A31D63F187005CE8FD /* viewController */, |
| | | 7BC600A11D63F167005CE8FD /* view */, |
| | |
| | | AD73C5ED1D4DDBAE0060437E /* lib(ç¬¬ä¸æ¹åº) */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 704C14A6265B72A5009DAB98 /* ZJScrollPageView */, |
| | | 706CECCA264FB895001FBEB7 /* dsbridge */, |
| | | 705F1F36251F1CA70065350E /* MJRefresh */, |
| | | 7042C94A2515A4FE0017F5D8 /* CSJ */, |
| | | 188322341F74AFFD00CCD0B4 /* HXEasyCustomShare */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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", |
| | |
| | | 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", |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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 */, |
| | |
| | | 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; |
| | |
| | | <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> |
| | |
| | | |
| | | //#import <AlibcTradeSDK/AlibcTradeSDK.h> |
| | | |
| | | #import "RecommendMainController.h" |
| | | #import "RecommendController.h" |
| | | #import "recommendViewController.h" |
| | | #import "subregionViewController.h" |
| | | #import "MineViewController.h" |
| | |
| | | //#import <UMShare/UMShare.h> |
| | | |
| | | #import <BUAdSDK/BUAdSDK.h> |
| | | #import <AppTrackingTransparency/AppTrackingTransparency.h> |
| | | #import <AdSupport/ASIdentifierManager.h> |
| | | |
| | | #define LECUsedBundleID @"com.yeshi.buwanshequ.ios" |
| | | |
| | |
| | | //æ¸
ç©ºè§æ |
| | | [UIApplication sharedApplication].applicationIconBadgeNumber = 0; |
| | | //è®¾ç½®ç¶ææ çåä½é¢è² |
| | | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; |
| | | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; |
| | | [self requestIDFA]; |
| | | //æ·»å ç½ç»çæµ |
| | | [self NetworkMonitoring]; |
| | | |
| | |
| | | |
| | | TOCK; |
| | | return YES; |
| | | } |
| | | |
| | | - (void)requestIDFA { |
| | | if (@available(iOS 14, *)) { |
| | | [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { |
| | | |
| | | }]; |
| | | |
| | | } else { |
| | | // Fallback on earlier versions |
| | | } |
| | | } |
| | | |
| | | - (void)fetchCommenConfig { |
| | |
| | | } |
| | | |
| | | - (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; |
| | | } |
| | | |
| | |
| | | |
| | | 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]; |
| | |
| | | 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]; |
| | |
| | | { |
| | | "info" : { |
| | | "version" : 1, |
| | | "author" : "xcode" |
| | | "author" : "xcode", |
| | | "version" : 1 |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "info" : { |
| | | "author" : "xcode", |
| | | "version" : 1 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
| | |
| | | { |
| | | "info" : { |
| | | "version" : 1, |
| | | "author" : "xcode" |
| | | "author" : "xcode", |
| | | "version" : 1 |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
New file |
| | |
| | | { |
| | | "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 |
| | | } |
| | | } |
| | |
| | | } |
| | | 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]]; |
| | | |
| | |
| | | "GetRewardAfterWatching" = "åç»ãæå¾ã¾ã§è¦è´ããã ããã¨ãªã¯ã¼ããä»ä¸ããã¾ã"; |
| | | "GiveUpReward" = "ãããªã"; |
| | | "ContinueWatching" = "è¦è´ãç¶ãã"; |
| | | "CanbeTurnedOffAfter" = "%dså¾ã«éãããã¾ã"; |
| | | "CanbeTurnedOffAfter" = "%dså¾ã«ã¹ããã"; |
| | | "Get" = "å
¥æ"; |
| | | "View" = "è¦ã"; |
| | | "ContinuePlaying" = "ã¤ã¥ãã"; |
New file |
| | |
| | | Versions/Current/BUAdSDK |
New file |
| | |
| | | Versions/Current/Headers |
New file |
| | |
| | | Versions/Current/Resources |
New file |
| | |
| | | // |
| | | // 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> |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | }; |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 */ |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 */ |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | Versions/Current/BUCNAuxiliary |
New file |
| | |
| | | Versions/Current/Headers |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // HMDBUBacktraceLog.h |
| | | // AppleCrashLog |
| | | // |
| | | // Created by è°¢ä¿é¸ on 8/3/2018. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "HMDBUThreadBacktrace.h" |
| | | |
| | | @interface HMDBUBacktraceLog : NSObject |
| | | + (NSString *)backtraceLogStringWithBacktraceInfo:(HMDBUThreadBacktrace*)backtraceInfo; |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | }; |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | Versions/Current/BUFoundation |
New file |
| | |
| | | Versions/Current/Headers |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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); |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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***********************************/ |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 *); |
New file |
| | |
| | | // |
| | | // 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; |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 */ |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | /* |
| | | 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 |
| | | |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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); |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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. |
| | | }; |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /** |
| | | * 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 |
New file |
| | |
| | | // |
| | | // 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" |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | |
| | | #import "YYModel.h" |
| | | #import "Share.h" |
| | | #import "YYWebImage.h" |
| | | #import <SDAutoLayout/SDAutoLayout.h> |
| | | |
| | | #import "HXEasyCustomShareView.h"//å享çé¢ |
| | | |
| | |
| | | // 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 // å±å¹å®½åº¦ |
| | |
| | | #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)//åºç¨ç主è²è° |
| | |
| | | <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> |
| | |
| | | <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> |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | |
| | | // Copyright © 2016年 com.yeshi.buwansheque.ios. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "MainBaseController.h" |
| | | |
| | | @interface LeftViewController : BaseViewController |
| | | @interface LeftViewController : MainBaseController |
| | | |
| | | @end |
| | |
| | | |
| | | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *MarkToMain;//è¿ä¸ªçå¼ä¸ºå®½åº¦çååä¹ä¸ |
| | | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *LeftbackgroundH;//æ ¹æ®å¾çæ¯ä¾è®¾ç½®é« |
| | | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageBGTopSpace; |
| | | |
| | | @property (nonatomic, assign) BOOL userOnLine;//ç¨æ·æ¯å¦ç»å½ |
| | | |
| | |
| | | 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; |
| | |
| | | <?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> |
| | |
| | | <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> |
| | |
| | | <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"/> |
| | |
| | | <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"/> |
| | |
| | | #define GetHomeAd @"getHomeAd" |
| | | |
| | | #pragma mark æ¨èåç±» |
| | | #define GetHomeType @"getHomeType" |
| | | #define GetHomeType @"getHomeTypeNew" |
| | | |
| | | #pragma mark æ´å¤è§é¢ |
| | | #define GetMoreVideo @"getMoreVideo" |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | |
| | | // |
| | | |
| | | #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 |
| | |
| | | [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); |
| | |
| | | }]; |
| | | } |
| | | |
| | | - (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(@""); |
| | | } |
| | | |
| | | // 页é¢å¼å§å è½½æ¶è°ç¨ |
| | |
| | | [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]; |
| | |
| | | //设置请æ±ç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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // 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 */ |
New file |
| | |
| | | // |
| | | // 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 */ |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | |
| | | // 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 |
New file |
| | |
| | | |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | |
| | | /** |
| | | * æ¨èåç±» |
| | | */ |
| | | - (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; |
| | | |
| | | /** |
| | | * ç¹å»ä¸ä¼ åç°é¡µé¢ç广å |
| | |
| | | |
| | | - (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 |
| | |
| | | } |
| | | |
| | | |
| | | - (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{ |
| | | |
| | |
| | | }]; |
| | | } |
| | | #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) { |
| | |
| | | }]; |
| | | } |
| | | |
| | | - (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{ |
| | |
| | | /** |
| | | * æ¨èåç±» |
| | | */ |
| | | + (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; |
| | | |
| | |
| | | //é¦é¡µç²¾é |
| | | + (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 |
| | |
| | | } |
| | | |
| | | #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"]; |
| | |
| | | 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{ |
| | |
| | | + (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"]; |
| | |
| | | /** |
| | | * æ´ä¸ªç¨åºç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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
New file |
| | |
| | | // |
| | | // 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 |
New file |
| | |
| | | // |
| | | // 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 |
| | | |
| | | |
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 |