├── README.md
├── ZKBanner.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── cain.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── cain.xcuserdatad
│ └── xcschemes
│ ├── ZKBanner.xcscheme
│ └── xcschememanagement.plist
├── ZKBanner
├── NewBannerView.h
├── NewBannerView.m
├── NewBannerViewManager.h
├── NewBannerViewManager.m
└── SDCycleScrollView
│ ├── PageControl
│ ├── TAAbstractDotView.h
│ ├── TAAbstractDotView.m
│ ├── TAAnimatedDotView.h
│ ├── TAAnimatedDotView.m
│ ├── TADotView.h
│ ├── TADotView.m
│ ├── TAPageControl.h
│ └── TAPageControl.m
│ ├── SDCollectionViewCell.h
│ ├── SDCollectionViewCell.m
│ ├── SDCycleScrollView.h
│ ├── SDCycleScrollView.m
│ ├── UIView+SDExtension.h
│ └── UIView+SDExtension.m
├── components
└── NewBanner.js
├── index.js
└── package.json
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-zkbanner
2 |
3 |
4 |
5 | ## Demo
6 | The [Project Demo](https://github.com/cainvan/ReactBannerDemo)
7 |
8 |
9 | 
10 |
11 | ## Introduction
12 |
13 | The aim of this library is to provide reusable React Native components that can Use a network or local image as a dynamic banner.
14 |
15 | ## Installation
16 |
17 | 1. Run `npm install --save react-native-zkbanner`.
18 |
19 | 2. Add all the files under node_modules/react-native-zkbanner/ZKBanner. (In Xcode: File -> Add files to "App Name").
20 |
21 | 3. Then you need to add [SDWebImage](https://github.com/rs/SDWebImage) to the Xcode project. Here, you can use the react-native-zkbanner.
22 |
23 |
24 | # Usage
25 |
26 | Example code:
27 |
28 | ```JavaScript
29 | /**
30 | * Sample React Native App
31 | * https://github.com/facebook/react-native
32 | * @flow
33 | */
34 |
35 | import React, { Component } from 'react';
36 | import {
37 | AppRegistry,
38 | StyleSheet,
39 | Dimensions,
40 | Text,
41 | View
42 | } from 'react-native';
43 |
44 | import { Banner } from 'react-native-zkbanner';
45 |
46 | class ReactBannerDemo extends Component {
47 | render() {
48 | var bannerImgs = [
49 | 'https://www.umeng.com/img/index/demo/0901-2.c1df5ebf79f4c2b31f5ded9b13970826.png',
50 | 'https://www.umeng.com/img/index/demo/0912.97aa0956cef2b613001d28d394eb4bd0.png',
51 | 'https://www.umeng.com/img/index/demo/8.a0a7379becc230ef38295a74956ec8f2.png',
52 | 'https://www.umeng.com/img/index/demo/825-1.58787216c12fb39bb6d384ad4d278037.jpg'
53 | ];
54 | return (
55 |
56 | {
61 | console.log('react' + event.nativeEvent.value);
62 | }}
63 | />
64 |
65 | );
66 | }
67 | }
68 |
69 | const styles = StyleSheet.create({
70 | map0: {
71 | width:Dimensions.get('window').width,
72 | height:Dimensions.get('window').height,
73 | alignItems:'center',
74 | justifyContent:'center',
75 | },
76 | map1: {
77 | width:Dimensions.get('window').width,
78 | height:200,
79 | },
80 | });
81 |
82 | AppRegistry.registerComponent('ReactBannerDemo', () => ReactBannerDemo);
83 |
84 | ```
85 | # License
86 | The MIT License (MIT)
87 |
88 | Copyright (C) 2016 cain_van@163.com
89 |
90 | 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:
91 |
92 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
93 |
94 | 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.
95 |
96 |
--------------------------------------------------------------------------------
/ZKBanner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A4387CA61D8935D900BDB11A /* NewBannerView.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387C931D8935D900BDB11A /* NewBannerView.m */; };
11 | A4387CA71D8935D900BDB11A /* NewBannerViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387C951D8935D900BDB11A /* NewBannerViewManager.m */; };
12 | A4387CA81D8935D900BDB11A /* TAAbstractDotView.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387C991D8935D900BDB11A /* TAAbstractDotView.m */; };
13 | A4387CA91D8935D900BDB11A /* TAAnimatedDotView.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387C9B1D8935D900BDB11A /* TAAnimatedDotView.m */; };
14 | A4387CAA1D8935D900BDB11A /* TADotView.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387C9D1D8935D900BDB11A /* TADotView.m */; };
15 | A4387CAB1D8935D900BDB11A /* TAPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387C9F1D8935D900BDB11A /* TAPageControl.m */; };
16 | A4387CAC1D8935D900BDB11A /* SDCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387CA11D8935D900BDB11A /* SDCollectionViewCell.m */; };
17 | A4387CAD1D8935D900BDB11A /* SDCycleScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387CA31D8935D900BDB11A /* SDCycleScrollView.m */; };
18 | A4387CAE1D8935D900BDB11A /* UIView+SDExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = A4387CA51D8935D900BDB11A /* UIView+SDExtension.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | A4387C761D89356D00BDB11A /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = A4387C541D89356D00BDB11A /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = A4387C5B1D89356D00BDB11A;
27 | remoteInfo = ZKBanner;
28 | };
29 | A4387C811D89356D00BDB11A /* PBXContainerItemProxy */ = {
30 | isa = PBXContainerItemProxy;
31 | containerPortal = A4387C541D89356D00BDB11A /* Project object */;
32 | proxyType = 1;
33 | remoteGlobalIDString = A4387C5B1D89356D00BDB11A;
34 | remoteInfo = ZKBanner;
35 | };
36 | /* End PBXContainerItemProxy section */
37 |
38 | /* Begin PBXFileReference section */
39 | A4387C921D8935D900BDB11A /* NewBannerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewBannerView.h; sourceTree = ""; };
40 | A4387C931D8935D900BDB11A /* NewBannerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewBannerView.m; sourceTree = ""; };
41 | A4387C941D8935D900BDB11A /* NewBannerViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewBannerViewManager.h; sourceTree = ""; };
42 | A4387C951D8935D900BDB11A /* NewBannerViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewBannerViewManager.m; sourceTree = ""; };
43 | A4387C981D8935D900BDB11A /* TAAbstractDotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TAAbstractDotView.h; sourceTree = ""; };
44 | A4387C991D8935D900BDB11A /* TAAbstractDotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TAAbstractDotView.m; sourceTree = ""; };
45 | A4387C9A1D8935D900BDB11A /* TAAnimatedDotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TAAnimatedDotView.h; sourceTree = ""; };
46 | A4387C9B1D8935D900BDB11A /* TAAnimatedDotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TAAnimatedDotView.m; sourceTree = ""; };
47 | A4387C9C1D8935D900BDB11A /* TADotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TADotView.h; sourceTree = ""; };
48 | A4387C9D1D8935D900BDB11A /* TADotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TADotView.m; sourceTree = ""; };
49 | A4387C9E1D8935D900BDB11A /* TAPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TAPageControl.h; sourceTree = ""; };
50 | A4387C9F1D8935D900BDB11A /* TAPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TAPageControl.m; sourceTree = ""; };
51 | A4387CA01D8935D900BDB11A /* SDCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDCollectionViewCell.h; sourceTree = ""; };
52 | A4387CA11D8935D900BDB11A /* SDCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDCollectionViewCell.m; sourceTree = ""; };
53 | A4387CA21D8935D900BDB11A /* SDCycleScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDCycleScrollView.h; sourceTree = ""; };
54 | A4387CA31D8935D900BDB11A /* SDCycleScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDCycleScrollView.m; sourceTree = ""; };
55 | A4387CA41D8935D900BDB11A /* UIView+SDExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+SDExtension.h"; sourceTree = ""; };
56 | A4387CA51D8935D900BDB11A /* UIView+SDExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SDExtension.m"; sourceTree = ""; };
57 | A4387CAF1D89361400BDB11A /* ZKBanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = ZKBanner.app; path = "/Users/cain/Desktop/react-banner/ZKBanner/build/Debug-iphoneos/ZKBanner.app"; sourceTree = ""; };
58 | A4387CB01D89361400BDB11A /* ZKBannerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = ZKBannerTests.xctest; path = "/Users/cain/Desktop/react-banner/ZKBanner/build/Debug-iphoneos/ZKBannerTests.xctest"; sourceTree = ""; };
59 | A4387CB11D89361400BDB11A /* ZKBannerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = ZKBannerUITests.xctest; path = "/Users/cain/Desktop/react-banner/ZKBanner/build/Debug-iphoneos/ZKBannerUITests.xctest"; sourceTree = ""; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | A4387C591D89356D00BDB11A /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | A4387C721D89356D00BDB11A /* Frameworks */ = {
71 | isa = PBXFrameworksBuildPhase;
72 | buildActionMask = 2147483647;
73 | files = (
74 | );
75 | runOnlyForDeploymentPostprocessing = 0;
76 | };
77 | A4387C7D1D89356D00BDB11A /* Frameworks */ = {
78 | isa = PBXFrameworksBuildPhase;
79 | buildActionMask = 2147483647;
80 | files = (
81 | );
82 | runOnlyForDeploymentPostprocessing = 0;
83 | };
84 | /* End PBXFrameworksBuildPhase section */
85 |
86 | /* Begin PBXGroup section */
87 | A4387C531D89356D00BDB11A = {
88 | isa = PBXGroup;
89 | children = (
90 | A4387C5E1D89356D00BDB11A /* ZKBanner */,
91 | );
92 | sourceTree = "";
93 | };
94 | A4387C5E1D89356D00BDB11A /* ZKBanner */ = {
95 | isa = PBXGroup;
96 | children = (
97 | A4387C921D8935D900BDB11A /* NewBannerView.h */,
98 | A4387C931D8935D900BDB11A /* NewBannerView.m */,
99 | A4387C941D8935D900BDB11A /* NewBannerViewManager.h */,
100 | A4387C951D8935D900BDB11A /* NewBannerViewManager.m */,
101 | A4387C961D8935D900BDB11A /* SDCycleScrollView */,
102 | );
103 | path = ZKBanner;
104 | sourceTree = "";
105 | };
106 | A4387C961D8935D900BDB11A /* SDCycleScrollView */ = {
107 | isa = PBXGroup;
108 | children = (
109 | A4387C971D8935D900BDB11A /* PageControl */,
110 | A4387CA01D8935D900BDB11A /* SDCollectionViewCell.h */,
111 | A4387CA11D8935D900BDB11A /* SDCollectionViewCell.m */,
112 | A4387CA21D8935D900BDB11A /* SDCycleScrollView.h */,
113 | A4387CA31D8935D900BDB11A /* SDCycleScrollView.m */,
114 | A4387CA41D8935D900BDB11A /* UIView+SDExtension.h */,
115 | A4387CA51D8935D900BDB11A /* UIView+SDExtension.m */,
116 | );
117 | path = SDCycleScrollView;
118 | sourceTree = "";
119 | };
120 | A4387C971D8935D900BDB11A /* PageControl */ = {
121 | isa = PBXGroup;
122 | children = (
123 | A4387C981D8935D900BDB11A /* TAAbstractDotView.h */,
124 | A4387C991D8935D900BDB11A /* TAAbstractDotView.m */,
125 | A4387C9A1D8935D900BDB11A /* TAAnimatedDotView.h */,
126 | A4387C9B1D8935D900BDB11A /* TAAnimatedDotView.m */,
127 | A4387C9C1D8935D900BDB11A /* TADotView.h */,
128 | A4387C9D1D8935D900BDB11A /* TADotView.m */,
129 | A4387C9E1D8935D900BDB11A /* TAPageControl.h */,
130 | A4387C9F1D8935D900BDB11A /* TAPageControl.m */,
131 | );
132 | path = PageControl;
133 | sourceTree = "";
134 | };
135 | /* End PBXGroup section */
136 |
137 | /* Begin PBXNativeTarget section */
138 | A4387C5B1D89356D00BDB11A /* ZKBanner */ = {
139 | isa = PBXNativeTarget;
140 | buildConfigurationList = A4387C891D89356D00BDB11A /* Build configuration list for PBXNativeTarget "ZKBanner" */;
141 | buildPhases = (
142 | A4387C581D89356D00BDB11A /* Sources */,
143 | A4387C591D89356D00BDB11A /* Frameworks */,
144 | A4387C5A1D89356D00BDB11A /* Resources */,
145 | );
146 | buildRules = (
147 | );
148 | dependencies = (
149 | );
150 | name = ZKBanner;
151 | productName = ZKBanner;
152 | productReference = A4387CAF1D89361400BDB11A /* ZKBanner.app */;
153 | productType = "com.apple.product-type.application";
154 | };
155 | A4387C741D89356D00BDB11A /* ZKBannerTests */ = {
156 | isa = PBXNativeTarget;
157 | buildConfigurationList = A4387C8C1D89356D00BDB11A /* Build configuration list for PBXNativeTarget "ZKBannerTests" */;
158 | buildPhases = (
159 | A4387C711D89356D00BDB11A /* Sources */,
160 | A4387C721D89356D00BDB11A /* Frameworks */,
161 | A4387C731D89356D00BDB11A /* Resources */,
162 | );
163 | buildRules = (
164 | );
165 | dependencies = (
166 | A4387C771D89356D00BDB11A /* PBXTargetDependency */,
167 | );
168 | name = ZKBannerTests;
169 | productName = ZKBannerTests;
170 | productReference = A4387CB01D89361400BDB11A /* ZKBannerTests.xctest */;
171 | productType = "com.apple.product-type.bundle.unit-test";
172 | };
173 | A4387C7F1D89356D00BDB11A /* ZKBannerUITests */ = {
174 | isa = PBXNativeTarget;
175 | buildConfigurationList = A4387C8F1D89356D00BDB11A /* Build configuration list for PBXNativeTarget "ZKBannerUITests" */;
176 | buildPhases = (
177 | A4387C7C1D89356D00BDB11A /* Sources */,
178 | A4387C7D1D89356D00BDB11A /* Frameworks */,
179 | A4387C7E1D89356D00BDB11A /* Resources */,
180 | );
181 | buildRules = (
182 | );
183 | dependencies = (
184 | A4387C821D89356D00BDB11A /* PBXTargetDependency */,
185 | );
186 | name = ZKBannerUITests;
187 | productName = ZKBannerUITests;
188 | productReference = A4387CB11D89361400BDB11A /* ZKBannerUITests.xctest */;
189 | productType = "com.apple.product-type.bundle.ui-testing";
190 | };
191 | /* End PBXNativeTarget section */
192 |
193 | /* Begin PBXProject section */
194 | A4387C541D89356D00BDB11A /* Project object */ = {
195 | isa = PBXProject;
196 | attributes = {
197 | LastUpgradeCheck = 0730;
198 | ORGANIZATIONNAME = Cain;
199 | TargetAttributes = {
200 | A4387C5B1D89356D00BDB11A = {
201 | CreatedOnToolsVersion = 7.3.1;
202 | DevelopmentTeam = 8G79A736F5;
203 | };
204 | A4387C741D89356D00BDB11A = {
205 | CreatedOnToolsVersion = 7.3.1;
206 | DevelopmentTeam = 8G79A736F5;
207 | TestTargetID = A4387C5B1D89356D00BDB11A;
208 | };
209 | A4387C7F1D89356D00BDB11A = {
210 | CreatedOnToolsVersion = 7.3.1;
211 | DevelopmentTeam = 8G79A736F5;
212 | TestTargetID = A4387C5B1D89356D00BDB11A;
213 | };
214 | };
215 | };
216 | buildConfigurationList = A4387C571D89356D00BDB11A /* Build configuration list for PBXProject "ZKBanner" */;
217 | compatibilityVersion = "Xcode 3.2";
218 | developmentRegion = English;
219 | hasScannedForEncodings = 0;
220 | knownRegions = (
221 | en,
222 | Base,
223 | );
224 | mainGroup = A4387C531D89356D00BDB11A;
225 | productRefGroup = A4387C531D89356D00BDB11A;
226 | projectDirPath = "";
227 | projectRoot = "";
228 | targets = (
229 | A4387C5B1D89356D00BDB11A /* ZKBanner */,
230 | A4387C741D89356D00BDB11A /* ZKBannerTests */,
231 | A4387C7F1D89356D00BDB11A /* ZKBannerUITests */,
232 | );
233 | };
234 | /* End PBXProject section */
235 |
236 | /* Begin PBXResourcesBuildPhase section */
237 | A4387C5A1D89356D00BDB11A /* Resources */ = {
238 | isa = PBXResourcesBuildPhase;
239 | buildActionMask = 2147483647;
240 | files = (
241 | );
242 | runOnlyForDeploymentPostprocessing = 0;
243 | };
244 | A4387C731D89356D00BDB11A /* Resources */ = {
245 | isa = PBXResourcesBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | );
249 | runOnlyForDeploymentPostprocessing = 0;
250 | };
251 | A4387C7E1D89356D00BDB11A /* Resources */ = {
252 | isa = PBXResourcesBuildPhase;
253 | buildActionMask = 2147483647;
254 | files = (
255 | );
256 | runOnlyForDeploymentPostprocessing = 0;
257 | };
258 | /* End PBXResourcesBuildPhase section */
259 |
260 | /* Begin PBXSourcesBuildPhase section */
261 | A4387C581D89356D00BDB11A /* Sources */ = {
262 | isa = PBXSourcesBuildPhase;
263 | buildActionMask = 2147483647;
264 | files = (
265 | A4387CA91D8935D900BDB11A /* TAAnimatedDotView.m in Sources */,
266 | A4387CA61D8935D900BDB11A /* NewBannerView.m in Sources */,
267 | A4387CAC1D8935D900BDB11A /* SDCollectionViewCell.m in Sources */,
268 | A4387CA81D8935D900BDB11A /* TAAbstractDotView.m in Sources */,
269 | A4387CAE1D8935D900BDB11A /* UIView+SDExtension.m in Sources */,
270 | A4387CA71D8935D900BDB11A /* NewBannerViewManager.m in Sources */,
271 | A4387CAA1D8935D900BDB11A /* TADotView.m in Sources */,
272 | A4387CAB1D8935D900BDB11A /* TAPageControl.m in Sources */,
273 | A4387CAD1D8935D900BDB11A /* SDCycleScrollView.m in Sources */,
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | };
277 | A4387C711D89356D00BDB11A /* Sources */ = {
278 | isa = PBXSourcesBuildPhase;
279 | buildActionMask = 2147483647;
280 | files = (
281 | );
282 | runOnlyForDeploymentPostprocessing = 0;
283 | };
284 | A4387C7C1D89356D00BDB11A /* Sources */ = {
285 | isa = PBXSourcesBuildPhase;
286 | buildActionMask = 2147483647;
287 | files = (
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | /* End PBXSourcesBuildPhase section */
292 |
293 | /* Begin PBXTargetDependency section */
294 | A4387C771D89356D00BDB11A /* PBXTargetDependency */ = {
295 | isa = PBXTargetDependency;
296 | target = A4387C5B1D89356D00BDB11A /* ZKBanner */;
297 | targetProxy = A4387C761D89356D00BDB11A /* PBXContainerItemProxy */;
298 | };
299 | A4387C821D89356D00BDB11A /* PBXTargetDependency */ = {
300 | isa = PBXTargetDependency;
301 | target = A4387C5B1D89356D00BDB11A /* ZKBanner */;
302 | targetProxy = A4387C811D89356D00BDB11A /* PBXContainerItemProxy */;
303 | };
304 | /* End PBXTargetDependency section */
305 |
306 | /* Begin XCBuildConfiguration section */
307 | A4387C871D89356D00BDB11A /* Debug */ = {
308 | isa = XCBuildConfiguration;
309 | buildSettings = {
310 | ALWAYS_SEARCH_USER_PATHS = NO;
311 | CLANG_ANALYZER_NONNULL = YES;
312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
313 | CLANG_CXX_LIBRARY = "libc++";
314 | CLANG_ENABLE_MODULES = YES;
315 | CLANG_ENABLE_OBJC_ARC = YES;
316 | CLANG_WARN_BOOL_CONVERSION = YES;
317 | CLANG_WARN_CONSTANT_CONVERSION = YES;
318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
319 | CLANG_WARN_EMPTY_BODY = YES;
320 | CLANG_WARN_ENUM_CONVERSION = YES;
321 | CLANG_WARN_INT_CONVERSION = YES;
322 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
323 | CLANG_WARN_UNREACHABLE_CODE = YES;
324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
326 | COPY_PHASE_STRIP = NO;
327 | DEBUG_INFORMATION_FORMAT = dwarf;
328 | ENABLE_STRICT_OBJC_MSGSEND = YES;
329 | ENABLE_TESTABILITY = YES;
330 | GCC_C_LANGUAGE_STANDARD = gnu99;
331 | GCC_DYNAMIC_NO_PIC = NO;
332 | GCC_NO_COMMON_BLOCKS = YES;
333 | GCC_OPTIMIZATION_LEVEL = 0;
334 | GCC_PREPROCESSOR_DEFINITIONS = (
335 | "DEBUG=1",
336 | "$(inherited)",
337 | );
338 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
339 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
340 | GCC_WARN_UNDECLARED_SELECTOR = YES;
341 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
342 | GCC_WARN_UNUSED_FUNCTION = YES;
343 | GCC_WARN_UNUSED_VARIABLE = YES;
344 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
345 | MTL_ENABLE_DEBUG_INFO = YES;
346 | ONLY_ACTIVE_ARCH = YES;
347 | SDKROOT = iphoneos;
348 | };
349 | name = Debug;
350 | };
351 | A4387C881D89356D00BDB11A /* Release */ = {
352 | isa = XCBuildConfiguration;
353 | buildSettings = {
354 | ALWAYS_SEARCH_USER_PATHS = NO;
355 | CLANG_ANALYZER_NONNULL = YES;
356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
357 | CLANG_CXX_LIBRARY = "libc++";
358 | CLANG_ENABLE_MODULES = YES;
359 | CLANG_ENABLE_OBJC_ARC = YES;
360 | CLANG_WARN_BOOL_CONVERSION = YES;
361 | CLANG_WARN_CONSTANT_CONVERSION = YES;
362 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
363 | CLANG_WARN_EMPTY_BODY = YES;
364 | CLANG_WARN_ENUM_CONVERSION = YES;
365 | CLANG_WARN_INT_CONVERSION = YES;
366 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
367 | CLANG_WARN_UNREACHABLE_CODE = YES;
368 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
369 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
370 | COPY_PHASE_STRIP = NO;
371 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
372 | ENABLE_NS_ASSERTIONS = NO;
373 | ENABLE_STRICT_OBJC_MSGSEND = YES;
374 | GCC_C_LANGUAGE_STANDARD = gnu99;
375 | GCC_NO_COMMON_BLOCKS = YES;
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
383 | MTL_ENABLE_DEBUG_INFO = NO;
384 | SDKROOT = iphoneos;
385 | VALIDATE_PRODUCT = YES;
386 | };
387 | name = Release;
388 | };
389 | A4387C8A1D89356D00BDB11A /* Debug */ = {
390 | isa = XCBuildConfiguration;
391 | buildSettings = {
392 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
393 | INFOPLIST_FILE = ZKBanner/Info.plist;
394 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
395 | PRODUCT_BUNDLE_IDENTIFIER = WZK.ZKBanner;
396 | PRODUCT_NAME = "$(TARGET_NAME)";
397 | };
398 | name = Debug;
399 | };
400 | A4387C8B1D89356D00BDB11A /* Release */ = {
401 | isa = XCBuildConfiguration;
402 | buildSettings = {
403 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
404 | INFOPLIST_FILE = ZKBanner/Info.plist;
405 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
406 | PRODUCT_BUNDLE_IDENTIFIER = WZK.ZKBanner;
407 | PRODUCT_NAME = "$(TARGET_NAME)";
408 | };
409 | name = Release;
410 | };
411 | A4387C8D1D89356D00BDB11A /* Debug */ = {
412 | isa = XCBuildConfiguration;
413 | buildSettings = {
414 | BUNDLE_LOADER = "$(TEST_HOST)";
415 | INFOPLIST_FILE = ZKBannerTests/Info.plist;
416 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
417 | PRODUCT_BUNDLE_IDENTIFIER = WZK.ZKBannerTests;
418 | PRODUCT_NAME = "$(TARGET_NAME)";
419 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ZKBanner.app/ZKBanner";
420 | };
421 | name = Debug;
422 | };
423 | A4387C8E1D89356D00BDB11A /* Release */ = {
424 | isa = XCBuildConfiguration;
425 | buildSettings = {
426 | BUNDLE_LOADER = "$(TEST_HOST)";
427 | INFOPLIST_FILE = ZKBannerTests/Info.plist;
428 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
429 | PRODUCT_BUNDLE_IDENTIFIER = WZK.ZKBannerTests;
430 | PRODUCT_NAME = "$(TARGET_NAME)";
431 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ZKBanner.app/ZKBanner";
432 | };
433 | name = Release;
434 | };
435 | A4387C901D89356D00BDB11A /* Debug */ = {
436 | isa = XCBuildConfiguration;
437 | buildSettings = {
438 | INFOPLIST_FILE = ZKBannerUITests/Info.plist;
439 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
440 | PRODUCT_BUNDLE_IDENTIFIER = WZK.ZKBannerUITests;
441 | PRODUCT_NAME = "$(TARGET_NAME)";
442 | TEST_TARGET_NAME = ZKBanner;
443 | };
444 | name = Debug;
445 | };
446 | A4387C911D89356D00BDB11A /* Release */ = {
447 | isa = XCBuildConfiguration;
448 | buildSettings = {
449 | INFOPLIST_FILE = ZKBannerUITests/Info.plist;
450 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
451 | PRODUCT_BUNDLE_IDENTIFIER = WZK.ZKBannerUITests;
452 | PRODUCT_NAME = "$(TARGET_NAME)";
453 | TEST_TARGET_NAME = ZKBanner;
454 | };
455 | name = Release;
456 | };
457 | /* End XCBuildConfiguration section */
458 |
459 | /* Begin XCConfigurationList section */
460 | A4387C571D89356D00BDB11A /* Build configuration list for PBXProject "ZKBanner" */ = {
461 | isa = XCConfigurationList;
462 | buildConfigurations = (
463 | A4387C871D89356D00BDB11A /* Debug */,
464 | A4387C881D89356D00BDB11A /* Release */,
465 | );
466 | defaultConfigurationIsVisible = 0;
467 | defaultConfigurationName = Release;
468 | };
469 | A4387C891D89356D00BDB11A /* Build configuration list for PBXNativeTarget "ZKBanner" */ = {
470 | isa = XCConfigurationList;
471 | buildConfigurations = (
472 | A4387C8A1D89356D00BDB11A /* Debug */,
473 | A4387C8B1D89356D00BDB11A /* Release */,
474 | );
475 | defaultConfigurationIsVisible = 0;
476 | defaultConfigurationName = Release;
477 | };
478 | A4387C8C1D89356D00BDB11A /* Build configuration list for PBXNativeTarget "ZKBannerTests" */ = {
479 | isa = XCConfigurationList;
480 | buildConfigurations = (
481 | A4387C8D1D89356D00BDB11A /* Debug */,
482 | A4387C8E1D89356D00BDB11A /* Release */,
483 | );
484 | defaultConfigurationIsVisible = 0;
485 | defaultConfigurationName = Release;
486 | };
487 | A4387C8F1D89356D00BDB11A /* Build configuration list for PBXNativeTarget "ZKBannerUITests" */ = {
488 | isa = XCConfigurationList;
489 | buildConfigurations = (
490 | A4387C901D89356D00BDB11A /* Debug */,
491 | A4387C911D89356D00BDB11A /* Release */,
492 | );
493 | defaultConfigurationIsVisible = 0;
494 | defaultConfigurationName = Release;
495 | };
496 | /* End XCConfigurationList section */
497 | };
498 | rootObject = A4387C541D89356D00BDB11A /* Project object */;
499 | }
500 |
--------------------------------------------------------------------------------
/ZKBanner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ZKBanner.xcodeproj/project.xcworkspace/xcuserdata/cain.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cainvan/react-native-zkbanner/20412cb42c5a36f0a1d5a56678032ca9877974da/ZKBanner.xcodeproj/project.xcworkspace/xcuserdata/cain.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZKBanner.xcodeproj/xcuserdata/cain.xcuserdatad/xcschemes/ZKBanner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/ZKBanner.xcodeproj/xcuserdata/cain.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZKBanner.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A4387C5B1D89356D00BDB11A
16 |
17 | primary
18 |
19 |
20 | A4387C741D89356D00BDB11A
21 |
22 | primary
23 |
24 |
25 | A4387C7F1D89356D00BDB11A
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ZKBanner/NewBannerView.h:
--------------------------------------------------------------------------------
1 | //
2 | // newBannerView.h
3 | // NativeView
4 | //
5 | // Created by Cain on 16/9/13.
6 | // Copyright © 2016年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "SDCycleScrollView.h"
10 |
11 | #import "RCTComponent.h"
12 | #import "UIView+React.h"
13 |
14 | @interface NewBannerView : SDCycleScrollView
15 |
16 | @property (nonatomic, copy) RCTBubblingEventBlock onClickBanner;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ZKBanner/NewBannerView.m:
--------------------------------------------------------------------------------
1 | //
2 | // newBannerView.m
3 | // NativeView
4 | //
5 | // Created by Cain on 16/9/13.
6 | // Copyright © 2016年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "NewBannerView.h"
10 |
11 | @implementation NewBannerView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ZKBanner/NewBannerViewManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // newBannerViewManager.h
3 | // NativeView
4 | //
5 | // Created by Cain on 16/9/13.
6 | // Copyright © 2016年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "RCTViewManager.h"
10 |
11 | @interface NewBanner : RCTViewManager
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ZKBanner/NewBannerViewManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // newBannerViewManager.m
3 | // NativeView
4 | //
5 | // Created by Cain on 16/9/13.
6 | // Copyright © 2016年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "NewBannerViewManager.h"
10 | #import "NewBannerView.h"
11 |
12 | #import "RCTBridge.h" //进行通信的头文件
13 | #import "RCTEventDispatcher.h" //事件派发,不导入会引起Xcode警告
14 |
15 | @interface NewBanner()
16 |
17 | @end
18 |
19 | @implementation NewBanner
20 |
21 | RCT_EXPORT_MODULE()
22 |
23 | RCT_EXPORT_VIEW_PROPERTY(autoScrollTimeInterval, CGFloat);
24 |
25 | RCT_EXPORT_VIEW_PROPERTY(imageURLStringsGroup, NSArray);
26 |
27 | RCT_EXPORT_VIEW_PROPERTY(autoScroll, BOOL);
28 |
29 | RCT_EXPORT_VIEW_PROPERTY(pageControlAliment, NSInteger);
30 |
31 | RCT_EXPORT_VIEW_PROPERTY(onClickBanner, RCTBubblingEventBlock);
32 |
33 | RCT_EXPORT_VIEW_PROPERTY(localizationImageNamesGroup, NSArray);
34 |
35 | - (UIView *)view
36 | {
37 | NewBannerView *bannerScrollView = [NewBannerView cycleScrollViewWithFrame:CGRectZero delegate:self placeholderImage:nil];
38 | bannerScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleClassic;
39 | bannerScrollView.pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
40 | return bannerScrollView;
41 | }
42 |
43 | #pragma mark SDCycleScrollViewDelegate
44 |
45 | //- (NSArray *) customDirectEventTypes {
46 | // return @[@"onClickBanner"];
47 | //}
48 |
49 | /**
50 | * banner点击
51 | */
52 | - (void)cycleScrollView:(NewBannerView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index{
53 |
54 | if (!cycleScrollView.onClickBanner) {
55 | return;
56 | }
57 |
58 | NSLog(@"oc did click %li", [cycleScrollView.reactTag integerValue]);
59 |
60 | cycleScrollView.onClickBanner(@{@"target": cycleScrollView.reactTag,
61 | @"value": [NSNumber numberWithInteger:index+1]});
62 |
63 | }
64 |
65 | //- (NSDictionary *)constantsToExport{
66 | // return @{
67 | // @"SDCycleScrollViewPageContolAliment": @{
68 | // @"right": @(SDCycleScrollViewPageContolAlimentRight),
69 | // @"center": @(SDCycleScrollViewPageContolAlimentCenter)
70 | // }
71 | // };
72 | //}
73 | //
74 | //RCT_EXPORT_METHOD(testResetTime:(RCTResponseSenderBlock)callback) {
75 | //
76 | // callback(@[@(234)]);
77 | //}
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TAAbstractDotView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TAAbstractDotView.h
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-22.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface TAAbstractDotView : UIView
13 |
14 |
15 | /**
16 | * A method call let view know which state appearance it should take. Active meaning it's current page. Inactive not the current page.
17 | *
18 | * @param active BOOL to tell if view is active or not
19 | */
20 | - (void)changeActivityState:(BOOL)active;
21 |
22 |
23 | @end
24 |
25 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TAAbstractDotView.m:
--------------------------------------------------------------------------------
1 | //
2 | // TAAbstractDotView.m
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-22.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import "TAAbstractDotView.h"
10 |
11 |
12 | @implementation TAAbstractDotView
13 |
14 |
15 | - (id)init
16 | {
17 | @throw [NSException exceptionWithName:NSInternalInconsistencyException
18 | reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
19 | userInfo:nil];
20 | }
21 |
22 |
23 | - (void)changeActivityState:(BOOL)active
24 | {
25 | @throw [NSException exceptionWithName:NSInternalInconsistencyException
26 | reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
27 | userInfo:nil];
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TAAnimatedDotView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TAAnimatedDotView.h
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-22.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import "TAAbstractDotView.h"
10 |
11 | @interface TAAnimatedDotView : TAAbstractDotView
12 |
13 | @property (nonatomic, strong) UIColor *dotColor;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TAAnimatedDotView.m:
--------------------------------------------------------------------------------
1 | //
2 | // TAAnimatedDotView.m
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-22.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import "TAAnimatedDotView.h"
10 |
11 | static CGFloat const kAnimateDuration = 1;
12 |
13 | @implementation TAAnimatedDotView
14 |
15 | - (instancetype)init
16 | {
17 | self = [super init];
18 | if (self) {
19 | [self initialization];
20 | }
21 |
22 | return self;
23 | }
24 |
25 |
26 | - (id)initWithFrame:(CGRect)frame
27 | {
28 | self = [super initWithFrame:frame];
29 | if (self) {
30 | [self initialization];
31 | }
32 | return self;
33 | }
34 |
35 |
36 | - (id)initWithCoder:(NSCoder *)aDecoder
37 | {
38 | self = [super initWithCoder:aDecoder];
39 | if (self) {
40 | [self initialization];
41 | }
42 |
43 | return self;
44 | }
45 |
46 | - (void)setDotColor:(UIColor *)dotColor
47 | {
48 | _dotColor = dotColor;
49 | self.layer.borderColor = dotColor.CGColor;
50 | }
51 |
52 | - (void)initialization
53 | {
54 | _dotColor = [UIColor whiteColor];
55 | self.backgroundColor = [UIColor clearColor];
56 | self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2;
57 | self.layer.borderColor = [UIColor whiteColor].CGColor;
58 | self.layer.borderWidth = 2;
59 | }
60 |
61 |
62 | - (void)changeActivityState:(BOOL)active
63 | {
64 | if (active) {
65 | [self animateToActiveState];
66 | } else {
67 | [self animateToDeactiveState];
68 | }
69 | }
70 |
71 |
72 | - (void)animateToActiveState
73 | {
74 | [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:-20 options:UIViewAnimationOptionCurveLinear animations:^{
75 | self.backgroundColor = _dotColor;
76 | self.transform = CGAffineTransformMakeScale(1.4, 1.4);
77 | } completion:nil];
78 | }
79 |
80 | - (void)animateToDeactiveState
81 | {
82 | [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
83 | self.backgroundColor = [UIColor clearColor];
84 | self.transform = CGAffineTransformIdentity;
85 | } completion:nil];
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TADotView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TADotView.h
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-22.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import "TAAbstractDotView.h"
10 |
11 | @interface TADotView : TAAbstractDotView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TADotView.m:
--------------------------------------------------------------------------------
1 | //
2 | // TADotView.m
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-22.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import "TADotView.h"
10 |
11 | @implementation TADotView
12 |
13 |
14 | - (instancetype)init
15 | {
16 | self = [super init];
17 | if (self) {
18 | [self initialization];
19 | }
20 |
21 | return self;
22 | }
23 |
24 |
25 | - (id)initWithFrame:(CGRect)frame
26 | {
27 | self = [super initWithFrame:frame];
28 | if (self) {
29 | [self initialization];
30 | }
31 | return self;
32 | }
33 |
34 |
35 | - (id)initWithCoder:(NSCoder *)aDecoder
36 | {
37 | self = [super initWithCoder:aDecoder];
38 | if (self) {
39 | [self initialization];
40 | }
41 |
42 | return self;
43 | }
44 |
45 | - (void)initialization
46 | {
47 | self.backgroundColor = [UIColor clearColor];
48 | self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2;
49 | self.layer.borderColor = [UIColor whiteColor].CGColor;
50 | self.layer.borderWidth = 2;
51 | }
52 |
53 |
54 | - (void)changeActivityState:(BOOL)active
55 | {
56 | if (active) {
57 | self.backgroundColor = [UIColor whiteColor];
58 | } else {
59 | self.backgroundColor = [UIColor clearColor];
60 | }
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TAPageControl.h:
--------------------------------------------------------------------------------
1 | //
2 | // TAPageControl.h
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-21.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol TAPageControlDelegate;
12 |
13 |
14 | @interface TAPageControl : UIControl
15 |
16 |
17 | /**
18 | * Dot view customization properties
19 | */
20 |
21 | /**
22 | * The Class of your custom UIView, make sure to respect the TAAbstractDotView class.
23 | */
24 | @property (nonatomic) Class dotViewClass;
25 |
26 |
27 | /**
28 | * UIImage to represent a dot.
29 | */
30 | @property (nonatomic) UIImage *dotImage;
31 |
32 |
33 | /**
34 | * UIImage to represent current page dot.
35 | */
36 | @property (nonatomic) UIImage *currentDotImage;
37 |
38 |
39 | /**
40 | * Dot size for dot views. Default is 8 by 8.
41 | */
42 | @property (nonatomic) CGSize dotSize;
43 |
44 |
45 | @property (nonatomic, strong) UIColor *dotColor;
46 |
47 | /**
48 | * Spacing between two dot views. Default is 8.
49 | */
50 | @property (nonatomic) NSInteger spacingBetweenDots;
51 |
52 |
53 | /**
54 | * Page control setup properties
55 | */
56 |
57 |
58 | /**
59 | * Delegate for TAPageControl
60 | */
61 | @property(nonatomic,assign) id delegate;
62 |
63 |
64 | /**
65 | * Number of pages for control. Default is 0.
66 | */
67 | @property (nonatomic) NSInteger numberOfPages;
68 |
69 |
70 | /**
71 | * Current page on which control is active. Default is 0.
72 | */
73 | @property (nonatomic) NSInteger currentPage;
74 |
75 |
76 | /**
77 | * Hide the control if there is only one page. Default is NO.
78 | */
79 | @property (nonatomic) BOOL hidesForSinglePage;
80 |
81 |
82 | /**
83 | * Let the control know if should grow bigger by keeping center, or just get longer (right side expanding). By default YES.
84 | */
85 | @property (nonatomic) BOOL shouldResizeFromCenter;
86 |
87 |
88 | /**
89 | * Return the minimum size required to display control properly for the given page count.
90 | *
91 | * @param pageCount Number of dots that will require display
92 | *
93 | * @return The CGSize being the minimum size required.
94 | */
95 | - (CGSize)sizeForNumberOfPages:(NSInteger)pageCount;
96 |
97 |
98 | @end
99 |
100 |
101 | @protocol TAPageControlDelegate
102 |
103 | @optional
104 | - (void)TAPageControl:(TAPageControl *)pageControl didSelectPageAtIndex:(NSInteger)index;
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/PageControl/TAPageControl.m:
--------------------------------------------------------------------------------
1 | //
2 | // TAPageControl.m
3 | // TAPageControl
4 | //
5 | // Created by Tanguy Aladenise on 2015-01-21.
6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
7 | //
8 |
9 | #import "TAPageControl.h"
10 | #import "TAAbstractDotView.h"
11 | #import "TAAnimatedDotView.h"
12 | #import "TADotView.h"
13 |
14 | /**
15 | * Default number of pages for initialization
16 | */
17 | static NSInteger const kDefaultNumberOfPages = 0;
18 |
19 | /**
20 | * Default current page for initialization
21 | */
22 | static NSInteger const kDefaultCurrentPage = 0;
23 |
24 | /**
25 | * Default setting for hide for single page feature. For initialization
26 | */
27 | static BOOL const kDefaultHideForSinglePage = NO;
28 |
29 | /**
30 | * Default setting for shouldResizeFromCenter. For initialiation
31 | */
32 | static BOOL const kDefaultShouldResizeFromCenter = YES;
33 |
34 | /**
35 | * Default spacing between dots
36 | */
37 | static NSInteger const kDefaultSpacingBetweenDots = 8;
38 |
39 | /**
40 | * Default dot size
41 | */
42 | static CGSize const kDefaultDotSize = {8, 8};
43 |
44 |
45 | @interface TAPageControl()
46 |
47 |
48 | /**
49 | * Array of dot views for reusability and touch events.
50 | */
51 | @property (strong, nonatomic) NSMutableArray *dots;
52 |
53 |
54 | @end
55 |
56 | @implementation TAPageControl
57 |
58 |
59 | #pragma mark - Lifecycle
60 |
61 |
62 | - (id)init
63 | {
64 | self = [super init];
65 | if (self) {
66 | [self initialization];
67 | }
68 |
69 | return self;
70 | }
71 |
72 |
73 | - (id)initWithFrame:(CGRect)frame
74 | {
75 | self = [super initWithFrame:frame];
76 | if (self) {
77 | [self initialization];
78 | }
79 | return self;
80 | }
81 |
82 |
83 | - (id)initWithCoder:(NSCoder *)aDecoder
84 | {
85 | self = [super initWithCoder:aDecoder];
86 | if (self) {
87 | [self initialization];
88 | }
89 |
90 | return self;
91 | }
92 |
93 |
94 | /**
95 | * Default setup when initiating control
96 | */
97 | - (void)initialization
98 | {
99 | self.dotViewClass = [TAAnimatedDotView class];
100 | self.spacingBetweenDots = kDefaultSpacingBetweenDots;
101 | self.numberOfPages = kDefaultNumberOfPages;
102 | self.currentPage = kDefaultCurrentPage;
103 | self.hidesForSinglePage = kDefaultHideForSinglePage;
104 | self.shouldResizeFromCenter = kDefaultShouldResizeFromCenter;
105 | }
106 |
107 |
108 | #pragma mark - Touch event
109 |
110 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
111 | {
112 | UITouch *touch = [touches anyObject];
113 | if (touch.view != self) {
114 | NSInteger index = [self.dots indexOfObject:touch.view];
115 | if ([self.delegate respondsToSelector:@selector(TAPageControl:didSelectPageAtIndex:)]) {
116 | [self.delegate TAPageControl:self didSelectPageAtIndex:index];
117 | }
118 | }
119 | }
120 |
121 | #pragma mark - Layout
122 |
123 |
124 | /**
125 | * Resizes and moves the receiver view so it just encloses its subviews.
126 | */
127 | - (void)sizeToFit
128 | {
129 | [self updateFrame:YES];
130 | }
131 |
132 |
133 | - (CGSize)sizeForNumberOfPages:(NSInteger)pageCount
134 | {
135 | return CGSizeMake((self.dotSize.width + self.spacingBetweenDots) * pageCount - self.spacingBetweenDots , self.dotSize.height);
136 | }
137 |
138 |
139 | /**
140 | * Will update dots display and frame. Reuse existing views or instantiate one if required. Update their position in case frame changed.
141 | */
142 | - (void)updateDots
143 | {
144 | if (self.numberOfPages == 0) {
145 | return;
146 | }
147 |
148 | for (NSInteger i = 0; i < self.numberOfPages; i++) {
149 |
150 | UIView *dot;
151 | if (i < self.dots.count) {
152 | dot = [self.dots objectAtIndex:i];
153 | } else {
154 | dot = [self generateDotView];
155 | }
156 |
157 | [self updateDotFrame:dot atIndex:i];
158 | }
159 |
160 | [self changeActivity:YES atIndex:self.currentPage];
161 |
162 | [self hideForSinglePage];
163 | }
164 |
165 |
166 | /**
167 | * Update frame control to fit current number of pages. It will apply required size if authorize and required.
168 | *
169 | * @param overrideExistingFrame BOOL to allow frame to be overriden. Meaning the required size will be apply no mattter what.
170 | */
171 | - (void)updateFrame:(BOOL)overrideExistingFrame
172 | {
173 | CGPoint center = self.center;
174 | CGSize requiredSize = [self sizeForNumberOfPages:self.numberOfPages];
175 |
176 | // We apply requiredSize only if authorize to and necessary
177 | if (overrideExistingFrame || ((CGRectGetWidth(self.frame) < requiredSize.width || CGRectGetHeight(self.frame) < requiredSize.height) && !overrideExistingFrame)) {
178 | self.frame = CGRectMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame), requiredSize.width, requiredSize.height);
179 | if (self.shouldResizeFromCenter) {
180 | self.center = center;
181 | }
182 | }
183 |
184 | [self resetDotViews];
185 | }
186 |
187 |
188 | /**
189 | * Update the frame of a specific dot at a specific index
190 | *
191 | * @param dot Dot view
192 | * @param index Page index of dot
193 | */
194 | - (void)updateDotFrame:(UIView *)dot atIndex:(NSInteger)index
195 | {
196 | // Dots are always centered within view
197 | CGFloat x = (self.dotSize.width + self.spacingBetweenDots) * index + ( (CGRectGetWidth(self.frame) - [self sizeForNumberOfPages:self.numberOfPages].width) / 2);
198 | CGFloat y = (CGRectGetHeight(self.frame) - self.dotSize.height) / 2;
199 |
200 | dot.frame = CGRectMake(x, y, self.dotSize.width, self.dotSize.height);
201 | }
202 |
203 |
204 | #pragma mark - Utils
205 |
206 |
207 | /**
208 | * Generate a dot view and add it to the collection
209 | *
210 | * @return The UIView object representing a dot
211 | */
212 | - (UIView *)generateDotView
213 | {
214 | UIView *dotView;
215 |
216 | if (self.dotViewClass) {
217 | dotView = [[self.dotViewClass alloc] initWithFrame:CGRectMake(0, 0, self.dotSize.width, self.dotSize.height)];
218 | if ([dotView isKindOfClass:[TAAnimatedDotView class]] && self.dotColor) {
219 | ((TAAnimatedDotView *)dotView).dotColor = self.dotColor;
220 | }
221 | } else {
222 | dotView = [[UIImageView alloc] initWithImage:self.dotImage];
223 | dotView.frame = CGRectMake(0, 0, self.dotSize.width, self.dotSize.height);
224 | }
225 |
226 | if (dotView) {
227 | [self addSubview:dotView];
228 | [self.dots addObject:dotView];
229 | }
230 |
231 | dotView.userInteractionEnabled = YES;
232 | return dotView;
233 | }
234 |
235 |
236 | /**
237 | * Change activity state of a dot view. Current/not currrent.
238 | *
239 | * @param active Active state to apply
240 | * @param index Index of dot for state update
241 | */
242 | - (void)changeActivity:(BOOL)active atIndex:(NSInteger)index
243 | {
244 | if (self.dotViewClass) {
245 | TAAbstractDotView *abstractDotView = (TAAbstractDotView *)[self.dots objectAtIndex:index];
246 | if ([abstractDotView respondsToSelector:@selector(changeActivityState:)]) {
247 | [abstractDotView changeActivityState:active];
248 | } else {
249 | NSLog(@"Custom view : %@ must implement an 'changeActivityState' method or you can subclass %@ to help you.", self.dotViewClass, [TAAbstractDotView class]);
250 | }
251 | } else if (self.dotImage && self.currentDotImage) {
252 | UIImageView *dotView = (UIImageView *)[self.dots objectAtIndex:index];
253 | dotView.image = (active) ? self.currentDotImage : self.dotImage;
254 | }
255 | }
256 |
257 |
258 | - (void)resetDotViews
259 | {
260 | for (UIView *dotView in self.dots) {
261 | [dotView removeFromSuperview];
262 | }
263 |
264 | [self.dots removeAllObjects];
265 | [self updateDots];
266 | }
267 |
268 |
269 | - (void)hideForSinglePage
270 | {
271 | if (self.dots.count == 1 && self.hidesForSinglePage) {
272 | self.hidden = YES;
273 | } else {
274 | self.hidden = NO;
275 | }
276 | }
277 |
278 | #pragma mark - Setters
279 |
280 |
281 | - (void)setNumberOfPages:(NSInteger)numberOfPages
282 | {
283 | _numberOfPages = numberOfPages;
284 |
285 | // Update dot position to fit new number of pages
286 | [self resetDotViews];
287 | }
288 |
289 |
290 | - (void)setSpacingBetweenDots:(NSInteger)spacingBetweenDots
291 | {
292 | _spacingBetweenDots = spacingBetweenDots;
293 |
294 | [self resetDotViews];
295 | }
296 |
297 |
298 | - (void)setCurrentPage:(NSInteger)currentPage
299 | {
300 | // If no pages, no current page to treat.
301 | if (self.numberOfPages == 0 || currentPage == _currentPage) {
302 | _currentPage = currentPage;
303 | return;
304 | }
305 |
306 | // Pre set
307 | [self changeActivity:NO atIndex:_currentPage];
308 | _currentPage = currentPage;
309 | // Post set
310 | [self changeActivity:YES atIndex:_currentPage];
311 | }
312 |
313 |
314 | - (void)setDotImage:(UIImage *)dotImage
315 | {
316 | _dotImage = dotImage;
317 | [self resetDotViews];
318 | self.dotViewClass = nil;
319 | }
320 |
321 |
322 | - (void)setCurrentDotImage:(UIImage *)currentDotimage
323 | {
324 | _currentDotImage = currentDotimage;
325 | [self resetDotViews];
326 | self.dotViewClass = nil;
327 | }
328 |
329 |
330 | - (void)setDotViewClass:(Class)dotViewClass
331 | {
332 | _dotViewClass = dotViewClass;
333 | self.dotSize = CGSizeZero;
334 | [self resetDotViews];
335 | }
336 |
337 |
338 | #pragma mark - Getters
339 |
340 |
341 | - (NSMutableArray *)dots
342 | {
343 | if (!_dots) {
344 | _dots = [[NSMutableArray alloc] init];
345 | }
346 |
347 | return _dots;
348 | }
349 |
350 |
351 | - (CGSize)dotSize
352 | {
353 | // Dot size logic depending on the source of the dot view
354 | if (self.dotImage && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
355 | _dotSize = self.dotImage.size;
356 | } else if (self.dotViewClass && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
357 | _dotSize = kDefaultDotSize;
358 | return _dotSize;
359 | }
360 |
361 | return _dotSize;
362 | }
363 |
364 | @end
365 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/SDCollectionViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // SDCollectionViewCell.h
3 | // SDCycleScrollView
4 | //
5 | // Created by aier on 15-3-22.
6 | // Copyright (c) 2015年 GSD. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 |
12 | @interface SDCollectionViewCell : UICollectionViewCell
13 |
14 | @property (weak, nonatomic) UIImageView *imageView;
15 | @property (copy, nonatomic) NSString *title;
16 |
17 | @property (nonatomic, strong) UIColor *titleLabelTextColor;
18 | @property (nonatomic, strong) UIFont *titleLabelTextFont;
19 | @property (nonatomic, strong) UIColor *titleLabelBackgroundColor;
20 | @property (nonatomic, assign) CGFloat titleLabelHeight;
21 |
22 | @property (nonatomic, assign) BOOL hasConfigured;
23 |
24 | /** 只展示文字轮播 */
25 | @property (nonatomic, assign) BOOL onlyDisplayText;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/SDCollectionViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDCollectionViewCell.m
3 | // SDCycleScrollView
4 | //
5 | // Created by aier on 15-3-22.
6 | // Copyright (c) 2015年 GSD. All rights reserved.
7 | //
8 |
9 |
10 |
11 | #import "SDCollectionViewCell.h"
12 | #import "UIView+SDExtension.h"
13 |
14 | @implementation SDCollectionViewCell
15 | {
16 | __weak UILabel *_titleLabel;
17 | }
18 |
19 |
20 | - (instancetype)initWithFrame:(CGRect)frame
21 | {
22 | if (self = [super initWithFrame:frame]) {
23 | [self setupImageView];
24 | [self setupTitleLabel];
25 | }
26 |
27 | return self;
28 | }
29 |
30 | - (void)setTitleLabelBackgroundColor:(UIColor *)titleLabelBackgroundColor
31 | {
32 | _titleLabelBackgroundColor = titleLabelBackgroundColor;
33 | _titleLabel.backgroundColor = titleLabelBackgroundColor;
34 | }
35 |
36 | - (void)setTitleLabelTextColor:(UIColor *)titleLabelTextColor
37 | {
38 | _titleLabelTextColor = titleLabelTextColor;
39 | _titleLabel.textColor = titleLabelTextColor;
40 | }
41 |
42 | - (void)setTitleLabelTextFont:(UIFont *)titleLabelTextFont
43 | {
44 | _titleLabelTextFont = titleLabelTextFont;
45 | _titleLabel.font = titleLabelTextFont;
46 | }
47 |
48 | - (void)setupImageView
49 | {
50 | UIImageView *imageView = [[UIImageView alloc] init];
51 | _imageView = imageView;
52 | [self.contentView addSubview:imageView];
53 | }
54 |
55 | - (void)setupTitleLabel
56 | {
57 | UILabel *titleLabel = [[UILabel alloc] init];
58 | _titleLabel = titleLabel;
59 | _titleLabel.hidden = YES;
60 | [self.contentView addSubview:titleLabel];
61 | }
62 |
63 | - (void)setTitle:(NSString *)title
64 | {
65 | _title = [title copy];
66 | _titleLabel.text = [NSString stringWithFormat:@" %@", title];
67 | if (_titleLabel.hidden) {
68 | _titleLabel.hidden = NO;
69 | }
70 | }
71 |
72 |
73 | - (void)layoutSubviews
74 | {
75 | [super layoutSubviews];
76 |
77 | if (self.onlyDisplayText) {
78 | _titleLabel.frame = self.bounds;
79 | } else {
80 | _imageView.frame = self.bounds;
81 | CGFloat titleLabelW = self.sd_width;
82 | CGFloat titleLabelH = _titleLabelHeight;
83 | CGFloat titleLabelX = 0;
84 | CGFloat titleLabelY = self.sd_height - titleLabelH;
85 | _titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH);
86 | }
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/SDCycleScrollView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SDCycleScrollView.h
3 | // SDCycleScrollView
4 | //
5 | // Created by aier on 15-3-22.
6 | // Copyright (c) 2015年 GSD. All rights reserved.
7 | //
8 |
9 |
10 | /*
11 | * 当前版本为1.62
12 | * 更新日期:2016.04.21
13 | */
14 |
15 | #import
16 |
17 | typedef enum {
18 | SDCycleScrollViewPageContolAlimentRight,
19 | SDCycleScrollViewPageContolAlimentCenter
20 | } SDCycleScrollViewPageContolAliment;
21 |
22 | typedef enum {
23 | SDCycleScrollViewPageContolStyleClassic, // 系统自带经典样式
24 | SDCycleScrollViewPageContolStyleAnimated, // 动画效果pagecontrol
25 | SDCycleScrollViewPageContolStyleNone // 不显示pagecontrol
26 | } SDCycleScrollViewPageContolStyle;
27 |
28 | @class SDCycleScrollView;
29 |
30 | @protocol SDCycleScrollViewDelegate
31 |
32 | @optional
33 |
34 | /** 点击图片回调 */
35 | - (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index;
36 |
37 | /** 图片滚动回调 */
38 | - (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didScrollToIndex:(NSInteger)index;
39 |
40 | @end
41 |
42 | @interface SDCycleScrollView : UIView
43 |
44 |
45 | /** 初始轮播图(推荐使用) */
46 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame delegate:(id)delegate placeholderImage:(UIImage *)placeholderImage;
47 |
48 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageURLStringsGroup:(NSArray *)imageURLStringsGroup;
49 |
50 |
51 | /** 本地图片轮播初始化方式 */
52 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageNamesGroup:(NSArray *)imageNamesGroup;
53 |
54 | /** 本地图片轮播初始化方式2,infiniteLoop:是否无限循环 */
55 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame shouldInfiniteLoop:(BOOL)infiniteLoop imageNamesGroup:(NSArray *)imageNamesGroup;
56 |
57 |
58 | ////////////////////// 数据源接口 //////////////////////
59 |
60 | /** 网络图片 url string 数组 */
61 | @property (nonatomic, strong) NSArray *imageURLStringsGroup;
62 |
63 | /** 每张图片对应要显示的文字数组 */
64 | @property (nonatomic, strong) NSArray *titlesGroup;
65 |
66 | /** 本地图片数组 */
67 | @property (nonatomic, strong) NSArray *localizationImageNamesGroup;
68 |
69 |
70 |
71 |
72 |
73 | ////////////////////// 滚动控制接口 //////////////////////
74 |
75 | /** 自动滚动间隔时间,默认2s */
76 | @property (nonatomic, assign) CGFloat autoScrollTimeInterval;
77 |
78 | /** 是否无限循环,默认Yes */
79 | @property (nonatomic,assign) BOOL infiniteLoop;
80 |
81 | /** 是否自动滚动,默认Yes */
82 | @property (nonatomic,assign) BOOL autoScroll;
83 |
84 | /** 图片滚动方向,默认为水平滚动 */
85 | @property (nonatomic, assign) UICollectionViewScrollDirection scrollDirection;
86 |
87 | @property (nonatomic, weak) id delegate;
88 |
89 | /** block方式监听点击 */
90 | @property (nonatomic, copy) void (^clickItemOperationBlock)(NSInteger currentIndex);
91 |
92 | /** block方式监听滚动 */
93 | @property (nonatomic, copy) void (^itemDidScrollOperationBlock)(NSInteger currentIndex);
94 |
95 | /** 解决viewWillAppear时出现时轮播图卡在一半的问题,在控制器viewWillAppear时调用此方法 */
96 | - (void)adjustWhenControllerViewWillAppera;
97 |
98 | ////////////////////// 自定义样式接口 //////////////////////
99 |
100 |
101 | /** 轮播图片的ContentMode,默认为 UIViewContentModeScaleToFill */
102 | @property (nonatomic, assign) UIViewContentMode bannerImageViewContentMode;
103 |
104 | /** 占位图,用于网络未加载到图片时 */
105 | @property (nonatomic, strong) UIImage *placeholderImage;
106 |
107 | /** 是否显示分页控件 */
108 | @property (nonatomic, assign) BOOL showPageControl;
109 |
110 | /** 是否在只有一张图时隐藏pagecontrol,默认为YES */
111 | @property(nonatomic) BOOL hidesForSinglePage;
112 |
113 | /** 只展示文字轮播 */
114 | @property (nonatomic, assign) BOOL onlyDisplayText;
115 |
116 | /** pagecontrol 样式,默认为动画样式 */
117 | @property (nonatomic, assign) SDCycleScrollViewPageContolStyle pageControlStyle;
118 |
119 | /** 分页控件位置 */
120 | @property (nonatomic, assign) SDCycleScrollViewPageContolAliment pageControlAliment;
121 |
122 | /** 分页控件小圆标大小 */
123 | @property (nonatomic, assign) CGSize pageControlDotSize;
124 |
125 | /** 当前分页控件小圆标颜色 */
126 | @property (nonatomic, strong) UIColor *currentPageDotColor;
127 |
128 | /** 其他分页控件小圆标颜色 */
129 | @property (nonatomic, strong) UIColor *pageDotColor;
130 |
131 | /** 当前分页控件小圆标图片 */
132 | @property (nonatomic, strong) UIImage *currentPageDotImage;
133 |
134 | /** 其他分页控件小圆标图片 */
135 | @property (nonatomic, strong) UIImage *pageDotImage;
136 |
137 | /** 轮播文字label字体颜色 */
138 | @property (nonatomic, strong) UIColor *titleLabelTextColor;
139 |
140 | /** 轮播文字label字体大小 */
141 | @property (nonatomic, strong) UIFont *titleLabelTextFont;
142 |
143 | /** 轮播文字label背景颜色 */
144 | @property (nonatomic, strong) UIColor *titleLabelBackgroundColor;
145 |
146 | /** 轮播文字label高度 */
147 | @property (nonatomic, assign) CGFloat titleLabelHeight;
148 |
149 |
150 |
151 | ////////////////////// 清除缓存接口 //////////////////////
152 |
153 | /** 清除图片缓存(此次升级后统一使用SDWebImage管理图片加载和缓存) */
154 | + (void)clearImagesCache;
155 |
156 | /** 清除图片缓存(兼容旧版本方法) */
157 | - (void)clearCache;
158 |
159 | @end
160 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/SDCycleScrollView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDCycleScrollView.m
3 | // SDCycleScrollView
4 | //
5 | // Created by aier on 15-3-22.
6 | // Copyright (c) 2015年 GSD. All rights reserved.
7 | //
8 |
9 |
10 | #import "SDCycleScrollView.h"
11 | #import "SDCollectionViewCell.h"
12 | #import "UIView+SDExtension.h"
13 | #import "TAPageControl.h"
14 | #import "UIImageView+WebCache.h"
15 | #import "SDImageCache.h"
16 |
17 | #define kCycleScrollViewInitialPageControlDotSize CGSizeMake(10, 10)
18 |
19 | NSString * const ID = @"cycleCell";
20 |
21 | @interface SDCycleScrollView ()
22 |
23 |
24 | @property (nonatomic, weak) UICollectionView *mainView; // 显示图片的collectionView
25 | @property (nonatomic, weak) UICollectionViewFlowLayout *flowLayout;
26 | @property (nonatomic, strong) NSArray *imagePathsGroup;
27 | @property (nonatomic, weak) NSTimer *timer;
28 | @property (nonatomic, assign) NSInteger totalItemsCount;
29 | @property (nonatomic, weak) UIControl *pageControl;
30 |
31 | @property (nonatomic, strong) UIImageView *backgroundImageView; // 当imageURLs为空时的背景图
32 |
33 | @end
34 |
35 | @implementation SDCycleScrollView
36 |
37 | - (instancetype)initWithFrame:(CGRect)frame
38 | {
39 | if (self = [super initWithFrame:frame]) {
40 | [self initialization];
41 | [self setupMainView];
42 | }
43 | return self;
44 | }
45 |
46 | - (void)awakeFromNib
47 | {
48 | [self initialization];
49 | [self setupMainView];
50 | }
51 |
52 | - (void)initialization
53 | {
54 | _pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
55 | _autoScrollTimeInterval = 2.0;
56 | _titleLabelTextColor = [UIColor whiteColor];
57 | _titleLabelTextFont= [UIFont systemFontOfSize:14];
58 | _titleLabelBackgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
59 | _titleLabelHeight = 30;
60 | _autoScroll = YES;
61 | _infiniteLoop = YES;
62 | _showPageControl = YES;
63 | _pageControlDotSize = kCycleScrollViewInitialPageControlDotSize;
64 | _pageControlStyle = SDCycleScrollViewPageContolStyleClassic;
65 | _hidesForSinglePage = YES;
66 | _currentPageDotColor = [UIColor whiteColor];
67 | _pageDotColor = [UIColor lightGrayColor];
68 | _bannerImageViewContentMode = UIViewContentModeScaleToFill;
69 |
70 | self.backgroundColor = [UIColor whiteColor];
71 |
72 | }
73 |
74 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageNamesGroup:(NSArray *)imageNamesGroup
75 | {
76 | SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
77 | cycleScrollView.localizationImageNamesGroup = [NSMutableArray arrayWithArray:imageNamesGroup];
78 | return cycleScrollView;
79 | }
80 |
81 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame shouldInfiniteLoop:(BOOL)infiniteLoop imageNamesGroup:(NSArray *)imageNamesGroup
82 | {
83 | SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
84 | cycleScrollView.infiniteLoop = infiniteLoop;
85 | cycleScrollView.localizationImageNamesGroup = [NSMutableArray arrayWithArray:imageNamesGroup];
86 | return cycleScrollView;
87 | }
88 |
89 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageURLStringsGroup:(NSArray *)imageURLsGroup
90 | {
91 | SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
92 | cycleScrollView.imageURLStringsGroup = [NSMutableArray arrayWithArray:imageURLsGroup];
93 | return cycleScrollView;
94 | }
95 |
96 | + (instancetype)cycleScrollViewWithFrame:(CGRect)frame delegate:(id)delegate placeholderImage:(UIImage *)placeholderImage
97 | {
98 | SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
99 | cycleScrollView.delegate = delegate;
100 | cycleScrollView.placeholderImage = placeholderImage;
101 |
102 | return cycleScrollView;
103 | }
104 |
105 | // 设置显示图片的collectionView
106 | - (void)setupMainView
107 | {
108 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
109 | flowLayout.minimumLineSpacing = 0;
110 | flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
111 | _flowLayout = flowLayout;
112 |
113 | UICollectionView *mainView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:flowLayout];
114 | mainView.backgroundColor = [UIColor clearColor];
115 | mainView.pagingEnabled = YES;
116 | mainView.showsHorizontalScrollIndicator = NO;
117 | mainView.showsVerticalScrollIndicator = NO;
118 | [mainView registerClass:[SDCollectionViewCell class] forCellWithReuseIdentifier:ID];
119 | mainView.dataSource = self;
120 | mainView.delegate = self;
121 | mainView.scrollsToTop = NO;
122 | [self addSubview:mainView];
123 | _mainView = mainView;
124 | }
125 |
126 |
127 | #pragma mark - properties
128 |
129 | - (void)setPlaceholderImage:(UIImage *)placeholderImage
130 | {
131 | _placeholderImage = placeholderImage;
132 |
133 | if (!self.backgroundImageView) {
134 | UIImageView *bgImageView = [UIImageView new];
135 | bgImageView.contentMode = UIViewContentModeScaleAspectFit;
136 | [self insertSubview:bgImageView belowSubview:self.mainView];
137 | self.backgroundImageView = bgImageView;
138 | }
139 |
140 | self.backgroundImageView.image = placeholderImage;
141 | }
142 |
143 | - (void)setPageControlDotSize:(CGSize)pageControlDotSize
144 | {
145 | _pageControlDotSize = pageControlDotSize;
146 | [self setupPageControl];
147 | if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
148 | TAPageControl *pageContol = (TAPageControl *)_pageControl;
149 | pageContol.dotSize = pageControlDotSize;
150 | }
151 | }
152 |
153 | - (void)setShowPageControl:(BOOL)showPageControl
154 | {
155 | _showPageControl = showPageControl;
156 |
157 | _pageControl.hidden = !showPageControl;
158 | }
159 |
160 | - (void)setCurrentPageDotColor:(UIColor *)currentPageDotColor
161 | {
162 | _currentPageDotColor = currentPageDotColor;
163 | if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
164 | TAPageControl *pageControl = (TAPageControl *)_pageControl;
165 | pageControl.dotColor = currentPageDotColor;
166 | } else {
167 | UIPageControl *pageControl = (UIPageControl *)_pageControl;
168 | pageControl.currentPageIndicatorTintColor = currentPageDotColor;
169 | }
170 |
171 | }
172 |
173 | - (void)setPageDotColor:(UIColor *)pageDotColor
174 | {
175 | _pageDotColor = pageDotColor;
176 |
177 | if ([self.pageControl isKindOfClass:[UIPageControl class]]) {
178 | UIPageControl *pageControl = (UIPageControl *)_pageControl;
179 | pageControl.pageIndicatorTintColor = pageDotColor;
180 | }
181 | }
182 |
183 | - (void)setCurrentPageDotImage:(UIImage *)currentPageDotImage
184 | {
185 | _currentPageDotImage = currentPageDotImage;
186 |
187 | if (self.pageControlStyle != SDCycleScrollViewPageContolStyleAnimated) {
188 | self.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;
189 | }
190 |
191 | [self setCustomPageControlDotImage:currentPageDotImage isCurrentPageDot:YES];
192 | }
193 |
194 | - (void)setPageDotImage:(UIImage *)pageDotImage
195 | {
196 | _pageDotImage = pageDotImage;
197 |
198 | if (self.pageControlStyle != SDCycleScrollViewPageContolStyleAnimated) {
199 | self.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;
200 | }
201 |
202 | [self setCustomPageControlDotImage:pageDotImage isCurrentPageDot:NO];
203 | }
204 |
205 | - (void)setCustomPageControlDotImage:(UIImage *)image isCurrentPageDot:(BOOL)isCurrentPageDot
206 | {
207 | if (!image || !self.pageControl) return;
208 |
209 | if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
210 | TAPageControl *pageControl = (TAPageControl *)_pageControl;
211 | if (isCurrentPageDot) {
212 | pageControl.currentDotImage = image;
213 | } else {
214 | pageControl.dotImage = image;
215 | }
216 | }
217 | }
218 |
219 | - (void)setInfiniteLoop:(BOOL)infiniteLoop
220 | {
221 | _infiniteLoop = infiniteLoop;
222 |
223 | if (self.imagePathsGroup.count) {
224 | self.imagePathsGroup = self.imagePathsGroup;
225 | }
226 | }
227 |
228 | -(void)setAutoScroll:(BOOL)autoScroll{
229 | _autoScroll = autoScroll;
230 |
231 | [self invalidateTimer];
232 |
233 | if (_autoScroll) {
234 | [self setupTimer];
235 | }
236 | }
237 |
238 | - (void)setScrollDirection:(UICollectionViewScrollDirection)scrollDirection
239 | {
240 | _scrollDirection = scrollDirection;
241 |
242 | _flowLayout.scrollDirection = scrollDirection;
243 | }
244 |
245 | - (void)setAutoScrollTimeInterval:(CGFloat)autoScrollTimeInterval
246 | {
247 | _autoScrollTimeInterval = autoScrollTimeInterval;
248 |
249 | [self setAutoScroll:self.autoScroll];
250 | }
251 |
252 | - (void)setPageControlStyle:(SDCycleScrollViewPageContolStyle)pageControlStyle
253 | {
254 | _pageControlStyle = pageControlStyle;
255 |
256 | [self setupPageControl];
257 | }
258 |
259 | - (void)setImagePathsGroup:(NSArray *)imagePathsGroup
260 | {
261 | [self invalidateTimer];
262 |
263 | _imagePathsGroup = imagePathsGroup;
264 |
265 | _totalItemsCount = self.infiniteLoop ? self.imagePathsGroup.count * 100 : self.imagePathsGroup.count;
266 |
267 | if (imagePathsGroup.count != 1) {
268 | self.mainView.scrollEnabled = YES;
269 | [self setAutoScroll:self.autoScroll];
270 | } else {
271 | self.mainView.scrollEnabled = NO;
272 | }
273 |
274 | [self setupPageControl];
275 | [self.mainView reloadData];
276 | }
277 |
278 | - (void)setImageURLStringsGroup:(NSArray *)imageURLStringsGroup
279 | {
280 | _imageURLStringsGroup = imageURLStringsGroup;
281 |
282 | NSMutableArray *temp = [NSMutableArray new];
283 | [_imageURLStringsGroup enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * stop) {
284 | NSString *urlString;
285 | if ([obj isKindOfClass:[NSString class]]) {
286 | urlString = obj;
287 | } else if ([obj isKindOfClass:[NSURL class]]) {
288 | NSURL *url = (NSURL *)obj;
289 | urlString = [url absoluteString];
290 | }
291 | if (urlString) {
292 | [temp addObject:urlString];
293 | }
294 | }];
295 | self.imagePathsGroup = [temp copy];
296 | }
297 |
298 | - (void)setLocalizationImageNamesGroup:(NSArray *)localizationImageNamesGroup
299 | {
300 | _localizationImageNamesGroup = localizationImageNamesGroup;
301 | self.imagePathsGroup = [localizationImageNamesGroup copy];
302 | }
303 |
304 | - (void)setTitlesGroup:(NSArray *)titlesGroup
305 | {
306 | _titlesGroup = titlesGroup;
307 | if (self.onlyDisplayText) {
308 | NSMutableArray *temp = [NSMutableArray new];
309 | for (int i = 0; i < _titlesGroup.count; i++) {
310 | [temp addObject:@""];
311 | }
312 | self.backgroundColor = [UIColor clearColor];
313 | self.imageURLStringsGroup = [temp copy];
314 | }
315 | }
316 |
317 | #pragma mark - actions
318 |
319 | - (void)setupTimer
320 | {
321 | NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:self.autoScrollTimeInterval target:self selector:@selector(automaticScroll) userInfo:nil repeats:YES];
322 | _timer = timer;
323 | [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
324 | }
325 |
326 | - (void)invalidateTimer
327 | {
328 | [_timer invalidate];
329 | _timer = nil;
330 | }
331 |
332 | - (void)setupPageControl
333 | {
334 | if (_pageControl) [_pageControl removeFromSuperview]; // 重新加载数据时调整
335 |
336 | if (self.imagePathsGroup.count == 0 || self.onlyDisplayText) return;
337 |
338 | if ((self.imagePathsGroup.count == 1) && self.hidesForSinglePage) return;
339 |
340 | int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:[self currentIndex]];
341 |
342 | switch (self.pageControlStyle) {
343 | case SDCycleScrollViewPageContolStyleAnimated:
344 | {
345 | TAPageControl *pageControl = [[TAPageControl alloc] init];
346 | pageControl.numberOfPages = self.imagePathsGroup.count;
347 | pageControl.dotColor = self.currentPageDotColor;
348 | pageControl.userInteractionEnabled = NO;
349 | pageControl.currentPage = indexOnPageControl;
350 | [self addSubview:pageControl];
351 | _pageControl = pageControl;
352 | }
353 | break;
354 |
355 | case SDCycleScrollViewPageContolStyleClassic:
356 | {
357 | UIPageControl *pageControl = [[UIPageControl alloc] init];
358 | pageControl.numberOfPages = self.imagePathsGroup.count;
359 | pageControl.currentPageIndicatorTintColor = self.currentPageDotColor;
360 | pageControl.pageIndicatorTintColor = self.pageDotColor;
361 | pageControl.userInteractionEnabled = NO;
362 | pageControl.currentPage = indexOnPageControl;
363 | [self addSubview:pageControl];
364 | _pageControl = pageControl;
365 | }
366 | break;
367 |
368 | default:
369 | break;
370 | }
371 |
372 | // 重设pagecontroldot图片
373 | if (self.currentPageDotImage) {
374 | self.currentPageDotImage = self.currentPageDotImage;
375 | }
376 | if (self.pageDotImage) {
377 | self.pageDotImage = self.pageDotImage;
378 | }
379 | }
380 |
381 |
382 | - (void)automaticScroll
383 | {
384 | if (0 == _totalItemsCount) return;
385 | int currentIndex = [self currentIndex];
386 | int targetIndex = currentIndex + 1;
387 | [self scrollToIndex:targetIndex];
388 | }
389 |
390 | - (void)scrollToIndex:(int)targetIndex
391 | {
392 | if (targetIndex >= _totalItemsCount) {
393 | if (self.infiniteLoop) {
394 | targetIndex = _totalItemsCount * 0.5;
395 | [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
396 | }
397 | return;
398 | }
399 | [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
400 | }
401 |
402 | - (int)currentIndex
403 | {
404 | if (_mainView.sd_width == 0 || _mainView.sd_height == 0) {
405 | return 0;
406 | }
407 |
408 | int index = 0;
409 | if (_flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
410 | index = (_mainView.contentOffset.x + _flowLayout.itemSize.width * 0.5) / _flowLayout.itemSize.width;
411 | } else {
412 | index = (_mainView.contentOffset.y + _flowLayout.itemSize.height * 0.5) / _flowLayout.itemSize.height;
413 | }
414 |
415 | return MAX(0, index);
416 | }
417 |
418 | - (int)pageControlIndexWithCurrentCellIndex:(NSInteger)index
419 | {
420 | return (int)index % self.imagePathsGroup.count;
421 | }
422 |
423 | - (void)clearCache
424 | {
425 | [[self class] clearImagesCache];
426 | }
427 |
428 | + (void)clearImagesCache
429 | {
430 | [[[SDWebImageManager sharedManager] imageCache] clearDisk];
431 | }
432 |
433 | #pragma mark - life circles
434 |
435 | - (void)layoutSubviews
436 | {
437 | [super layoutSubviews];
438 |
439 | _flowLayout.itemSize = self.frame.size;
440 |
441 | _mainView.frame = self.bounds;
442 | if (_mainView.contentOffset.x == 0 && _totalItemsCount) {
443 | int targetIndex = 0;
444 | if (self.infiniteLoop) {
445 | targetIndex = _totalItemsCount * 0.5;
446 | }else{
447 | targetIndex = 0;
448 | }
449 | [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
450 | }
451 |
452 | CGSize size = CGSizeZero;
453 | if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
454 | TAPageControl *pageControl = (TAPageControl *)_pageControl;
455 | if (!(self.pageDotImage && self.currentPageDotImage && CGSizeEqualToSize(kCycleScrollViewInitialPageControlDotSize, self.pageControlDotSize))) {
456 | pageControl.dotSize = self.pageControlDotSize;
457 | }
458 | size = [pageControl sizeForNumberOfPages:self.imagePathsGroup.count];
459 | } else {
460 | size = CGSizeMake(self.imagePathsGroup.count * self.pageControlDotSize.width * 1.2, self.pageControlDotSize.height);
461 | }
462 | CGFloat x = (self.sd_width - size.width) * 0.5;
463 | if (self.pageControlAliment == SDCycleScrollViewPageContolAlimentRight) {
464 | x = self.mainView.sd_width - size.width - 10;
465 | }
466 | CGFloat y = self.mainView.sd_height - size.height - 10;
467 |
468 | if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
469 | TAPageControl *pageControl = (TAPageControl *)_pageControl;
470 | [pageControl sizeToFit];
471 | }
472 |
473 | self.pageControl.frame = CGRectMake(x, y, size.width, size.height);
474 | self.pageControl.hidden = !_showPageControl;
475 |
476 | if (self.backgroundImageView) {
477 | self.backgroundImageView.frame = self.bounds;
478 | }
479 |
480 | }
481 |
482 | //解决当父View释放时,当前视图因为被Timer强引用而不能释放的问题
483 | - (void)willMoveToSuperview:(UIView *)newSuperview
484 | {
485 | if (!newSuperview) {
486 | [self invalidateTimer];
487 | }
488 | }
489 |
490 | //解决当timer释放后 回调scrollViewDidScroll时访问野指针导致崩溃
491 | - (void)dealloc {
492 | _mainView.delegate = nil;
493 | _mainView.dataSource = nil;
494 | }
495 |
496 | #pragma mark - public actions
497 |
498 | - (void)adjustWhenControllerViewWillAppera
499 | {
500 | long targetIndex = [self currentIndex];
501 | if (targetIndex < _totalItemsCount) {
502 | [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
503 | }
504 | }
505 |
506 |
507 | #pragma mark - UICollectionViewDataSource
508 |
509 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
510 | {
511 | return _totalItemsCount;
512 | }
513 |
514 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
515 | {
516 | SDCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
517 | long itemIndex = [self pageControlIndexWithCurrentCellIndex:indexPath.item];
518 |
519 | NSString *imagePath = self.imagePathsGroup[itemIndex];
520 |
521 | if (!self.onlyDisplayText && [imagePath isKindOfClass:[NSString class]]) {
522 | if ([imagePath hasPrefix:@"http"]) {
523 | [cell.imageView sd_setImageWithURL:[NSURL URLWithString:imagePath] placeholderImage:self.placeholderImage];
524 | } else {
525 | UIImage *image = [UIImage imageNamed:imagePath];
526 | if (!image) {
527 | [UIImage imageWithContentsOfFile:imagePath];
528 | }
529 | cell.imageView.image = image;
530 | }
531 | } else if (!self.onlyDisplayText && [imagePath isKindOfClass:[UIImage class]]) {
532 | cell.imageView.image = (UIImage *)imagePath;
533 | }
534 |
535 | if (_titlesGroup.count && itemIndex < _titlesGroup.count) {
536 | cell.title = _titlesGroup[itemIndex];
537 | }
538 |
539 | if (!cell.hasConfigured) {
540 | cell.titleLabelBackgroundColor = self.titleLabelBackgroundColor;
541 | cell.titleLabelHeight = self.titleLabelHeight;
542 | cell.titleLabelTextColor = self.titleLabelTextColor;
543 | cell.titleLabelTextFont = self.titleLabelTextFont;
544 | cell.hasConfigured = YES;
545 | cell.imageView.contentMode = self.bannerImageViewContentMode;
546 | cell.clipsToBounds = YES;
547 | cell.onlyDisplayText = self.onlyDisplayText;
548 | }
549 |
550 | return cell;
551 | }
552 |
553 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
554 | {
555 | if ([self.delegate respondsToSelector:@selector(cycleScrollView:didSelectItemAtIndex:)]) {
556 | [self.delegate cycleScrollView:self didSelectItemAtIndex:[self pageControlIndexWithCurrentCellIndex:indexPath.item]];
557 | }
558 | if (self.clickItemOperationBlock) {
559 | self.clickItemOperationBlock([self pageControlIndexWithCurrentCellIndex:indexPath.item]);
560 | }
561 | }
562 |
563 |
564 | #pragma mark - UIScrollViewDelegate
565 |
566 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView
567 | {
568 | if (!self.imagePathsGroup.count) return; // 解决清除timer时偶尔会出现的问题
569 | int itemIndex = [self currentIndex];
570 | int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:itemIndex];
571 |
572 | if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
573 | TAPageControl *pageControl = (TAPageControl *)_pageControl;
574 | pageControl.currentPage = indexOnPageControl;
575 | } else {
576 | UIPageControl *pageControl = (UIPageControl *)_pageControl;
577 | pageControl.currentPage = indexOnPageControl;
578 | }
579 | }
580 |
581 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
582 | {
583 | if (self.autoScroll) {
584 | [self invalidateTimer];
585 | }
586 | }
587 |
588 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
589 | {
590 | if (self.autoScroll) {
591 | [self setupTimer];
592 | }
593 | }
594 |
595 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
596 | {
597 | [self scrollViewDidEndScrollingAnimation:self.mainView];
598 | }
599 |
600 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
601 | {
602 | if (!self.imagePathsGroup.count) return; // 解决清除timer时偶尔会出现的问题
603 | int itemIndex = [self currentIndex];
604 | int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:itemIndex];
605 |
606 | if ([self.delegate respondsToSelector:@selector(cycleScrollView:didScrollToIndex:)]) {
607 | [self.delegate cycleScrollView:self didScrollToIndex:indexOnPageControl];
608 | } else if (self.itemDidScrollOperationBlock) {
609 | self.itemDidScrollOperationBlock(indexOnPageControl);
610 | }
611 | }
612 |
613 |
614 | @end
615 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/UIView+SDExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+SDExtension.h
3 | // SDRefreshView
4 | //
5 | // Created by aier on 15-2-23.
6 | // Copyright (c) 2015年 GSD. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 |
12 | #define SDColorCreater(r, g, b, a) [UIColor colorWithRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:a]
13 |
14 |
15 | @interface UIView (SDExtension)
16 |
17 | @property (nonatomic, assign) CGFloat sd_height;
18 | @property (nonatomic, assign) CGFloat sd_width;
19 |
20 | @property (nonatomic, assign) CGFloat sd_y;
21 | @property (nonatomic, assign) CGFloat sd_x;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ZKBanner/SDCycleScrollView/UIView+SDExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+SDExtension.m
3 | // SDRefreshView
4 | //
5 | // Created by aier on 15-2-23.
6 | // Copyright (c) 2015年 GSD. All rights reserved.
7 | //
8 |
9 |
10 | #import "UIView+SDExtension.h"
11 |
12 | @implementation UIView (SDExtension)
13 |
14 | - (CGFloat)sd_height
15 | {
16 | return self.frame.size.height;
17 | }
18 |
19 | - (void)setSd_height:(CGFloat)sd_height
20 | {
21 | CGRect temp = self.frame;
22 | temp.size.height = sd_height;
23 | self.frame = temp;
24 | }
25 |
26 | - (CGFloat)sd_width
27 | {
28 | return self.frame.size.width;
29 | }
30 |
31 | - (void)setSd_width:(CGFloat)sd_width
32 | {
33 | CGRect temp = self.frame;
34 | temp.size.width = sd_width;
35 | self.frame = temp;
36 | }
37 |
38 |
39 | - (CGFloat)sd_y
40 | {
41 | return self.frame.origin.y;
42 | }
43 |
44 | - (void)setSd_y:(CGFloat)sd_y
45 | {
46 | CGRect temp = self.frame;
47 | temp.origin.y = sd_y;
48 | self.frame = temp;
49 | }
50 |
51 | - (CGFloat)sd_x
52 | {
53 | return self.frame.origin.x;
54 | }
55 |
56 | - (void)setSd_x:(CGFloat)sd_x
57 | {
58 | CGRect temp = self.frame;
59 | temp.origin.x = sd_x;
60 | self.frame = temp;
61 | }
62 |
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/components/NewBanner.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import { requireNativeComponent} from 'react-native';
3 |
4 | var NewBanner = requireNativeComponent('NewBanner', NewBannerView);
5 |
6 | export default class NewBannerView extends Component {
7 | static propTypes = {
8 | /**
9 | * 属性
10 | * 定义组件需要传到原生端的属性
11 | * 使用React.PropTypes来进行校验
12 | */
13 |
14 | //自动滑动间隔时间
15 | autoScrollTimeInterval: PropTypes.number,
16 | //是否自动滑动
17 | autoScroll: PropTypes.bool,
18 | //图片点击事件
19 | onClickBanner: PropTypes.func,
20 | //网络图片数组
21 | imageURLStringsGroup:PropTypes.array,
22 | //本地图片
23 | localizationImageNamesGroup:PropTypes.array,
24 | };
25 | render() {
26 | return (
27 |
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import Banner from './components/NewBanner';
2 |
3 | module.exports = {
4 | Banner
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-zkbanner",
3 | "version": "1.0.0",
4 | "description": "...",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "react-native",
11 | "banner",
12 | "react-native-zkbanner"
13 | ],
14 | "author": "Cain",
15 | "license": "MIT"
16 | }
17 |
--------------------------------------------------------------------------------