├── Screenshot.gif
├── SwiftImageSlider.bundle
├── zh-Hans.lproj
│ └── SwiftImageSlider.strings
└── en.lproj
│ └── SwiftImageSlider.strings
├── Example
├── Podfile
├── Example.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
├── Example.xcworkspace
│ └── contents.xcworkspacedata
├── .gitignore
└── Example
│ ├── ViewController.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── AppDelegate.swift
│ └── Base.lproj
│ └── Main.storyboard
├── Source
├── ImageSliderCellDelegate.swift
├── ImageSliderViewDelegate.swift
├── ImageSliderUtility.swift
├── ImageSliderView.swift
├── ImageSliderViewController.swift
└── ImageSliderCell.swift
├── README.md
├── CHANGELOG.md
├── SwiftImageSlider.podspec
└── LICENSE
/Screenshot.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nanjingboy/SwiftImageSlider/HEAD/Screenshot.gif
--------------------------------------------------------------------------------
/SwiftImageSlider.bundle/zh-Hans.lproj/SwiftImageSlider.strings:
--------------------------------------------------------------------------------
1 | "Failed to load the image" = "图片加载失败";
--------------------------------------------------------------------------------
/SwiftImageSlider.bundle/en.lproj/SwiftImageSlider.strings:
--------------------------------------------------------------------------------
1 | "Failed to load the image" = "Failed to load the image";
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '8.0'
2 |
3 | use_frameworks!
4 |
5 | target 'Example' do
6 | pod 'SwiftImageSlider', :path => '../'
7 | end
8 |
9 |
--------------------------------------------------------------------------------
/Source/ImageSliderCellDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | protocol ImageSliderCellDelegate {
4 |
5 | func imageSliderCellSingleTap(_ tap: UITapGestureRecognizer)
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Source/ImageSliderViewDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | public protocol ImageSliderViewDelegate {
4 |
5 | func imageSliderViewSingleTap(_ tap: UITapGestureRecognizer)
6 |
7 | func imageSliderViewImageSwitch(_ index: Int, count: Int, imageUrl: String?)
8 | }
9 |
--------------------------------------------------------------------------------
/Example/Example.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/.gitignore:
--------------------------------------------------------------------------------
1 | ## Build generated
2 | build/
3 | DerivedData
4 |
5 | ## Various settings
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata
15 |
16 | ## Other
17 | *.xccheckout
18 | *.moved-aside
19 | *.xcuserstate
20 | *.xcscmblueprint
21 |
22 | ## Obj-C/Swift specific
23 | *.hmap
24 | *.ipa
25 |
26 | Pods/
27 |
28 | **/.DS_Store
29 | Podfile.lock
--------------------------------------------------------------------------------
/Source/ImageSliderUtility.swift:
--------------------------------------------------------------------------------
1 | class ImageSliderUtility: NSObject {
2 |
3 | static func localizedString(_ key: String) -> String {
4 | if let bundleUrl = Bundle(for: classForCoder()).url(forResource: "SwiftImageSlider", withExtension: "bundle") {
5 | if let bundle = Bundle(url: bundleUrl) {
6 | return bundle.localizedString(forKey: key, value: key, table: "SwiftImageSlider")
7 | }
8 | }
9 |
10 | return key
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SwiftImageSlider
2 | A simple image slide show library by Swift.
3 |
4 | # Screenshot
5 |
6 | 
7 |
8 | # Setup
9 |
10 | #### Install with [CocoaPods](http://cocoapods.org/)
11 |
12 | ```ruby
13 | platform :ios, '8.0'
14 | pod 'SwiftImageSlider', '~> 0.2.1'
15 | ```
16 |
17 | #### [Example](Example/Example/ViewController.swift)
18 |
19 | # Thanks
20 |
21 | * [Kingfisher](https://github.com/onevcat/Kingfisher)
22 | * [Toast-Swift](https://github.com/scalessec/Toast-Swift)
23 |
24 | # License
25 |
26 | [MIT](LICENSE)
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.2.1 2016-11-11
2 | * Replace Kingfisher api with [Kingfisher3.0](https://github.com/onevcat/Kingfisher/wiki/Kingfisher-3.0-Migration-Guide)
3 |
4 | ## 0.2.0 2016-11-10
5 | * Migrate to swift 3.0
6 |
7 | ## 0.1.6 2016-06-15
8 | * Set access level to public for ImageSliderView#scrollView & ImageSliderView#delegate
9 |
10 | ## 0.1.5 2016-06-15
11 | * Set access level to public for ImageSliderViewController#imageSliderView & ImageSliderViewController#displayLabel
12 |
13 | ## 0.1.3 2016-06-08
14 | * Let image fix scroll view width all time
15 |
16 | ## 0.1.0 2016-06-05
17 | * Initial release
18 |
--------------------------------------------------------------------------------
/SwiftImageSlider.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'SwiftImageSlider'
3 | s.version = '0.2.1'
4 | s.summary = 'A simple image slide show library by Swift.'
5 | s.homepage = 'https://github.com/nanjingboy/SwiftImageSlider'
6 | s.license = { :type => 'MIT', :file => 'LICENSE' }
7 | s.author = { 'Tom.Huang' => 'hzlhu.dargon@gmail.com' }
8 | s.source = { :git => 'https://github.com/nanjingboy/SwiftImageSlider.git', :tag => s.version.to_s }
9 | s.ios.deployment_target = '8.0'
10 | s.source_files = "Source/*.swift"
11 | s.resources = 'SwiftImageSlider.bundle'
12 | s.dependency "Kingfisher", "~> 3.2"
13 | s.dependency "Toast-Swift", "~> 2.0"
14 | end
15 |
--------------------------------------------------------------------------------
/Example/Example/ViewController.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import SwiftImageSlider
3 |
4 | class ViewController: UIViewController {
5 |
6 | @IBAction func showImageSlider(_ sender: AnyObject) {
7 | let imageUrls = [
8 | "http://img.bimg.126.net/photo/qwLaXLhl3boN0bUPMGRPiA==/5704653352996391616.jpg",
9 | "http://img1.cache.netease.com/catchpic/5/5C/5C02C05BD566B31FDF6F4A0D16E5C260.jpg",
10 | "http://imgsrc.baidu.com/forum/w%3D580/sign=20af00b006087bf47dec57e1c2d2575e/bd291cd162d9f2d36a161b14adec8a136227cc27.jpg",
11 | "http://tw.bid.yimg.com/pimg1/77/8c/p080324724868-item-2640xf1x0490x0395-m.jpg"
12 | ]
13 | let controller = ImageSliderViewController(currentIndex: 0, imageUrls: imageUrls)
14 | present(controller, animated: true, completion: nil)
15 |
16 | }
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Tom.Huang
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/Example/Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | NSAppTransportSecurity
8 |
9 | NSAllowsArbitraryLoads
10 |
11 |
12 | CFBundleExecutable
13 | $(EXECUTABLE_NAME)
14 | CFBundleIdentifier
15 | $(PRODUCT_BUNDLE_IDENTIFIER)
16 | CFBundleInfoDictionaryVersion
17 | 6.0
18 | CFBundleName
19 | $(PRODUCT_NAME)
20 | CFBundlePackageType
21 | APPL
22 | CFBundleShortVersionString
23 | 1.0
24 | CFBundleSignature
25 | ????
26 | CFBundleVersion
27 | 1
28 | LSRequiresIPhoneOS
29 |
30 | UILaunchStoryboardName
31 | Main
32 | UIMainStoryboardFile
33 | Main
34 | UIRequiredDeviceCapabilities
35 |
36 | armv7
37 |
38 | UISupportedInterfaceOrientations
39 |
40 | UIInterfaceOrientationPortrait
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/Example/Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Example
4 | //
5 | // Created by TomHuang on 16/6/4.
6 | // Copyright © 2016年 TomHuang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Example/Example/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Source/ImageSliderView.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | open class ImageSliderView: UIView, UIScrollViewDelegate, ImageSliderCellDelegate {
4 |
5 | fileprivate var currentIndex: Int
6 | fileprivate var sliderCells: [ImageSliderCell] = []
7 | fileprivate var isUpdatingCellFrames = false
8 |
9 | open var delegate: ImageSliderViewDelegate?
10 | open let scrollView = UIScrollView()
11 |
12 | open override var bounds: CGRect {
13 | didSet {
14 | updateCellFrames()
15 | }
16 | }
17 |
18 | public init(currntIndex: Int, imageUrls: [String]) {
19 | self.currentIndex = currntIndex
20 | super.init(frame: CGRect.zero)
21 | initialize(imageUrls)
22 | }
23 |
24 | public required init?(coder aDecoder: NSCoder) {
25 | self.currentIndex = 0
26 | super.init(coder: aDecoder)
27 | initialize([])
28 | }
29 |
30 | open func scrollViewDidScroll(_ scrollView: UIScrollView) {
31 | if (isUpdatingCellFrames) {
32 | isUpdatingCellFrames = false
33 | return
34 | }
35 | self.scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: 0)
36 | let width = self.scrollView.frame.width
37 | let index = Int(floor((self.scrollView.contentOffset.x - width / 2) / width) + 1)
38 | if (currentIndex != index) {
39 | switchImage(index)
40 | }
41 | }
42 |
43 | func initialize(_ imageUrls: [String]) {
44 | clipsToBounds = false
45 |
46 | scrollView.scrollsToTop = false
47 | scrollView.isPagingEnabled = true
48 | scrollView.delegate = self
49 | scrollView.showsVerticalScrollIndicator = false
50 | scrollView.showsHorizontalScrollIndicator = false
51 | scrollView.autoresizesSubviews = false
52 | scrollView.autoresizingMask = UIViewAutoresizing()
53 | scrollView.translatesAutoresizingMaskIntoConstraints = false
54 |
55 | for imageUrl in imageUrls {
56 | let sliderCell = ImageSliderCell(imageUrl: imageUrl)
57 | sliderCell.delegate = self
58 | sliderCells.append(sliderCell)
59 | scrollView.addSubview(sliderCell)
60 | }
61 |
62 | addSubview(scrollView)
63 | }
64 |
65 | func updateCellFrames() {
66 | let pageCount = sliderCells.count
67 | let sliderViewFrame = bounds
68 |
69 | isUpdatingCellFrames = true
70 | scrollView.frame = sliderViewFrame
71 | scrollView.contentSize = CGSize(width: sliderViewFrame.size.width * CGFloat(pageCount),
72 | height: sliderViewFrame.size.height * CGFloat(pageCount))
73 |
74 | scrollView.contentOffset = CGPoint(x: CGFloat(currentIndex) * sliderViewFrame.size.width, y: 0)
75 | let scrollViewBounds = scrollView.bounds
76 | for index in 0 ..< pageCount {
77 | let sliderCell = sliderCells[index]
78 | sliderCell.frame = CGRect(x: scrollViewBounds.width * CGFloat(index),
79 | y: scrollViewBounds.minY,
80 | width: scrollViewBounds.width,
81 | height: scrollViewBounds.height)
82 | }
83 |
84 | switchImage(currentIndex)
85 | }
86 |
87 | func switchImage(_ index: Int) {
88 | let sliderCell = sliderCells[index]
89 | sliderCell.loadImage()
90 | currentIndex = index
91 | delegate?.imageSliderViewImageSwitch(index, count: sliderCells.count, imageUrl: sliderCell.imageUrl)
92 | }
93 |
94 | func imageSliderCellSingleTap(_ tap: UITapGestureRecognizer) {
95 | delegate?.imageSliderViewSingleTap(tap)
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Source/ImageSliderViewController.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | open class ImageSliderViewController: UIViewController, ImageSliderViewDelegate {
4 |
5 | open let imageSliderView: ImageSliderView
6 | open let pageControl = UIPageControl()
7 |
8 | public init(currentIndex: Int, imageUrls: [String]) {
9 | imageSliderView = ImageSliderView(currntIndex: currentIndex, imageUrls: imageUrls)
10 | super.init(nibName: nil, bundle: nil)
11 | imageSliderViewImageSwitch(currentIndex, count: imageUrls.count, imageUrl: imageUrls[currentIndex])
12 | }
13 |
14 | public required init?(coder aDecoder: NSCoder) {
15 | imageSliderView = ImageSliderView(currntIndex: 0, imageUrls: [])
16 | super.init(coder: aDecoder)
17 | imageSliderViewImageSwitch(0, count: 0, imageUrl: nil)
18 | }
19 |
20 | open override func viewDidLoad() {
21 | super.viewDidLoad()
22 | view.clipsToBounds = true
23 | view.backgroundColor = UIColor.black
24 |
25 | imageSliderView.delegate = self
26 | imageSliderView.translatesAutoresizingMaskIntoConstraints = false
27 | view.addSubview(imageSliderView)
28 | setImageSliderViewConstraints()
29 |
30 | pageControl.translatesAutoresizingMaskIntoConstraints = false
31 |
32 | view.addSubview(pageControl)
33 | setDisplayLabelConstraints()
34 | }
35 |
36 | open func setImageSliderViewConstraints() {
37 | let imageSliderViewHConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[imageSliderView]-0-|",
38 | options: [],
39 | metrics: nil,
40 | views: ["imageSliderView": imageSliderView])
41 | view.addConstraints(imageSliderViewHConstraints)
42 |
43 | let imageSliderViewVConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[imageSliderView]-0-|",
44 | options: [],
45 | metrics: nil,
46 | views: ["imageSliderView": imageSliderView])
47 | view.addConstraints(imageSliderViewVConstraints)
48 | }
49 |
50 | open func setDisplayLabelConstraints() {
51 | let constraint = NSLayoutConstraint(item: pageControl,
52 | attribute: NSLayoutAttribute.centerX,
53 | relatedBy: NSLayoutRelation.equal,
54 | toItem: view,
55 | attribute: NSLayoutAttribute.centerX,
56 | multiplier: 1.0,
57 | constant: 0.0)
58 | view.addConstraint(constraint)
59 |
60 | let displayLabelVConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[pageControl]-20-|",
61 | options: [],
62 | metrics: nil,
63 | views: ["pageControl": pageControl])
64 | view.addConstraints(displayLabelVConstraints)
65 | }
66 |
67 | open func imageSliderViewSingleTap(_ tap: UITapGestureRecognizer) {
68 | dismiss(animated: true, completion: nil)
69 | }
70 |
71 | open func imageSliderViewImageSwitch(_ index: Int, count: Int, imageUrl: String?) {
72 | pageControl.numberOfPages = count
73 | pageControl.currentPage = index
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Source/ImageSliderCell.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Kingfisher
3 | import Toast_Swift
4 |
5 | class ImageSliderCell: UIView, UIScrollViewDelegate {
6 |
7 | var delegate: ImageSliderCellDelegate?
8 | let imageUrl: String
9 |
10 | fileprivate let imageView = UIImageView()
11 | fileprivate let scrollView = UIScrollView()
12 |
13 | override var frame: CGRect {
14 | didSet {
15 | if !frame.equalTo(CGRect.zero) {
16 | scrollView.frame = bounds
17 | resetZoomScale()
18 | drawImage()
19 | }
20 | }
21 | }
22 |
23 | init(imageUrl: String) {
24 | self.imageUrl = imageUrl
25 | super.init(frame: CGRect.zero)
26 | initialize()
27 | }
28 |
29 | required init?(coder aDecoder: NSCoder) {
30 | self.imageUrl = ""
31 | super.init(coder: aDecoder)
32 | initialize()
33 | }
34 |
35 | func initialize() {
36 | imageView.contentMode = UIViewContentMode.scaleAspectFit
37 |
38 | scrollView.clipsToBounds = true
39 | scrollView.delegate = self
40 | scrollView.showsHorizontalScrollIndicator = false
41 | scrollView.showsVerticalScrollIndicator = false
42 | scrollView.decelerationRate /= 2
43 | scrollView.bouncesZoom = true
44 | scrollView.addSubview(imageView)
45 | addSubview(scrollView)
46 |
47 | let doubleTap = UITapGestureRecognizer(target: self, action: #selector(imageSliderCellDoubleTap))
48 | doubleTap.numberOfTapsRequired = 2
49 | scrollView.addGestureRecognizer(doubleTap)
50 |
51 | let singleTap = UITapGestureRecognizer(target: self, action: #selector(imageSliderCellSingleTap))
52 | singleTap.numberOfTapsRequired = 1
53 | singleTap.require(toFail: doubleTap)
54 | scrollView.addGestureRecognizer(singleTap)
55 | }
56 |
57 | func imageSliderCellDoubleTap(_ tap: UITapGestureRecognizer) {
58 | let touchPoint = tap.location(in: self)
59 | if (scrollView.zoomScale == scrollView.minimumZoomScale) {
60 | scrollView.zoom(to: CGRect(x: touchPoint.x, y: touchPoint.y, width: 1, height: 1), animated: true)
61 | } else {
62 | scrollView.setZoomScale(scrollView.minimumZoomScale, animated: true)
63 | }
64 | }
65 |
66 | func imageSliderCellSingleTap(_ tap: UITapGestureRecognizer) {
67 | delegate?.imageSliderCellSingleTap(tap)
68 | }
69 |
70 | func viewForZooming(in scrollView: UIScrollView) -> UIView? {
71 | return imageView
72 | }
73 |
74 | func scrollViewDidZoom(_ scrollView: UIScrollView) {
75 | imageView.center = centerOfScrollView(scrollView)
76 | }
77 |
78 | func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
79 | UIView.animate(withDuration: 0.25, animations: {
80 | view?.center = self.centerOfScrollView(scrollView)
81 | })
82 | }
83 |
84 | func loadImage() {
85 | if let _ = imageView.image {
86 | return
87 | }
88 |
89 | makeToastActivity(.center)
90 | scrollView.frame = bounds
91 | resetZoomScale()
92 | imageView.kf.setImage(with: URL(string: imageUrl)!,
93 | placeholder: nil,
94 | options: nil,
95 | progressBlock: nil,
96 | completionHandler: {(image, error, cacheType, imageURL) -> () in
97 | self.hideToastActivity()
98 | if image == nil || error != nil {
99 | var style = ToastStyle()
100 | style.messageAlignment = NSTextAlignment.center
101 | self.makeToast(ImageSliderUtility.localizedString("Failed to load the image"), duration: 2, position: .center, style: style)
102 | } else {
103 | self.drawImage()
104 | }
105 | }
106 | )
107 | }
108 |
109 | func resetZoomScale() {
110 | scrollView.minimumZoomScale = 1.0
111 | scrollView.maximumZoomScale = 1.0
112 | scrollView.zoomScale = 1.0
113 | }
114 |
115 | func drawImage() {
116 | var scrollViewFrame = scrollView.frame
117 | if imageView.image == nil {
118 | scrollViewFrame.origin = CGPoint.zero
119 | imageView.frame = scrollViewFrame
120 | scrollView.contentSize = imageView.frame.size
121 | resetZoomScale()
122 | } else {
123 | let imageSize = imageView.image!.size
124 | let ratio = scrollViewFrame.size.width / imageSize.width
125 | imageView.frame = CGRect(x: 0, y: 0, width: scrollViewFrame.size.width, height: imageSize.height * ratio)
126 | scrollView.contentSize = imageView.frame.size
127 | imageView.center = centerOfScrollView(scrollView)
128 | scrollView.minimumZoomScale = 1.0
129 | scrollView.maximumZoomScale = scrollViewFrame.height / imageView.frame.size.height
130 | scrollView.zoomScale = 1.0
131 | }
132 | scrollView.contentOffset = CGPoint.zero
133 | }
134 |
135 | func centerOfScrollView(_ scrollView: UIScrollView) -> CGPoint {
136 | var offsetX: CGFloat
137 | if scrollView.bounds.size.width > scrollView.bounds.size.height {
138 | offsetX = (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5
139 | } else {
140 | offsetX = 0.0
141 | }
142 |
143 | var offsetY: CGFloat
144 | if scrollView.bounds.size.height > scrollView.contentSize.height {
145 | offsetY = (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5
146 | } else {
147 | offsetY = 0.0
148 | }
149 |
150 | return CGPoint(x: scrollView.contentSize.width * 0.5 + offsetX,
151 | y: scrollView.contentSize.height * 0.5 + offsetY)
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6A2FFDA3BC3AEED1E9812B3C /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C63FFC89D1DF6FC4743794 /* Pods_Example.framework */; };
11 | E2AAFC401D02C00700F85EB1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AAFC3F1D02C00700F85EB1 /* AppDelegate.swift */; };
12 | E2AAFC421D02C00700F85EB1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AAFC411D02C00700F85EB1 /* ViewController.swift */; };
13 | E2AAFC451D02C00700F85EB1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E2AAFC431D02C00700F85EB1 /* Main.storyboard */; };
14 | E2AAFC471D02C00700F85EB1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E2AAFC461D02C00700F85EB1 /* Assets.xcassets */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | A1C63FFC89D1DF6FC4743794 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
19 | B17E902500E1C67590DF71FC /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; };
20 | C8C4C2C83CBA2AF09B8C50E4 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; };
21 | E2AAFC3C1D02C00700F85EB1 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
22 | E2AAFC3F1D02C00700F85EB1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
23 | E2AAFC411D02C00700F85EB1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
24 | E2AAFC441D02C00700F85EB1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
25 | E2AAFC461D02C00700F85EB1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
26 | E2AAFC4B1D02C00700F85EB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
27 | /* End PBXFileReference section */
28 |
29 | /* Begin PBXFrameworksBuildPhase section */
30 | E2AAFC391D02C00700F85EB1 /* Frameworks */ = {
31 | isa = PBXFrameworksBuildPhase;
32 | buildActionMask = 2147483647;
33 | files = (
34 | 6A2FFDA3BC3AEED1E9812B3C /* Pods_Example.framework in Frameworks */,
35 | );
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXFrameworksBuildPhase section */
39 |
40 | /* Begin PBXGroup section */
41 | E2AAFC331D02C00700F85EB1 = {
42 | isa = PBXGroup;
43 | children = (
44 | E2AAFC3E1D02C00700F85EB1 /* Example */,
45 | E2AAFC3D1D02C00700F85EB1 /* Products */,
46 | FDC68372E016134075A09FF6 /* Pods */,
47 | EA73C8C6CEC6B890EAEF3B13 /* Frameworks */,
48 | );
49 | sourceTree = "";
50 | };
51 | E2AAFC3D1D02C00700F85EB1 /* Products */ = {
52 | isa = PBXGroup;
53 | children = (
54 | E2AAFC3C1D02C00700F85EB1 /* Example.app */,
55 | );
56 | name = Products;
57 | sourceTree = "";
58 | };
59 | E2AAFC3E1D02C00700F85EB1 /* Example */ = {
60 | isa = PBXGroup;
61 | children = (
62 | E2AAFC3F1D02C00700F85EB1 /* AppDelegate.swift */,
63 | E2AAFC411D02C00700F85EB1 /* ViewController.swift */,
64 | E2AAFC431D02C00700F85EB1 /* Main.storyboard */,
65 | E2AAFC461D02C00700F85EB1 /* Assets.xcassets */,
66 | E2AAFC4B1D02C00700F85EB1 /* Info.plist */,
67 | );
68 | path = Example;
69 | sourceTree = "";
70 | };
71 | EA73C8C6CEC6B890EAEF3B13 /* Frameworks */ = {
72 | isa = PBXGroup;
73 | children = (
74 | A1C63FFC89D1DF6FC4743794 /* Pods_Example.framework */,
75 | );
76 | name = Frameworks;
77 | sourceTree = "";
78 | };
79 | FDC68372E016134075A09FF6 /* Pods */ = {
80 | isa = PBXGroup;
81 | children = (
82 | C8C4C2C83CBA2AF09B8C50E4 /* Pods-Example.debug.xcconfig */,
83 | B17E902500E1C67590DF71FC /* Pods-Example.release.xcconfig */,
84 | );
85 | name = Pods;
86 | sourceTree = "";
87 | };
88 | /* End PBXGroup section */
89 |
90 | /* Begin PBXNativeTarget section */
91 | E2AAFC3B1D02C00700F85EB1 /* Example */ = {
92 | isa = PBXNativeTarget;
93 | buildConfigurationList = E2AAFC4E1D02C00700F85EB1 /* Build configuration list for PBXNativeTarget "Example" */;
94 | buildPhases = (
95 | C06D7B3F46D69C697F4975F3 /* [CP] Check Pods Manifest.lock */,
96 | E2AAFC381D02C00700F85EB1 /* Sources */,
97 | E2AAFC391D02C00700F85EB1 /* Frameworks */,
98 | E2AAFC3A1D02C00700F85EB1 /* Resources */,
99 | 975A3B4FD971F08EACC9E37C /* [CP] Embed Pods Frameworks */,
100 | 8F6B7CC8E53497DA8FB42B69 /* [CP] Copy Pods Resources */,
101 | );
102 | buildRules = (
103 | );
104 | dependencies = (
105 | );
106 | name = Example;
107 | productName = Example;
108 | productReference = E2AAFC3C1D02C00700F85EB1 /* Example.app */;
109 | productType = "com.apple.product-type.application";
110 | };
111 | /* End PBXNativeTarget section */
112 |
113 | /* Begin PBXProject section */
114 | E2AAFC341D02C00700F85EB1 /* Project object */ = {
115 | isa = PBXProject;
116 | attributes = {
117 | LastSwiftUpdateCheck = 0730;
118 | LastUpgradeCheck = 0730;
119 | ORGANIZATIONNAME = TomHuang;
120 | TargetAttributes = {
121 | E2AAFC3B1D02C00700F85EB1 = {
122 | CreatedOnToolsVersion = 7.3.1;
123 | LastSwiftMigration = 0810;
124 | };
125 | };
126 | };
127 | buildConfigurationList = E2AAFC371D02C00700F85EB1 /* Build configuration list for PBXProject "Example" */;
128 | compatibilityVersion = "Xcode 3.2";
129 | developmentRegion = English;
130 | hasScannedForEncodings = 0;
131 | knownRegions = (
132 | en,
133 | Base,
134 | );
135 | mainGroup = E2AAFC331D02C00700F85EB1;
136 | productRefGroup = E2AAFC3D1D02C00700F85EB1 /* Products */;
137 | projectDirPath = "";
138 | projectRoot = "";
139 | targets = (
140 | E2AAFC3B1D02C00700F85EB1 /* Example */,
141 | );
142 | };
143 | /* End PBXProject section */
144 |
145 | /* Begin PBXResourcesBuildPhase section */
146 | E2AAFC3A1D02C00700F85EB1 /* Resources */ = {
147 | isa = PBXResourcesBuildPhase;
148 | buildActionMask = 2147483647;
149 | files = (
150 | E2AAFC471D02C00700F85EB1 /* Assets.xcassets in Resources */,
151 | E2AAFC451D02C00700F85EB1 /* Main.storyboard in Resources */,
152 | );
153 | runOnlyForDeploymentPostprocessing = 0;
154 | };
155 | /* End PBXResourcesBuildPhase section */
156 |
157 | /* Begin PBXShellScriptBuildPhase section */
158 | 8F6B7CC8E53497DA8FB42B69 /* [CP] Copy Pods Resources */ = {
159 | isa = PBXShellScriptBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | );
163 | inputPaths = (
164 | );
165 | name = "[CP] Copy Pods Resources";
166 | outputPaths = (
167 | );
168 | runOnlyForDeploymentPostprocessing = 0;
169 | shellPath = /bin/sh;
170 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-resources.sh\"\n";
171 | showEnvVarsInLog = 0;
172 | };
173 | 975A3B4FD971F08EACC9E37C /* [CP] Embed Pods Frameworks */ = {
174 | isa = PBXShellScriptBuildPhase;
175 | buildActionMask = 2147483647;
176 | files = (
177 | );
178 | inputPaths = (
179 | );
180 | name = "[CP] Embed Pods Frameworks";
181 | outputPaths = (
182 | );
183 | runOnlyForDeploymentPostprocessing = 0;
184 | shellPath = /bin/sh;
185 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n";
186 | showEnvVarsInLog = 0;
187 | };
188 | C06D7B3F46D69C697F4975F3 /* [CP] Check Pods Manifest.lock */ = {
189 | isa = PBXShellScriptBuildPhase;
190 | buildActionMask = 2147483647;
191 | files = (
192 | );
193 | inputPaths = (
194 | );
195 | name = "[CP] Check Pods Manifest.lock";
196 | outputPaths = (
197 | );
198 | runOnlyForDeploymentPostprocessing = 0;
199 | shellPath = /bin/sh;
200 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
201 | showEnvVarsInLog = 0;
202 | };
203 | /* End PBXShellScriptBuildPhase section */
204 |
205 | /* Begin PBXSourcesBuildPhase section */
206 | E2AAFC381D02C00700F85EB1 /* Sources */ = {
207 | isa = PBXSourcesBuildPhase;
208 | buildActionMask = 2147483647;
209 | files = (
210 | E2AAFC421D02C00700F85EB1 /* ViewController.swift in Sources */,
211 | E2AAFC401D02C00700F85EB1 /* AppDelegate.swift in Sources */,
212 | );
213 | runOnlyForDeploymentPostprocessing = 0;
214 | };
215 | /* End PBXSourcesBuildPhase section */
216 |
217 | /* Begin PBXVariantGroup section */
218 | E2AAFC431D02C00700F85EB1 /* Main.storyboard */ = {
219 | isa = PBXVariantGroup;
220 | children = (
221 | E2AAFC441D02C00700F85EB1 /* Base */,
222 | );
223 | name = Main.storyboard;
224 | sourceTree = "";
225 | };
226 | /* End PBXVariantGroup section */
227 |
228 | /* Begin XCBuildConfiguration section */
229 | E2AAFC4C1D02C00700F85EB1 /* Debug */ = {
230 | isa = XCBuildConfiguration;
231 | buildSettings = {
232 | ALWAYS_SEARCH_USER_PATHS = NO;
233 | CLANG_ANALYZER_NONNULL = YES;
234 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
235 | CLANG_CXX_LIBRARY = "libc++";
236 | CLANG_ENABLE_MODULES = YES;
237 | CLANG_ENABLE_OBJC_ARC = YES;
238 | CLANG_WARN_BOOL_CONVERSION = YES;
239 | CLANG_WARN_CONSTANT_CONVERSION = YES;
240 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
241 | CLANG_WARN_EMPTY_BODY = YES;
242 | CLANG_WARN_ENUM_CONVERSION = YES;
243 | CLANG_WARN_INT_CONVERSION = YES;
244 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
245 | CLANG_WARN_UNREACHABLE_CODE = YES;
246 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
247 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
248 | COPY_PHASE_STRIP = NO;
249 | DEBUG_INFORMATION_FORMAT = dwarf;
250 | ENABLE_STRICT_OBJC_MSGSEND = YES;
251 | ENABLE_TESTABILITY = YES;
252 | GCC_C_LANGUAGE_STANDARD = gnu99;
253 | GCC_DYNAMIC_NO_PIC = NO;
254 | GCC_NO_COMMON_BLOCKS = YES;
255 | GCC_OPTIMIZATION_LEVEL = 0;
256 | GCC_PREPROCESSOR_DEFINITIONS = (
257 | "DEBUG=1",
258 | "$(inherited)",
259 | );
260 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
261 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
262 | GCC_WARN_UNDECLARED_SELECTOR = YES;
263 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
264 | GCC_WARN_UNUSED_FUNCTION = YES;
265 | GCC_WARN_UNUSED_VARIABLE = YES;
266 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
267 | MTL_ENABLE_DEBUG_INFO = YES;
268 | ONLY_ACTIVE_ARCH = YES;
269 | SDKROOT = iphoneos;
270 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
271 | TARGETED_DEVICE_FAMILY = "1,2";
272 | };
273 | name = Debug;
274 | };
275 | E2AAFC4D1D02C00700F85EB1 /* Release */ = {
276 | isa = XCBuildConfiguration;
277 | buildSettings = {
278 | ALWAYS_SEARCH_USER_PATHS = NO;
279 | CLANG_ANALYZER_NONNULL = YES;
280 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
281 | CLANG_CXX_LIBRARY = "libc++";
282 | CLANG_ENABLE_MODULES = YES;
283 | CLANG_ENABLE_OBJC_ARC = YES;
284 | CLANG_WARN_BOOL_CONVERSION = YES;
285 | CLANG_WARN_CONSTANT_CONVERSION = YES;
286 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
287 | CLANG_WARN_EMPTY_BODY = YES;
288 | CLANG_WARN_ENUM_CONVERSION = YES;
289 | CLANG_WARN_INT_CONVERSION = YES;
290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
291 | CLANG_WARN_UNREACHABLE_CODE = YES;
292 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
293 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
294 | COPY_PHASE_STRIP = NO;
295 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
296 | ENABLE_NS_ASSERTIONS = NO;
297 | ENABLE_STRICT_OBJC_MSGSEND = YES;
298 | GCC_C_LANGUAGE_STANDARD = gnu99;
299 | GCC_NO_COMMON_BLOCKS = YES;
300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
302 | GCC_WARN_UNDECLARED_SELECTOR = YES;
303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
304 | GCC_WARN_UNUSED_FUNCTION = YES;
305 | GCC_WARN_UNUSED_VARIABLE = YES;
306 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
307 | MTL_ENABLE_DEBUG_INFO = NO;
308 | SDKROOT = iphoneos;
309 | TARGETED_DEVICE_FAMILY = "1,2";
310 | VALIDATE_PRODUCT = YES;
311 | };
312 | name = Release;
313 | };
314 | E2AAFC4F1D02C00700F85EB1 /* Debug */ = {
315 | isa = XCBuildConfiguration;
316 | baseConfigurationReference = C8C4C2C83CBA2AF09B8C50E4 /* Pods-Example.debug.xcconfig */;
317 | buildSettings = {
318 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
319 | INFOPLIST_FILE = Example/Info.plist;
320 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
321 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
322 | PRODUCT_BUNDLE_IDENTIFIER = me.tom.Example;
323 | PRODUCT_NAME = "$(TARGET_NAME)";
324 | SWIFT_VERSION = 3.0;
325 | };
326 | name = Debug;
327 | };
328 | E2AAFC501D02C00700F85EB1 /* Release */ = {
329 | isa = XCBuildConfiguration;
330 | baseConfigurationReference = B17E902500E1C67590DF71FC /* Pods-Example.release.xcconfig */;
331 | buildSettings = {
332 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
333 | INFOPLIST_FILE = Example/Info.plist;
334 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
335 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
336 | PRODUCT_BUNDLE_IDENTIFIER = me.tom.Example;
337 | PRODUCT_NAME = "$(TARGET_NAME)";
338 | SWIFT_VERSION = 3.0;
339 | };
340 | name = Release;
341 | };
342 | /* End XCBuildConfiguration section */
343 |
344 | /* Begin XCConfigurationList section */
345 | E2AAFC371D02C00700F85EB1 /* Build configuration list for PBXProject "Example" */ = {
346 | isa = XCConfigurationList;
347 | buildConfigurations = (
348 | E2AAFC4C1D02C00700F85EB1 /* Debug */,
349 | E2AAFC4D1D02C00700F85EB1 /* Release */,
350 | );
351 | defaultConfigurationIsVisible = 0;
352 | defaultConfigurationName = Release;
353 | };
354 | E2AAFC4E1D02C00700F85EB1 /* Build configuration list for PBXNativeTarget "Example" */ = {
355 | isa = XCConfigurationList;
356 | buildConfigurations = (
357 | E2AAFC4F1D02C00700F85EB1 /* Debug */,
358 | E2AAFC501D02C00700F85EB1 /* Release */,
359 | );
360 | defaultConfigurationIsVisible = 0;
361 | defaultConfigurationName = Release;
362 | };
363 | /* End XCConfigurationList section */
364 | };
365 | rootObject = E2AAFC341D02C00700F85EB1 /* Project object */;
366 | }
367 |
--------------------------------------------------------------------------------