Repository: wangmchn/WMPageController-Swift Branch: master Commit: 4c68bdc69568 Files: 42 Total size: 156.7 KB Directory structure: gitextract_5pm0eoic/ ├── .gitignore ├── .travis.yml ├── LICENSE ├── PageController/ │ ├── FloodView.swift │ ├── MenuItem.swift │ ├── MenuView.swift │ ├── PageController.swift │ └── ProgressView.swift ├── README.md ├── StoryboardExample/ │ ├── StoryboardExample/ │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets/ │ │ │ └── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── ParentController/ │ │ │ └── CustomPageController.swift │ │ ├── TableViewController.swift │ │ └── ViewController.swift │ ├── StoryboardExample.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── StoryboardExample.xcscheme │ ├── StoryboardExampleTests/ │ │ ├── Info.plist │ │ └── StoryboardExampleTests.swift │ └── StoryboardExampleUITests/ │ ├── Info.plist │ └── StoryboardExampleUITests.swift ├── WMPageController-Swift/ │ ├── AppDelegate.swift │ ├── Assets.xcassets/ │ │ └── AppIcon.appiconset/ │ │ └── Contents.json │ ├── Base.lproj/ │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── TableViewController.swift │ └── ViewController.swift ├── WMPageController-Swift.podspec ├── WMPageController-Swift.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ ├── WMPageController-Swift.xcscheme │ └── WMPageControllerSwiftFramework.xcscheme ├── WMPageController-SwiftTests/ │ ├── Info.plist │ └── WMPageController_SwiftTests.swift ├── WMPageController-SwiftUITests/ │ ├── Info.plist │ └── WMPageController_SwiftUITests.swift └── WMPageControllerSwiftFramework/ ├── Info.plist └── WMPageControllerSwiftFramework.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Xcode # build/ *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata *.xccheckout *.moved-aside DerivedData *.hmap *.ipa *.xcuserstate # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control # # Pods/ # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build ================================================ FILE: .travis.yml ================================================ language: objective-c osx_image: xcode7.3 xcode_project: WMPageController-Swift.xcodeproj xcode_scheme: WMPageControllerSwiftFramework xcode_sdk: iphonesimulator9.3 env: global: - FRAMEWORK_NAME=WMPageControllerSwiftFramework before_install: - brew update - brew outdated carthage || brew upgrade carthage before_script: before_deploy: - carthage build --no-skip-current - carthage archive WMPageControllerSwift deploy: provider: releases api_key: secure: hxnNtDAGGZFHRMxJF02POFZfDZq7mjYd+B1osAtCXPmf7wE+Twk3+Ax4VuFR3bGrtYCbegaSWFsrxwG7JOtqTzDQ6eIJvvK85N6+//MX3iyloO/sbtljgDEdDDdjwKiIK3pQhnL9F7Rd+3fz5JAVPYIkNEO5E7BnwvDIWQOxK/QtW5fhBmuGM1+YacvsQX8f+MrHjKslIsZp5DRaXXLtyDlV8eKwHef127+nRmnvkPBHVA/ZQhVMLAdcuNvzl64XXryDgNQxCDCqNw60IiIFnMNtaN1G1H9JwF0mQBWm4Pn8Yua+KV8rVOyW3F39YXFCrfcBIfgqJpeB7bzJr7WD2p2G4y1x2yAiXn1Dc5TpCrhnLffoJ3MtyD2KbgD/kVsKOtnfWAdAHyKIbSTQIEpHfRLcr7beucANxoDK4VMtARPsz1WGyzNqUU+Chguj32B6IXKB3NMifXy7syBBT59ZJzUCbyp1Om/CAJDCChP8EsByFD8AhDSYfZKvfO3NK/x+qZdgxV3EOiCrcF9q7rACA32yyxXTa75J+LzcsgN/ESd9GPOC8E8t0I86JdwwRlROGUNjcSRFOcGZ50Rrdd2c5L42rD1OOkTzUCAnacj2U2ewnyDREQ0SQ7EYsrVl8Mtzglb1VNISrsgscx2gJwCZXtbWIitMdcGCv6K1mMB9HNg= file: WMPageControllerSwift.framework.zip on: repo: wangmchn/WMPageController-Swift ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Wang Ming Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: PageController/FloodView.swift ================================================ // // FooldView.swift // PageController // // Created by Mark on 15/10/20. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit class FloodView: ProgressView { // MARK: - Vars var hollow = false fileprivate var margin: CGFloat = 0.0 fileprivate var radius: CGFloat = 0.0 fileprivate var height: CGFloat = 0.0 // MARK: - Private funcs override func willMove(toSuperview newSuperview: UIView?) { height = frame.size.height margin = height * 0.15 radius = (height - margin * 2.0) / 2.0 } override func draw(_ rect: CGRect) { // Drawing code let currentIndex = Int(progress) let rate = progress - CGFloat(currentIndex) let nextIndex = (currentIndex + 1) >= itemFrames.count ? currentIndex : currentIndex + 1 let currentFrame = itemFrames[currentIndex] let currentWidth = currentFrame.size.width let currentX = currentFrame.origin.x let nextWidth = itemFrames[nextIndex].size.width let nextX = self.itemFrames[nextIndex].origin.x let startX = currentX + (nextX - currentX) * rate let endX = startX + currentWidth + (nextWidth - currentWidth) * rate let ctx = UIGraphicsGetCurrentContext() ctx?.translateBy(x: 0.0, y: height) ctx?.scaleBy(x: 1.0, y: -1.0) ctx?.addArc(center: CGPoint(x: startX + radius, y: height / 2.0), radius: radius, startAngle: CGFloat(Double.pi / 2), endAngle: CGFloat(Double.pi / 2) * 3, clockwise: false) // CGContextAddArc(ctx, startX + radius, height / 2.0, radius, CGFloat(M_PI_2), CGFloat(M_PI_2) * 3, 0) ctx?.addLine(to: CGPoint(x: endX - radius, y: margin)) ctx?.addArc(center: CGPoint(x: endX - radius, y: height / 2.0), radius: radius, startAngle: CGFloat(-Double.pi / 2), endAngle: CGFloat(Double.pi / 2), clockwise: false) // CGContextAddArc(ctx, endX - radius, height / 2.0, radius, CGFloat(-M_PI_2), CGFloat(M_PI_2), 0) ctx?.closePath() if hollow == true { ctx?.setStrokeColor(color) ctx?.strokePath() return } ctx?.closePath() ctx?.setFillColor(color) ctx?.fillPath() } } ================================================ FILE: PageController/MenuItem.swift ================================================ // // MenuItem.swift // PageController // // Created by Mark on 15/10/20. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit protocol MenuItemDelegate: NSObjectProtocol { func didSelectedMenuItem(_ menuItem: MenuItem) } class MenuItem: UILabel { // MARK: - Public vars var normalSize: CGFloat = 15.0 var selectedSize: CGFloat = 18.0 weak var delegate: MenuItemDelegate? var selected = false { didSet { rate = (selected == false) ? 0.0 : 1.0 } } var rate: CGFloat = 0.0 { didSet { let red = normalComponents.red + (selectedComponets.red - normalComponents.red) * rate let green = normalComponents.green + (selectedComponets.green - normalComponents.green) * rate let blue = normalComponents.blue + (selectedComponets.blue - normalComponents.blue) * rate let alpha = normalComponents.alpha + (selectedComponets.alpha - normalComponents.alpha) * rate let minScale = normalSize / selectedSize let trueScale = minScale + (1 - minScale) * rate textColor = UIColor(red: red, green: green, blue: blue, alpha: alpha) transform = CGAffineTransform(scaleX: trueScale, y: trueScale) } } var normalColor: UIColor? { didSet { normalColor?.getRed(&normalComponents.red, green: &normalComponents.green, blue: &normalComponents.blue, alpha: &normalComponents.alpha) } } var selectedColor: UIColor? { didSet { selectedColor?.getRed(&selectedComponets.red, green: &selectedComponets.green, blue: &selectedComponets.blue, alpha: &selectedComponets.alpha) } } // MARK: - Private vars fileprivate var normalComponents: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) = (0.0, 0.0, 0.0, 0.0) fileprivate var selectedComponets: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) = (0.0, 0.0, 0.0, 0.0) // MARK: - Public funcs func selectWithAnimation(_ select: Bool) -> Void { if selected == select { return } UIView.animate(withDuration: 0.3, animations: { () -> Void in if self.selected == true { self.rate = 0.0 } else { self.rate = 1.0 } self.selected = select }) } override init(frame: CGRect) { super.init(frame: frame) setup() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } // MARK: - Private funcs fileprivate func setup() { textAlignment = NSTextAlignment.center isUserInteractionEnabled = true backgroundColor = .clear numberOfLines = 0 } override func touchesEnded(_ touches: Set, with event: UIEvent?) { delegate?.didSelectedMenuItem(self) } } ================================================ FILE: PageController/MenuView.swift ================================================ // // MenuView.swift // PageController // // Created by Mark on 15/10/20. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit @objc public protocol MenuViewDelegate: NSObjectProtocol { func menuView(_ menuView: MenuView, widthForItemAtIndex index: Int) -> CGFloat @objc optional func menuView(_ menuView: MenuView, didSelectedIndex index: Int, fromIndex currentIndex: Int) @objc optional func menuView(_ menuView: MenuView, itemMarginAtIndex index: Int) -> CGFloat } @objc public protocol MenuViewDataSource: NSObjectProtocol { func menuView(_ menuView: MenuView, titleAtIndex index: Int) -> String func numbersOfTitlesInMenuView(_ menuView: MenuView) -> Int } public enum MenuViewStyle { case `default`, line, flood, fooldHollow } open class MenuView: UIView, MenuItemDelegate { // MARK: - Public vars override open var frame: CGRect { didSet { guard contentView != nil else { return } let rightMargin = (rightView == nil) ? contentMargin : contentMargin + rightView!.frame.width let leftMargin = (leftView == nil) ? contentMargin : contentMargin + leftView!.frame.width let contentWidth = contentView.frame.width + leftMargin + rightMargin let startX = (leftView != nil) ? leftView!.frame.origin.x : (contentView.frame.origin.x - contentMargin) // Make the contentView center, because system will change menuView's frame if it's a titleView. if (startX + contentWidth / 2 != bounds.width / 2) { let xOffset = (contentWidth - bounds.width) / 2 contentView.frame.origin.x -= xOffset rightView?.frame.origin.x -= xOffset leftView?.frame.origin.x -= xOffset } } } open weak var leftView: UIView? { willSet { leftView?.removeFromSuperview() } didSet { if let lView = leftView { addSubview(lView) } resetFrames() } } open weak var rightView: UIView? { willSet { rightView?.removeFromSuperview() } didSet { if let rView = rightView { addSubview(rView) } resetFrames() } } open var contentMargin: CGFloat = 0.0 { didSet { guard contentView != nil else { return } resetFrames() } } open var style = MenuViewStyle.default open var fontName: String? open var progressHeight: CGFloat = 2.0 open var normalSize: CGFloat = 15.0 open var selectedSize: CGFloat = 18.0 open var progressColor: UIColor? open weak var delegate: MenuViewDelegate? open weak var dataSource: MenuViewDataSource! open lazy var normalColor = UIColor.black open lazy var selectedColor = UIColor(red: 168.0/255.0, green: 20.0/255.0, blue: 4/255.0, alpha: 1.0) // MARK: - Private vars fileprivate weak var contentView: UIScrollView! fileprivate weak var progressView: ProgressView? fileprivate weak var selectedItem: MenuItem! fileprivate var itemFrames = [CGRect]() fileprivate let tagGap = 6250 fileprivate var itemsCount: Int { return dataSource.numbersOfTitlesInMenuView(self) } open func reload() { itemFrames.removeAll() progressView?.removeFromSuperview() for subview in contentView.subviews { subview.removeFromSuperview() } addMenuItems() addProgressView() } // MARK: - Public funcs open func slideMenuAtProgress(_ progress: CGFloat) { progressView?.progress = progress let tag = Int(progress) + tagGap let rate = progress - CGFloat(tag - tagGap) let currentItem = viewWithTag(tag) as? MenuItem let nextItem = viewWithTag(tag + 1) as? MenuItem if rate == 0.0 { selectedItem.selected = false selectedItem = currentItem selectedItem.selected = true refreshContentOffset() return } currentItem?.rate = 1.0 - rate nextItem?.rate = rate } open func selectItemAtIndex(_ index: Int) { let tag = index + tagGap let currentIndex = selectedItem.tag - tagGap guard currentIndex != index && selectedItem != nil else { return } let menuItem = viewWithTag(tag) as! MenuItem selectedItem.selected = false selectedItem = menuItem selectedItem.selected = true progressView?.moveToPosition(index, animation: false) delegate?.menuView?(self, didSelectedIndex: index, fromIndex: currentIndex) refreshContentOffset() } // MARK: - Update Title open func updateTitle(_ title: String, atIndex index: Int, andWidth update: Bool) { guard index >= 0 && index < itemsCount else { return } let item = viewWithTag(tagGap + index) as? MenuItem item?.text = title guard update else { return } resetFrames() } // MARK: - Update Frames open func resetFrames() { var contentFrame = bounds if let rView = rightView { var rightFrame = rView.frame rightFrame.origin.x = contentFrame.width - rightFrame.width rightView?.frame = rightFrame contentFrame.size.width -= rightFrame.width } if let lView = leftView { var leftFrame = lView.frame leftFrame.origin.x = 0 leftView?.frame = leftFrame contentFrame.origin.x += leftFrame.width contentFrame.size.width -= leftFrame.width } contentFrame.origin.x += contentMargin contentFrame.size.width -= contentMargin * 2 contentView.frame = contentFrame resetFramesFromIndex(0) refreshContentOffset() } open func resetFramesFromIndex(_ index: Int) { itemFrames.removeAll() calculateFrames() for i in index ..< itemsCount { let item = viewWithTag(tagGap + i) as? MenuItem item?.frame = itemFrames[i] } if let progress = progressView { var pFrame = progress.frame pFrame.size.width = contentView.contentSize.width if progress.isKind(of: FloodView.self) { pFrame.origin.y = 0 } else { pFrame.origin.y = frame.size.height - progressHeight } progress.frame = pFrame progress.itemFrames = itemFrames progress.setNeedsDisplay() } } // MARK: - Private funcs override open func willMove(toSuperview newSuperview: UIView?) { super.willMove(toSuperview: newSuperview) guard contentView == nil else { return } addScollView() addMenuItems() addProgressView() } fileprivate func refreshContentOffset() { let itemFrame = selectedItem.frame let itemX = itemFrame.origin.x let width = contentView.frame.size.width let contentWidth = contentView.contentSize.width if itemX > (width / 2) { var targetX: CGFloat = itemFrame.origin.x - width/2 + itemFrame.size.width/2 if (contentWidth - itemX) <= (width / 2) { targetX = contentWidth - width } if (targetX + width) > contentWidth { targetX = contentWidth - width } contentView.setContentOffset(CGPoint(x: targetX, y: 0), animated: true) } else { contentView.setContentOffset(CGPoint.zero, animated: true) } } // MARK: - Create Views fileprivate func addScollView() { let scrollViewFrame = CGRect(x: contentMargin, y: 0, width: frame.size.width - contentMargin * 2, height: frame.size.height) let scrollView = UIScrollView(frame: scrollViewFrame) scrollView.showsVerticalScrollIndicator = false scrollView.showsHorizontalScrollIndicator = false scrollView.backgroundColor = .clear scrollView.scrollsToTop = false addSubview(scrollView) contentView = scrollView } fileprivate func addMenuItems() { calculateFrames() for index in 0 ..< itemsCount { let menuItemFrame = itemFrames[index] let menuItem = MenuItem(frame: menuItemFrame) menuItem.tag = index + tagGap menuItem.delegate = self menuItem.text = dataSource.menuView(self, titleAtIndex: index) menuItem.textColor = normalColor if let optionalFontName = fontName { menuItem.font = UIFont(name: optionalFontName, size: selectedSize) } else { menuItem.font = UIFont.systemFont(ofSize: selectedSize) } menuItem.normalSize = normalSize menuItem.selectedSize = selectedSize menuItem.normalColor = normalColor menuItem.selectedColor = selectedColor menuItem.selected = (index == 0) ? true : false if index == 0 { selectedItem = menuItem } contentView.addSubview(menuItem) } } fileprivate func addProgressView() { var optionalType: ProgressView.Type? var hollow = false switch style { case .default: break case .line: optionalType = ProgressView.self case .fooldHollow: optionalType = FloodView.self hollow = true case .flood: optionalType = FloodView.self } if let viewType = optionalType { let pView = viewType.init() let height = (style == .line) ? progressHeight : frame.size.height let progressY = (style == .line) ? (frame.size.height - progressHeight) : 0 pView.frame = CGRect(x: 0, y: progressY, width: contentView.contentSize.width, height: height) pView.itemFrames = itemFrames if (progressColor == nil) { progressColor = selectedColor } pView.color = (progressColor?.cgColor)! pView.backgroundColor = .clear if let fooldView = pView as? FloodView { fooldView.hollow = hollow } contentView.insertSubview(pView, at: 0) progressView = pView } } // MARK: - Calculate Frames fileprivate func calculateFrames() { var contentWidth: CGFloat = itemMarginAtIndex(0) for index in 0 ..< itemsCount { let itemWidth = delegate!.menuView(self, widthForItemAtIndex: index) let itemFrame = CGRect(x: contentWidth, y: 0, width: itemWidth, height: frame.size.height) itemFrames.append(itemFrame) contentWidth += itemWidth + itemMarginAtIndex(index + 1) } if contentWidth < contentView.frame.size.width { let distance = contentView.frame.size.width - contentWidth let itemMargin = distance / CGFloat(itemsCount + 1) for index in 0 ..< itemsCount { var itemFrame = itemFrames[index] itemFrame.origin.x += itemMargin * CGFloat(index + 1) itemFrames[index] = itemFrame } contentWidth = contentView.frame.size.width } contentView.contentSize = CGSize(width: contentWidth, height: frame.size.height) } fileprivate func itemMarginAtIndex(_ index: Int) -> CGFloat { if let itemMargin = delegate?.menuView?(self, itemMarginAtIndex: index) { return itemMargin } return 0.0 } // MARK: - MenuItemDelegate func didSelectedMenuItem(_ menuItem: MenuItem) { if selectedItem == menuItem { return } let position = menuItem.tag - tagGap let currentIndex = selectedItem.tag - tagGap progressView?.moveToPosition(position, animation: true) delegate?.menuView?(self, didSelectedIndex: position, fromIndex: currentIndex) menuItem.selectWithAnimation(true) selectedItem.selectWithAnimation(false) selectedItem = menuItem refreshContentOffset() } } ================================================ FILE: PageController/PageController.swift ================================================ // // PageController.swift // PageController // // Created by Mark on 15/10/20. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit public enum CachePolicy: Int { case noLimit = 0 case lowMemory = 1 case balanced = 3 case high = 5 } public enum PreloadPolicy: Int { case never = 0 case neighbour = 1 case near = 2 } public let WMPageControllerDidMovedToSuperViewNotification = "WMPageControllerDidMovedToSuperViewNotification" public let WMPageControllerDidFullyDisplayedNotification = "WMPageControllerDidFullyDisplayedNotification" @objc public protocol PageControllerDataSource: NSObjectProtocol { @objc optional func numberOfControllersInPageController(_ pageController: PageController) -> Int @objc optional func pageController(_ pageController: PageController, viewControllerAtIndex index: Int) -> UIViewController @objc optional func pageController(_ pageController: PageController, titleAtIndex index: Int) -> String } @objc public protocol PageControllerDelegate: NSObjectProtocol { @objc optional func pageController(_ pageController: PageController, lazyLoadViewController viewController: UIViewController, withInfo info: NSDictionary) @objc optional func pageController(_ pageController: PageController, willCachedViewController viewController: UIViewController, withInfo info: NSDictionary) @objc optional func pageController(_ pageController: PageController, willEnterViewController viewController: UIViewController, withInfo info: NSDictionary) @objc optional func pageController(_ pageController: PageController, didEnterViewController viewController: UIViewController, withInfo info: NSDictionary) } open class ContentView: UIScrollView, UIGestureRecognizerDelegate { open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { guard let wrapperView = NSClassFromString("UITableViewWrapperView"), let otherGestureView = otherGestureRecognizer.view else { return false } if otherGestureView.isKind(of: wrapperView) && (otherGestureRecognizer is UIPanGestureRecognizer) { return true } return false } } open class PageController: UIViewController, UIScrollViewDelegate, MenuViewDelegate, MenuViewDataSource, PageControllerDelegate, PageControllerDataSource { // MARK: - Public vars open weak var dataSource: PageControllerDataSource? open weak var delegate: PageControllerDelegate? open var viewControllerClasses: [UIViewController.Type]? open var titles: [String]? open var values: NSArray? open var keys: [String]? open var progressColor: UIColor? open var progressHeight: CGFloat = 2.0 open var itemMargin: CGFloat = 0.0 open var menuViewStyle = MenuViewStyle.default open var titleFontName: String? open var pageAnimatable = false open var postNotification = false open var bounces = false open var showOnNavigationBar = false open var startDragging = false open var titleSizeSelected: CGFloat = 18.0 open var titleSizeNormal: CGFloat = 15.0 open var menuHeight: CGFloat = 30.0 open var menuItemWidth: CGFloat = 65.0 open weak var contentView: ContentView? open weak var menuView: MenuView? open var itemsWidths: [CGFloat]? open fileprivate(set) var currentViewController: UIViewController? open var selectedIndex: Int { set { _selectedIndex = newValue menuView?.selectItemAtIndex(newValue) } get { return _selectedIndex } } open var menuViewContentMargin: CGFloat = 0.0 { didSet { guard let menu = menuView else { return } menu.contentMargin = oldValue } } open var viewFrame = CGRect() { didSet { if let _ = menuView { hasInit = false viewDidLayoutSubviews() } } } open var itemsMargins: [CGFloat]? open var preloadPolicy: PreloadPolicy = .never open var cachePolicy: CachePolicy = .noLimit { didSet { memCache.countLimit = cachePolicy.rawValue } } open lazy var titleColorSelected = UIColor(red: 168.0/255.0, green: 20.0/255.0, blue: 4/255.0, alpha: 1.0) open lazy var titleColorNormal = UIColor.black open lazy var menuBGColor = UIColor(red: 244.0/255.0, green: 244.0/255.0, blue: 244.0/255.0, alpha: 1.0) override open var edgesForExtendedLayout: UIRectEdge { didSet { hasInit = false viewDidLayoutSubviews() } } // MARK: - Private vars fileprivate var memoryWarningCount = 0 fileprivate var viewHeight: CGFloat = 0.0 fileprivate var viewWidth: CGFloat = 0.0 fileprivate var viewX: CGFloat = 0.0 fileprivate var viewY: CGFloat = 0.0 fileprivate var _selectedIndex = 0 fileprivate var targetX: CGFloat = 0.0 fileprivate var superviewHeight: CGFloat = 0.0 fileprivate var hasInit = false fileprivate var shouldNotScroll = false fileprivate var initializedIndex = -1 fileprivate var controllerCount = -1 fileprivate var childControllersCount: Int { if controllerCount == -1 { if let count = dataSource?.numberOfControllersInPageController?(self) { controllerCount = count } else { controllerCount = (viewControllerClasses?.count ?? 0) } } return controllerCount } lazy fileprivate var displayingControllers = NSMutableDictionary() lazy fileprivate var memCache = NSCache() lazy fileprivate var childViewFrames = [CGRect]() // MARK: - Life cycle public convenience init(vcClasses: [UIViewController.Type], theirTitles: [String]) { self.init() assert(vcClasses.count == theirTitles.count, "`vcClasses.count` must equal to `titles.count`") titles = theirTitles viewControllerClasses = vcClasses } override open func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white guard childControllersCount > 0 else { return } calculateSize() addScrollView() addViewControllerAtIndex(_selectedIndex) currentViewController = displayingControllers[_selectedIndex] as? UIViewController addMenuView() } override open func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() guard childControllersCount > 0 else { return } let oldSuperviewHeight = superviewHeight superviewHeight = view.frame.size.height guard (!hasInit || superviewHeight != oldSuperviewHeight) && (view.window != nil) else { return } calculateSize() adjustScrollViewFrame() adjustMenuViewFrame() removeSuperfluousViewControllersIfNeeded() currentViewController?.view.frame = childViewFrames[_selectedIndex] hasInit = true view.layoutIfNeeded() } override open func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) guard childControllersCount > 0 else { return } postFullyDisplayedNotificationWithIndex(_selectedIndex) didEnterController(currentViewController!, atIndex: _selectedIndex) } override open func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() memoryWarningCount += 1 cachePolicy = CachePolicy.lowMemory NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(PageController.growCachePolicyAfterMemoryWarning), object: nil) NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(PageController.growCachePolicyToHigh), object: nil) memCache.removeAllObjects() if memoryWarningCount < 3 { perform(#selector(PageController.growCachePolicyAfterMemoryWarning), with: nil, afterDelay: 3.0, inModes: [RunLoopMode.commonModes]) } } // MARK: - Reload open func reloadData() { clearDatas() resetScrollView() memCache.removeAllObjects() viewDidLayoutSubviews() resetMenuView() } // MARK: - Update Title open func updateTitle(_ title: String, atIndex index: Int) { menuView?.updateTitle(title, atIndex: index, andWidth: false) } open func updateTitle(_ title: String, atIndex index: Int, andWidth width: CGFloat) { if var widths = itemsWidths { guard index < widths.count else { return } widths[index] = width itemsWidths = widths } else { var widths = [CGFloat]() for i in 0 ..< childControllersCount { let newWidth = (i == index) ? width : menuItemWidth widths.append(newWidth) } itemsWidths = widths } menuView?.updateTitle(title, atIndex: index, andWidth: true) } // MARK: - Data Source fileprivate func initializeViewControllerAtIndex(_ index: Int) -> UIViewController { if let viewController = dataSource?.pageController?(self, viewControllerAtIndex: index) { return viewController } return viewControllerClasses![index].init() } fileprivate func titleAtIndex(_ index: Int) -> String { if let titleAtIndex = dataSource?.pageController?(self, titleAtIndex: index) { return titleAtIndex } return titles![index] } // MARK: - Delegate fileprivate func infoWithIndex(_ index: Int) -> NSDictionary { let title = titleAtIndex(index) return ["title": title, "index": index] } fileprivate func willCachedController(_ vc: UIViewController, atIndex index: Int) { guard childControllersCount > 0 else { return } delegate?.pageController?(self, willCachedViewController: vc, withInfo: infoWithIndex(index)) } fileprivate func willEnterController(_ vc: UIViewController, atIndex index: Int) { guard childControllersCount > 0 else { return } delegate?.pageController?(self, willEnterViewController: vc, withInfo: infoWithIndex(index)) } fileprivate func didEnterController(_ vc: UIViewController, atIndex index: Int) { guard childControllersCount > 0 else { return } let info = infoWithIndex(index) delegate?.pageController?(self, didEnterViewController: vc, withInfo: info) if initializedIndex == index { delegate?.pageController?(self, lazyLoadViewController: vc, withInfo: info) initializedIndex = -1 } if preloadPolicy == .never { return } var start = 0 var end = childControllersCount - 1 if index > preloadPolicy.rawValue { start = index - preloadPolicy.rawValue } if childControllersCount - 1 > preloadPolicy.rawValue + index { end = index + preloadPolicy.rawValue } for i in start ... end { if memCache.object(forKey: NSNumber(integerLiteral: i)) == nil && displayingControllers[i] == nil { addViewControllerAtIndex(i) postMovedToSuperViewNotificationWithIndex(i) } } _selectedIndex = index } // MARK: - Private funcs fileprivate func clearDatas() { controllerCount = -1 hasInit = false _selectedIndex = _selectedIndex < childControllersCount ? _selectedIndex : childControllersCount - 1 for viewController in displayingControllers.allValues { if let vc = viewController as? UIViewController { vc.view.removeFromSuperview() vc.willMove(toParentViewController: nil) vc.removeFromParentViewController() } } memoryWarningCount = 0 NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(PageController.growCachePolicyAfterMemoryWarning), object: nil) NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(PageController.growCachePolicyToHigh), object: nil) currentViewController = nil displayingControllers.removeAllObjects() calculateSize() } fileprivate func resetScrollView() { contentView?.removeFromSuperview() addScrollView() addViewControllerAtIndex(_selectedIndex) currentViewController = displayingControllers[_selectedIndex] as? UIViewController } fileprivate func calculateSize() { var navBarHeight = (navigationController != nil) ? navigationController!.navigationBar.frame.maxY : 0 let tabBar = tabBarController?.tabBar ?? (navigationController?.toolbar ?? nil) let height = (tabBar != nil && tabBar?.isHidden != true) ? tabBar!.frame.height : 0 var tabBarHeight = (hidesBottomBarWhenPushed == true) ? 0 : height let mainWindow = UIApplication.shared.delegate?.window! let absoluteRect = view.superview?.convert(view.frame, to: mainWindow) if let rect = absoluteRect { navBarHeight -= rect.origin.y; tabBarHeight -= mainWindow!.frame.height - rect.maxY; } viewX = viewFrame.origin.x viewY = viewFrame.origin.y if viewFrame == CGRect.zero { viewWidth = view.frame.size.width viewHeight = view.frame.size.height - menuHeight - navBarHeight - tabBarHeight viewY += navBarHeight } else { viewWidth = viewFrame.size.width viewHeight = viewFrame.size.height - menuHeight } if showOnNavigationBar && (navigationController?.navigationBar != nil) { viewHeight += menuHeight } childViewFrames.removeAll() for index in 0 ..< childControllersCount { let viewControllerFrame = CGRect(x: CGFloat(index) * viewWidth, y: 0, width: viewWidth, height: viewHeight) childViewFrames.append(viewControllerFrame) } } fileprivate func addScrollView() { let scrollView = ContentView() scrollView.scrollsToTop = false scrollView.isPagingEnabled = true scrollView.delegate = self scrollView.showsVerticalScrollIndicator = false scrollView.showsHorizontalScrollIndicator = false scrollView.bounces = bounces view.addSubview(scrollView) contentView = scrollView } fileprivate func addMenuView() { var menuY = viewY if showOnNavigationBar && (navigationController?.navigationBar != nil) { let naviHeight = navigationController!.navigationBar.frame.height let realMenuHeight = menuHeight > naviHeight ? naviHeight : menuHeight menuY = (naviHeight - realMenuHeight) / 2 } let menuViewFrame = CGRect(x: viewX, y: menuY, width: viewWidth, height: menuHeight) let menu = MenuView(frame: menuViewFrame) menu.delegate = self menu.dataSource = self menu.backgroundColor = menuBGColor menu.normalSize = titleSizeNormal menu.selectedSize = titleSizeSelected menu.normalColor = titleColorNormal menu.selectedColor = titleColorSelected menu.style = menuViewStyle menu.progressHeight = progressHeight menu.progressColor = progressColor menu.fontName = titleFontName menu.contentMargin = menuViewContentMargin if showOnNavigationBar && (navigationController?.navigationBar != nil) { navigationItem.titleView = menu } else { view.addSubview(menu) } menuView = menu } fileprivate func postMovedToSuperViewNotificationWithIndex(_ index: Int) { guard postNotification else { return } let info = ["index": index, "title": titleAtIndex(index)] as [String : Any] NotificationCenter.default.post(name: Notification.Name(rawValue: WMPageControllerDidMovedToSuperViewNotification), object: info) } fileprivate func postFullyDisplayedNotificationWithIndex(_ index: Int) { guard postNotification else { return } let info = ["index": index, "title": titleAtIndex(index)] as [String : Any] NotificationCenter.default.post(name: Notification.Name(rawValue: WMPageControllerDidFullyDisplayedNotification), object: info) } fileprivate func layoutChildViewControllers() { let currentPage = Int(contentView!.contentOffset.x / viewWidth) let start = currentPage == 0 ? currentPage : (currentPage - 1) let end = (currentPage == childControllersCount - 1) ? currentPage : (currentPage + 1) for index in start ... end { let viewControllerFrame = childViewFrames[index] var vc = displayingControllers.object(forKey: index) if inScreen(viewControllerFrame) { if vc == nil { vc = memCache.object(forKey: NSNumber(integerLiteral: index)) if let viewController = vc as? UIViewController { addCachedViewController(viewController, atIndex: index) } else { addViewControllerAtIndex(index) } postMovedToSuperViewNotificationWithIndex(index) } } else { if let viewController = vc as? UIViewController { removeViewController(viewController, atIndex: index) } } } } fileprivate func removeSuperfluousViewControllersIfNeeded() { for (index, vc) in displayingControllers { let frame = childViewFrames[(index as AnyObject).intValue] if (inScreen(frame) == false) { removeViewController(vc as! UIViewController, atIndex: (index as AnyObject).intValue) } } } fileprivate func addCachedViewController(_ viewController: UIViewController, atIndex index: Int) { addChildViewController(viewController) viewController.view.frame = childViewFrames[index] viewController.didMove(toParentViewController: self) contentView?.addSubview(viewController.view) willEnterController(viewController, atIndex: index) displayingControllers.setObject(viewController, forKey: index as NSCopying) } fileprivate func addViewControllerAtIndex(_ index: Int) { initializedIndex = index let viewController = initializeViewControllerAtIndex(index) if let optionalKeys = keys { viewController.setValue(values?[index], forKey: optionalKeys[index]) } addChildViewController(viewController) viewController.view.frame = childViewFrames.count > 0 ? childViewFrames[index] : view.frame viewController.didMove(toParentViewController: self) contentView?.addSubview(viewController.view) willEnterController(viewController, atIndex: index) displayingControllers.setObject(viewController, forKey: index as NSCopying) } fileprivate func removeViewController(_ viewController: UIViewController, atIndex index: Int) { viewController.view.removeFromSuperview() viewController.willMove(toParentViewController: nil) viewController.removeFromParentViewController() displayingControllers.removeObject(forKey: index) if memCache.object(forKey: NSNumber(integerLiteral: index)) == nil { willCachedController(viewController, atIndex: index) memCache.setObject(viewController, forKey: NSNumber(integerLiteral: index)) } } fileprivate func inScreen(_ frame: CGRect) -> Bool { let x = frame.origin.x let ScreenWidth = contentView!.frame.size.width let contentOffsetX = contentView!.contentOffset.x if (frame.maxX > contentOffsetX) && (x - contentOffsetX < ScreenWidth) { return true } return false } fileprivate func resetMenuView() { if menuView == nil { addMenuView() return } menuView?.reload() guard selectedIndex != 0 else { return } menuView?.selectItemAtIndex(selectedIndex) view.bringSubview(toFront: menuView!) } @objc fileprivate func growCachePolicyAfterMemoryWarning() { cachePolicy = CachePolicy.balanced perform(#selector(PageController.growCachePolicyToHigh), with: nil, afterDelay: 2.0, inModes: [RunLoopMode.commonModes]) } @objc fileprivate func growCachePolicyToHigh() { cachePolicy = CachePolicy.high } // MARK: - Adjust Frame fileprivate func adjustScrollViewFrame() { shouldNotScroll = true var scrollFrame = CGRect(x: viewX, y: viewY + menuHeight, width: viewWidth, height: viewHeight) scrollFrame.origin.y -= showOnNavigationBar && (navigationController?.navigationBar != nil) ? menuHeight : 0 contentView?.frame = scrollFrame contentView?.contentSize = CGSize(width: CGFloat(childControllersCount) * viewWidth, height: 0) contentView?.contentOffset = CGPoint(x: CGFloat(_selectedIndex) * viewWidth, y: 0) shouldNotScroll = false } fileprivate func adjustMenuViewFrame() { var realMenuHeight = menuHeight var menuX = viewX var menuY = viewY var rightWidth: CGFloat = 0.0 if showOnNavigationBar && (navigationController?.navigationBar != nil) { for subview in (navigationController?.navigationBar.subviews)! { guard let UINavigationBarBackgroundClass = NSClassFromString("_UINavigationBarBackground") else { continue } guard !subview.isKind(of: UINavigationBarBackgroundClass) && !subview.isKind(of: MenuView.self) && (subview.alpha != 0) && (subview.isHidden == false) else { continue } let maxX = subview.frame.maxX if maxX < viewWidth / 2 { let leftWidth = maxX menuX = menuX > leftWidth ? menuX : leftWidth } let minX = subview.frame.minX if minX > viewWidth / 2 { let width = viewWidth - minX rightWidth = rightWidth > width ? rightWidth : width } } let naviHeight = navigationController!.navigationBar.frame.height realMenuHeight = menuHeight > naviHeight ? naviHeight : realMenuHeight menuY = (naviHeight - realMenuHeight) / 2 } let menuWidth = viewWidth - menuX - rightWidth menuView?.frame = CGRect(x: menuX, y: menuY, width: menuWidth, height: realMenuHeight) menuView?.resetFrames() if _selectedIndex != 0 { menuView?.selectItemAtIndex(_selectedIndex) } } // MARK: - UIScrollView Delegate open func scrollViewDidScroll(_ scrollView: UIScrollView) { if shouldNotScroll || !hasInit { return } layoutChildViewControllers() guard startDragging else { return } var contentOffsetX = contentView!.contentOffset.x if contentOffsetX < 0.0 { contentOffsetX = 0.0 } if contentOffsetX > (scrollView.contentSize.width - viewWidth) { contentOffsetX = scrollView.contentSize.width - viewWidth } let rate = contentOffsetX / viewWidth menuView?.slideMenuAtProgress(rate) if scrollView.contentOffset.y == 0 { return } var contentOffset = scrollView.contentOffset contentOffset.y = 0.0 scrollView.contentOffset = contentOffset } open func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { startDragging = true menuView?.isUserInteractionEnabled = false } open func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { menuView?.isUserInteractionEnabled = true _selectedIndex = Int(contentView!.contentOffset.x / viewWidth) removeSuperfluousViewControllersIfNeeded() currentViewController = displayingControllers[_selectedIndex] as? UIViewController postFullyDisplayedNotificationWithIndex(_selectedIndex) didEnterController(currentViewController!, atIndex: _selectedIndex) } open func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { _selectedIndex = Int(contentView!.contentOffset.x / viewWidth) removeSuperfluousViewControllersIfNeeded() currentViewController = displayingControllers[_selectedIndex] as? UIViewController postFullyDisplayedNotificationWithIndex(_selectedIndex) didEnterController(currentViewController!, atIndex: _selectedIndex) } open func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { guard decelerate == false else { return } menuView?.isUserInteractionEnabled = true let rate = targetX / viewWidth menuView?.slideMenuAtProgress(rate) } open func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { targetX = targetContentOffset.pointee.x } // MARK: - MenuViewDelegate open func menuView(_ menuView: MenuView, didSelectedIndex index: Int, fromIndex currentIndex: Int) { guard hasInit else { return } startDragging = false let targetPoint = CGPoint(x: CGFloat(index) * viewWidth, y: 0) contentView?.setContentOffset(targetPoint, animated: pageAnimatable) if !pageAnimatable { removeSuperfluousViewControllersIfNeeded() if let viewController = displayingControllers[index] as? UIViewController { removeViewController(viewController, atIndex: index) } layoutChildViewControllers() currentViewController = displayingControllers[index] as? UIViewController postFullyDisplayedNotificationWithIndex(index) _selectedIndex = index didEnterController(currentViewController!, atIndex: _selectedIndex) } } open func menuView(_ menuView: MenuView, widthForItemAtIndex index: Int) -> CGFloat { if let widths = itemsWidths { return widths[index] } return menuItemWidth } open func menuView(_ menuView: MenuView, itemMarginAtIndex index: Int) -> CGFloat { if let margins = itemsMargins { return margins[index] } return itemMargin } // MARK: - MenuViewDataSource open func numbersOfTitlesInMenuView(_ menuView: MenuView) -> Int { return childControllersCount } open func menuView(_ menuView: MenuView, titleAtIndex index: Int) -> String { return titleAtIndex(index) } } ================================================ FILE: PageController/ProgressView.swift ================================================ // // ProgressView.swift // PageController // // Created by Mark on 15/10/20. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit class ProgressView: UIView { // MARK: - Public vars var itemFrames = [CGRect]() var progress: CGFloat = 0.0 { didSet { setNeedsDisplay() } } lazy var color: CGColor = UIColor.brown.cgColor // MARK: - Private vars weak fileprivate var link: CADisplayLink? fileprivate var gap: CGFloat = 0.0 fileprivate var step: CGFloat = 0.0 fileprivate var sign = 1 // MARK: - Public funcs func moveToPosition(_ position: Int, animation: Bool) { if animation == false { progress = CGFloat(position) return } let pos = CGFloat(position) gap = fabs(progress - pos) sign = progress > pos ? -1 : 1 step = gap / 15.0 link?.remove(from: RunLoop.main, forMode: RunLoopMode.commonModes) let tempLink = CADisplayLink(target: self, selector: #selector(ProgressView.progressChanged)) tempLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) link = tempLink } func progressChanged() { if gap > 0.000001 { gap -= step if gap < 0.0 { progress = blurredCeil(progress + CGFloat(sign) * step ) return } progress += CGFloat(sign) * step } else { progress = blurredCeil(progress) link?.invalidate() link = nil } } fileprivate func blurredCeil(_ num: CGFloat) -> CGFloat { let p = num + 0.5 return floor(p) } // MARK: - Private funcs override func draw(_ rect: CGRect) { // Drawing code let ctx = UIGraphicsGetCurrentContext() let index = Int(progress) let rate = progress - CGFloat(index) let currentFrame = itemFrames[index] let currentWidth = currentFrame.size.width let nextIndex = (index + 1 < itemFrames.count) ? index + 1 : index let nextWidth = itemFrames[nextIndex].size.width let height = frame.size.height let constY = height / 2 let currentX = currentFrame.origin.x let nextX = itemFrames[nextIndex].origin.x let startX = currentX + (nextX - currentX) * rate let endX = startX + currentWidth + (nextWidth - currentWidth) * rate ctx?.move(to: CGPoint(x: startX, y: constY)) ctx?.addLine(to: CGPoint(x: endX, y: constY)) ctx?.setLineWidth(height) ctx?.setStrokeColor(color) ctx?.strokePath() } } ================================================ FILE: README.md ================================================ # WMPageController-Swift [![Build Status](https://travis-ci.org/wangmchn/WMPageController-Swift.svg?branch=master)](https://travis-ci.org/wangmchn/WMPageController-Swift) [![Platform](http://img.shields.io/badge/platform-iOS-blue.svg?style=flat )](https://developer.apple.com/iphone/index.action) [![License](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat )](http://mit-license.org) ![CocoaPods Version](https://img.shields.io/badge/pod-v0.36.4-brightgreen.svg) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) An easy solution to page controllers like NetEase News.(Swift Implementation)
## Objective-C Version Click here: https://github.com/wangmchn/WMPageController ## How to use [Objective-C README](https://github.com/wangmchn/WMPageController/blob/master/README.md) ## CocoaPods ``` pod 'WMPageController-Swift', '~> 1.3.3' ``` ================================================ FILE: StoryboardExample/StoryboardExample/AppDelegate.swift ================================================ // // AppDelegate.swift // StoryboardExample // // Created by Mark on 16/1/4. // Copyright © 2016年 Wecan Studio. All rights reserved. // import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. self.window?.backgroundColor = .whiteColor() return true } func applicationWillResignActive(application: UIApplication) { // 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. // 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. } func applicationDidEnterBackground(application: UIApplication) { // 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. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(application: UIApplication) { // 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. } func applicationDidBecomeActive(application: UIApplication) { // 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. } func applicationWillTerminate(application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } } ================================================ FILE: StoryboardExample/StoryboardExample/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: StoryboardExample/StoryboardExample/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: StoryboardExample/StoryboardExample/Base.lproj/Main.storyboard ================================================ ================================================ FILE: StoryboardExample/StoryboardExample/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: StoryboardExample/StoryboardExample/ParentController/CustomPageController.swift ================================================ // // CustomPageController.swift // StoryboardExample // // Created by Mark on 16/1/4. // Copyright © 2016年 Wecan Studio. All rights reserved. // import UIKit class CustomPageController: PageController { var vcTitles = ["use", "storyboard", "xib"] required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) dataSource = self delegate = self preloadPolicy = PreloadPolicy.Neighbour menuViewContentMargin = 10 } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. menuView?.leftView = customButtonWithTitle("Left") menuView?.rightView = customButtonWithTitle("Right") let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))) dispatch_after(delayTime, dispatch_get_main_queue()) { self.vcTitles = ["Test", "Test", "Test", "Test", "Test", "Test"] self.reloadData() } } private func customButtonWithTitle(title: String) -> UIButton { let button = UIButton(frame: CGRect(x: 0, y: 0, width: 60, height: menuHeight)) button.addTarget(self, action: #selector(CustomPageController.buttonPressed(_:)), forControlEvents: UIControlEvents.TouchUpInside) button.setTitle(title, forState: UIControlState.Normal) button.setTitleColor(.blueColor(), forState: UIControlState.Normal) return button } @objc private func buttonPressed(sender: UIButton) { print(sender) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - PageController DataSource func numberOfControllersInPageController(pageController: PageController) -> Int { return vcTitles.count } func pageController(pageController: PageController, titleAtIndex index: Int) -> String { return vcTitles[index] } func pageController(pageController: PageController, viewControllerAtIndex index: Int) -> UIViewController { let sb = UIStoryboard(name: "Main", bundle: nil) switch index { case 0: return sb.instantiateViewControllerWithIdentifier("ViewController") case 1: return sb.instantiateViewControllerWithIdentifier("TableViewController") default: return UIViewController() } } func pageController(pageController: PageController, lazyLoadViewController viewController: UIViewController, withInfo info: NSDictionary) { print(info) } override func menuView(menuView: MenuView, widthForItemAtIndex index: Int) -> CGFloat { if index == 1 { return 100 } return 60 } } ================================================ FILE: StoryboardExample/StoryboardExample/TableViewController.swift ================================================ // // TableViewController.swift // StoryboardExample // // Created by Mark on 16/1/4. // Copyright © 2016年 Wecan Studio. All rights reserved. // import UIKit class TableViewController: UITableViewController { let reuseIdentifier = "reuseIdentifier" override func viewDidLoad() { super.viewDidLoad() tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: reuseIdentifier) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - Table view data source override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 100 } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) cell.textLabel?.text = "This is a TableViewController from Storyboard" cell.textLabel?.font = UIFont.systemFontOfSize(15) return cell } } ================================================ FILE: StoryboardExample/StoryboardExample/ViewController.swift ================================================ // // ViewController.swift // StoryboardExample // // Created by Mark on 16/1/4. // Copyright © 2016年 Wecan Studio. All rights reserved. // import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } ================================================ FILE: StoryboardExample/StoryboardExample.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 4DCCF83D1CE8558A00C31A07 /* FooldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8381CE8558A00C31A07 /* FooldView.swift */; }; 4DCCF83E1CE8558A00C31A07 /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8391CE8558A00C31A07 /* MenuItem.swift */; }; 4DCCF83F1CE8558A00C31A07 /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF83A1CE8558A00C31A07 /* MenuView.swift */; }; 4DCCF8401CE8558A00C31A07 /* PageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF83B1CE8558A00C31A07 /* PageController.swift */; }; 4DCCF8411CE8558A00C31A07 /* ProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF83C1CE8558A00C31A07 /* ProgressView.swift */; }; 4DF0A9781C39847100731373 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF0A9771C39847100731373 /* AppDelegate.swift */; }; 4DF0A97A1C39847100731373 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF0A9791C39847100731373 /* ViewController.swift */; }; 4DF0A97D1C39847100731373 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4DF0A97B1C39847100731373 /* Main.storyboard */; }; 4DF0A97F1C39847100731373 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4DF0A97E1C39847100731373 /* Assets.xcassets */; }; 4DF0A9821C39847100731373 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4DF0A9801C39847100731373 /* LaunchScreen.storyboard */; }; 4DF0A98D1C39847100731373 /* StoryboardExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF0A98C1C39847100731373 /* StoryboardExampleTests.swift */; }; 4DF0A9981C39847100731373 /* StoryboardExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF0A9971C39847100731373 /* StoryboardExampleUITests.swift */; }; 4DF0A9B21C3984EB00731373 /* CustomPageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF0A9B11C3984EB00731373 /* CustomPageController.swift */; }; 4DF0A9B51C3986D600731373 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF0A9B41C3986D600731373 /* TableViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 4DF0A9891C39847100731373 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4DF0A96C1C39847100731373 /* Project object */; proxyType = 1; remoteGlobalIDString = 4DF0A9731C39847100731373; remoteInfo = StoryboardExample; }; 4DF0A9941C39847100731373 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4DF0A96C1C39847100731373 /* Project object */; proxyType = 1; remoteGlobalIDString = 4DF0A9731C39847100731373; remoteInfo = StoryboardExample; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 4DCCF8381CE8558A00C31A07 /* FooldView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FooldView.swift; sourceTree = ""; }; 4DCCF8391CE8558A00C31A07 /* MenuItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; }; 4DCCF83A1CE8558A00C31A07 /* MenuView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = ""; }; 4DCCF83B1CE8558A00C31A07 /* PageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageController.swift; sourceTree = ""; }; 4DCCF83C1CE8558A00C31A07 /* ProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressView.swift; sourceTree = ""; }; 4DF0A9741C39847100731373 /* StoryboardExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StoryboardExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4DF0A9771C39847100731373 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4DF0A9791C39847100731373 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 4DF0A97C1C39847100731373 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 4DF0A97E1C39847100731373 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4DF0A9811C39847100731373 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 4DF0A9831C39847100731373 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4DF0A9881C39847100731373 /* StoryboardExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StoryboardExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 4DF0A98C1C39847100731373 /* StoryboardExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryboardExampleTests.swift; sourceTree = ""; }; 4DF0A98E1C39847100731373 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4DF0A9931C39847100731373 /* StoryboardExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StoryboardExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 4DF0A9971C39847100731373 /* StoryboardExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryboardExampleUITests.swift; sourceTree = ""; }; 4DF0A9991C39847100731373 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4DF0A9B11C3984EB00731373 /* CustomPageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CustomPageController.swift; path = ParentController/CustomPageController.swift; sourceTree = ""; }; 4DF0A9B41C3986D600731373 /* TableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 4DF0A9711C39847100731373 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4DF0A9851C39847100731373 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4DF0A9901C39847100731373 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 4DCCF8371CE8558A00C31A07 /* PageController */ = { isa = PBXGroup; children = ( 4DCCF8381CE8558A00C31A07 /* FooldView.swift */, 4DCCF8391CE8558A00C31A07 /* MenuItem.swift */, 4DCCF83A1CE8558A00C31A07 /* MenuView.swift */, 4DCCF83B1CE8558A00C31A07 /* PageController.swift */, 4DCCF83C1CE8558A00C31A07 /* ProgressView.swift */, ); name = PageController; path = ../../PageController; sourceTree = ""; }; 4DF0A96B1C39847100731373 = { isa = PBXGroup; children = ( 4DF0A9761C39847100731373 /* StoryboardExample */, 4DF0A98B1C39847100731373 /* StoryboardExampleTests */, 4DF0A9961C39847100731373 /* StoryboardExampleUITests */, 4DF0A9751C39847100731373 /* Products */, ); sourceTree = ""; }; 4DF0A9751C39847100731373 /* Products */ = { isa = PBXGroup; children = ( 4DF0A9741C39847100731373 /* StoryboardExample.app */, 4DF0A9881C39847100731373 /* StoryboardExampleTests.xctest */, 4DF0A9931C39847100731373 /* StoryboardExampleUITests.xctest */, ); name = Products; sourceTree = ""; }; 4DF0A9761C39847100731373 /* StoryboardExample */ = { isa = PBXGroup; children = ( 4DCCF8371CE8558A00C31A07 /* PageController */, 4DF0A9B31C3986B800731373 /* ChildControllers */, 4DF0A9B01C3984BA00731373 /* ParentController */, 4DF0A9771C39847100731373 /* AppDelegate.swift */, 4DF0A97B1C39847100731373 /* Main.storyboard */, 4DF0A97E1C39847100731373 /* Assets.xcassets */, 4DF0A9801C39847100731373 /* LaunchScreen.storyboard */, 4DF0A9831C39847100731373 /* Info.plist */, ); path = StoryboardExample; sourceTree = ""; }; 4DF0A98B1C39847100731373 /* StoryboardExampleTests */ = { isa = PBXGroup; children = ( 4DF0A98C1C39847100731373 /* StoryboardExampleTests.swift */, 4DF0A98E1C39847100731373 /* Info.plist */, ); path = StoryboardExampleTests; sourceTree = ""; }; 4DF0A9961C39847100731373 /* StoryboardExampleUITests */ = { isa = PBXGroup; children = ( 4DF0A9971C39847100731373 /* StoryboardExampleUITests.swift */, 4DF0A9991C39847100731373 /* Info.plist */, ); path = StoryboardExampleUITests; sourceTree = ""; }; 4DF0A9B01C3984BA00731373 /* ParentController */ = { isa = PBXGroup; children = ( 4DF0A9B11C3984EB00731373 /* CustomPageController.swift */, ); name = ParentController; sourceTree = ""; }; 4DF0A9B31C3986B800731373 /* ChildControllers */ = { isa = PBXGroup; children = ( 4DF0A9791C39847100731373 /* ViewController.swift */, 4DF0A9B41C3986D600731373 /* TableViewController.swift */, ); name = ChildControllers; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 4DF0A9731C39847100731373 /* StoryboardExample */ = { isa = PBXNativeTarget; buildConfigurationList = 4DF0A99C1C39847100731373 /* Build configuration list for PBXNativeTarget "StoryboardExample" */; buildPhases = ( 4DF0A9701C39847100731373 /* Sources */, 4DF0A9711C39847100731373 /* Frameworks */, 4DF0A9721C39847100731373 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = StoryboardExample; productName = StoryboardExample; productReference = 4DF0A9741C39847100731373 /* StoryboardExample.app */; productType = "com.apple.product-type.application"; }; 4DF0A9871C39847100731373 /* StoryboardExampleTests */ = { isa = PBXNativeTarget; buildConfigurationList = 4DF0A99F1C39847100731373 /* Build configuration list for PBXNativeTarget "StoryboardExampleTests" */; buildPhases = ( 4DF0A9841C39847100731373 /* Sources */, 4DF0A9851C39847100731373 /* Frameworks */, 4DF0A9861C39847100731373 /* Resources */, ); buildRules = ( ); dependencies = ( 4DF0A98A1C39847100731373 /* PBXTargetDependency */, ); name = StoryboardExampleTests; productName = StoryboardExampleTests; productReference = 4DF0A9881C39847100731373 /* StoryboardExampleTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 4DF0A9921C39847100731373 /* StoryboardExampleUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 4DF0A9A21C39847100731373 /* Build configuration list for PBXNativeTarget "StoryboardExampleUITests" */; buildPhases = ( 4DF0A98F1C39847100731373 /* Sources */, 4DF0A9901C39847100731373 /* Frameworks */, 4DF0A9911C39847100731373 /* Resources */, ); buildRules = ( ); dependencies = ( 4DF0A9951C39847100731373 /* PBXTargetDependency */, ); name = StoryboardExampleUITests; productName = StoryboardExampleUITests; productReference = 4DF0A9931C39847100731373 /* StoryboardExampleUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 4DF0A96C1C39847100731373 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; LastUpgradeCheck = 0720; ORGANIZATIONNAME = "Wecan Studio"; TargetAttributes = { 4DF0A9731C39847100731373 = { CreatedOnToolsVersion = 7.2; }; 4DF0A9871C39847100731373 = { CreatedOnToolsVersion = 7.2; TestTargetID = 4DF0A9731C39847100731373; }; 4DF0A9921C39847100731373 = { CreatedOnToolsVersion = 7.2; TestTargetID = 4DF0A9731C39847100731373; }; }; }; buildConfigurationList = 4DF0A96F1C39847100731373 /* Build configuration list for PBXProject "StoryboardExample" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 4DF0A96B1C39847100731373; productRefGroup = 4DF0A9751C39847100731373 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 4DF0A9731C39847100731373 /* StoryboardExample */, 4DF0A9871C39847100731373 /* StoryboardExampleTests */, 4DF0A9921C39847100731373 /* StoryboardExampleUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 4DF0A9721C39847100731373 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4DF0A9821C39847100731373 /* LaunchScreen.storyboard in Resources */, 4DF0A97F1C39847100731373 /* Assets.xcassets in Resources */, 4DF0A97D1C39847100731373 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4DF0A9861C39847100731373 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4DF0A9911C39847100731373 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 4DF0A9701C39847100731373 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4DCCF83F1CE8558A00C31A07 /* MenuView.swift in Sources */, 4DF0A9B21C3984EB00731373 /* CustomPageController.swift in Sources */, 4DCCF83D1CE8558A00C31A07 /* FooldView.swift in Sources */, 4DCCF8401CE8558A00C31A07 /* PageController.swift in Sources */, 4DF0A97A1C39847100731373 /* ViewController.swift in Sources */, 4DF0A9B51C3986D600731373 /* TableViewController.swift in Sources */, 4DCCF83E1CE8558A00C31A07 /* MenuItem.swift in Sources */, 4DCCF8411CE8558A00C31A07 /* ProgressView.swift in Sources */, 4DF0A9781C39847100731373 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4DF0A9841C39847100731373 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4DF0A98D1C39847100731373 /* StoryboardExampleTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4DF0A98F1C39847100731373 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4DF0A9981C39847100731373 /* StoryboardExampleUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 4DF0A98A1C39847100731373 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4DF0A9731C39847100731373 /* StoryboardExample */; targetProxy = 4DF0A9891C39847100731373 /* PBXContainerItemProxy */; }; 4DF0A9951C39847100731373 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4DF0A9731C39847100731373 /* StoryboardExample */; targetProxy = 4DF0A9941C39847100731373 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 4DF0A97B1C39847100731373 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 4DF0A97C1C39847100731373 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 4DF0A9801C39847100731373 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 4DF0A9811C39847100731373 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 4DF0A99A1C39847100731373 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.2; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 4DF0A99B1C39847100731373 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; 4DF0A99D1C39847100731373 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = StoryboardExample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.StoryboardExample; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 4DF0A99E1C39847100731373 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = StoryboardExample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.StoryboardExample; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; 4DF0A9A01C39847100731373 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = StoryboardExampleTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.StoryboardExampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StoryboardExample.app/StoryboardExample"; }; name = Debug; }; 4DF0A9A11C39847100731373 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = StoryboardExampleTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.StoryboardExampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StoryboardExample.app/StoryboardExample"; }; name = Release; }; 4DF0A9A31C39847100731373 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = StoryboardExampleUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.StoryboardExampleUITests; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_TARGET_NAME = StoryboardExample; USES_XCTRUNNER = YES; }; name = Debug; }; 4DF0A9A41C39847100731373 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = StoryboardExampleUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.StoryboardExampleUITests; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_TARGET_NAME = StoryboardExample; USES_XCTRUNNER = YES; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 4DF0A96F1C39847100731373 /* Build configuration list for PBXProject "StoryboardExample" */ = { isa = XCConfigurationList; buildConfigurations = ( 4DF0A99A1C39847100731373 /* Debug */, 4DF0A99B1C39847100731373 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4DF0A99C1C39847100731373 /* Build configuration list for PBXNativeTarget "StoryboardExample" */ = { isa = XCConfigurationList; buildConfigurations = ( 4DF0A99D1C39847100731373 /* Debug */, 4DF0A99E1C39847100731373 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4DF0A99F1C39847100731373 /* Build configuration list for PBXNativeTarget "StoryboardExampleTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 4DF0A9A01C39847100731373 /* Debug */, 4DF0A9A11C39847100731373 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4DF0A9A21C39847100731373 /* Build configuration list for PBXNativeTarget "StoryboardExampleUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 4DF0A9A31C39847100731373 /* Debug */, 4DF0A9A41C39847100731373 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 4DF0A96C1C39847100731373 /* Project object */; } ================================================ FILE: StoryboardExample/StoryboardExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: StoryboardExample/StoryboardExample.xcodeproj/xcshareddata/xcschemes/StoryboardExample.xcscheme ================================================ ================================================ FILE: StoryboardExample/StoryboardExampleTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: StoryboardExample/StoryboardExampleTests/StoryboardExampleTests.swift ================================================ // // StoryboardExampleTests.swift // StoryboardExampleTests // // Created by Mark on 16/1/4. // Copyright © 2016年 Wecan Studio. All rights reserved. // import XCTest @testable import StoryboardExample class StoryboardExampleTests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. } func testPerformanceExample() { // This is an example of a performance test case. self.measureBlock { // Put the code you want to measure the time of here. } } } ================================================ FILE: StoryboardExample/StoryboardExampleUITests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: StoryboardExample/StoryboardExampleUITests/StoryboardExampleUITests.swift ================================================ // // StoryboardExampleUITests.swift // StoryboardExampleUITests // // Created by Mark on 16/1/4. // Copyright © 2016年 Wecan Studio. All rights reserved. // import XCTest class StoryboardExampleUITests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. // In UI tests it is usually best to stop immediately when a failure occurs. continueAfterFailure = false // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. XCUIApplication().launch() // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // Use recording to get started writing UI tests. // Use XCTAssert and related functions to verify your tests produce the correct results. } } ================================================ FILE: WMPageController-Swift/AppDelegate.swift ================================================ // // AppDelegate.swift // Example // // Created by Mark on 15/12/1. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. let pageController = customedPageController() window?.rootViewController = UINavigationController(rootViewController: pageController) // reloadPageController(pageController, afterDelay: 5.0) // updatePageController(pageController, title: "hahahahaha", afterDelay: 5.0) return true } func applicationWillResignActive(_ application: UIApplication) { // 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. // 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. } func applicationDidEnterBackground(_ application: UIApplication) { // 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. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // 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. } func applicationDidBecomeActive(_ application: UIApplication) { // 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. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } // MARK: - An example of `PageController` fileprivate func customedPageController() -> PageController { let vcClasses: [UIViewController.Type] = [ViewController.self, TableViewController.self] let titles = ["Hello", "World"] let pageController = PageController(vcClasses: vcClasses, theirTitles: titles) pageController.pageAnimatable = true pageController.menuViewStyle = MenuViewStyle.line pageController.bounces = true pageController.menuHeight = 44 pageController.titleSizeSelected = 15 pageController.values = ["Hello", "I'm Mark"] // pass values pageController.keys = ["type", "text"] // keys pageController.title = "Test" pageController.menuBGColor = .clear pageController.showOnNavigationBar = true // pageController.selectedIndex = 1 // pageController.progressColor = .blackColor() // pageController.viewFrame = CGRect(x: 50, y: 100, width: 320, height: 500) // pageController.itemsWidths = [100, 50] // pageController.itemsMargins = [100, 10, 100] // pageController.titleSizeNormal = 12 // pageController.titleSizeSelected = 14 // pageController.titleColorNormal = UIColor.brownColor() // pageController.titleColorSelected = UIColor.blackColor() return pageController } fileprivate func reloadPageController(_ pageController: PageController, afterDelay delay: TimeInterval) { let delayTime = DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) DispatchQueue.main.asyncAfter(deadline: delayTime) { pageController.titles = ["Hello", "World", "Reload"] pageController.viewControllerClasses = [ViewController.self, TableViewController.self, ViewController.self] pageController.values = ["Hello", "I'm Mark", "Reload"] pageController.keys = ["type", "text", "type"] pageController.reloadData() } } fileprivate func updatePageController(_ pageController: PageController, title: String, afterDelay delay: TimeInterval) { let delayTime = DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) DispatchQueue.main.asyncAfter(deadline: delayTime) { pageController.updateTitle(title, atIndex: 1, andWidth: 150) } } } ================================================ FILE: WMPageController-Swift/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: WMPageController-Swift/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: WMPageController-Swift/Base.lproj/Main.storyboard ================================================ ================================================ FILE: WMPageController-Swift/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: WMPageController-Swift/TableViewController.swift ================================================ // // TableViewController.swift // PageController // // Created by Mark on 15/10/31. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit class TableViewController: UITableViewController { var text = "" fileprivate let cellReuseIdentifier = "cellReuseIdentifier" override func viewDidLoad() { super.viewDidLoad() tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier) tableView.rowHeight = 60 } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) cell.selectionStyle = UITableViewCellSelectionStyle.none cell.imageView?.image = UIImage(named: "github") cell.textLabel?.text = text return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // let vc = ViewController() let vc = customedPageController() vc.title = "Push" // vc.type = "Bye bye" navigationController?.pushViewController(vc, animated: true) } // MARK: - An example of `PageController` fileprivate func customedPageController() -> PageController { let vcClasses: [UIViewController.Type] = [ViewController.self, TableViewController.self] let titles = ["Hello", "World"] let pageController = PageController(vcClasses: vcClasses, theirTitles: titles) pageController.pageAnimatable = true pageController.menuViewStyle = MenuViewStyle.line pageController.bounces = true pageController.menuHeight = 44 pageController.titleSizeSelected = 15 pageController.values = ["Hello", "I'm Mark"] // pass values pageController.keys = ["type", "text"] // keys pageController.title = "Test" pageController.menuBGColor = .clear // pageController.selectedIndex = 1 // pageController.progressColor = .blackColor() // pageController.viewFrame = CGRect(x: 50, y: 100, width: 320, height: 500) // pageController.itemsWidths = [100, 50] // pageController.itemsMargins = [50, 10, 100] // pageController.titleSizeNormal = 12 // pageController.titleSizeSelected = 14 // pageController.titleColorNormal = UIColor.brownColor() // pageController.titleColorSelected = UIColor.blackColor() return pageController } override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { if (indexPath as NSIndexPath).row % 2 == 0 { return true } return false } override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { } } ================================================ FILE: WMPageController-Swift/ViewController.swift ================================================ // // ViewController.swift // PageController // // Created by Mark on 15/10/20. // Copyright © 2015年 Wecan Studio. All rights reserved. // import UIKit class ViewController: UIViewController, UITableViewDelegate { var type = "" override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white createLabel() } fileprivate func createLabel() { let label = UILabel(frame: CGRect(x: 0, y: 100, width: view.bounds.size.width, height: 100)) label.text = type label.font = UIFont.systemFont(ofSize: 22) label.textAlignment = .center view.addSubview(label) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } ================================================ FILE: WMPageController-Swift.podspec ================================================ Pod::Spec.new do |s| s.name = "WMPageController-Swift" s.version = "1.4.0" s.summary = "An easy solution to page controllers like NetEase News.(Swift Implementation)" s.homepage = "https://github.com/wangmchn/WMPageController-Swift" s.license = 'MIT (LICENSE)' s.author = { "wangmchn" => "wangmchn@163.com" } s.source = { :git => "https://github.com/wangmchn/WMPageController-Swift.git", :tag => "1.4.0" } s.platform = :ios, '8.0' s.source_files = 'PageController', 'PageController/**/*.{swift}' s.exclude_files = 'Example' s.frameworks = 'Foundation', 'CoreGraphics', 'UIKit' s.requires_arc = true end ================================================ FILE: WMPageController-Swift.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 4D45BF191CC7A10B003F0151 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D45BF181CC7A10B003F0151 /* AppDelegate.swift */; }; 4D45BF1B1CC7A10B003F0151 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D45BF1A1CC7A10B003F0151 /* ViewController.swift */; }; 4D45BF1E1CC7A10B003F0151 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4D45BF1C1CC7A10B003F0151 /* Main.storyboard */; }; 4D45BF201CC7A10B003F0151 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4D45BF1F1CC7A10B003F0151 /* Assets.xcassets */; }; 4D45BF231CC7A10B003F0151 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4D45BF211CC7A10B003F0151 /* LaunchScreen.storyboard */; }; 4D45BF2E1CC7A10B003F0151 /* WMPageController_SwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D45BF2D1CC7A10B003F0151 /* WMPageController_SwiftTests.swift */; }; 4D45BF391CC7A10B003F0151 /* WMPageController_SwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D45BF381CC7A10B003F0151 /* WMPageController_SwiftUITests.swift */; }; 4D45BF521CC7A1EB003F0151 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D45BF511CC7A1EB003F0151 /* TableViewController.swift */; }; 4D45BF661CC7BC12003F0151 /* WMPageControllerSwiftFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D45BF651CC7BC12003F0151 /* WMPageControllerSwiftFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4D45BF6A1CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D45BF631CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework */; }; 4D45BF6B1CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4D45BF631CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4DCCF8481CE855F200C31A07 /* FloodView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8431CE855F200C31A07 /* FloodView.swift */; }; 4DCCF8491CE855F200C31A07 /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8441CE855F200C31A07 /* MenuItem.swift */; }; 4DCCF84A1CE855F200C31A07 /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8451CE855F200C31A07 /* MenuView.swift */; }; 4DCCF84B1CE855F200C31A07 /* PageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8461CE855F200C31A07 /* PageController.swift */; }; 4DCCF84C1CE855F200C31A07 /* ProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8471CE855F200C31A07 /* ProgressView.swift */; }; F73DD37B1F403F3500FAC00A /* FloodView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8431CE855F200C31A07 /* FloodView.swift */; }; F73DD37C1F403F3500FAC00A /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8441CE855F200C31A07 /* MenuItem.swift */; }; F73DD37D1F403F3500FAC00A /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8451CE855F200C31A07 /* MenuView.swift */; }; F73DD37E1F403F3500FAC00A /* PageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8461CE855F200C31A07 /* PageController.swift */; }; F73DD37F1F403F3500FAC00A /* ProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCCF8471CE855F200C31A07 /* ProgressView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 4D45BF2A1CC7A10B003F0151 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4D45BF0D1CC7A10B003F0151 /* Project object */; proxyType = 1; remoteGlobalIDString = 4D45BF141CC7A10B003F0151; remoteInfo = "WMPageController-Swift"; }; 4D45BF351CC7A10B003F0151 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4D45BF0D1CC7A10B003F0151 /* Project object */; proxyType = 1; remoteGlobalIDString = 4D45BF141CC7A10B003F0151; remoteInfo = "WMPageController-Swift"; }; 4D45BF681CC7BC12003F0151 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4D45BF0D1CC7A10B003F0151 /* Project object */; proxyType = 1; remoteGlobalIDString = 4D45BF621CC7BC12003F0151; remoteInfo = WMPageControllerSwiftFramework; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ 4D45BF6F1CC7BC12003F0151 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( 4D45BF6B1CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 4D45BF151CC7A10B003F0151 /* WMPageController-Swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WMPageController-Swift.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4D45BF181CC7A10B003F0151 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4D45BF1A1CC7A10B003F0151 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 4D45BF1D1CC7A10B003F0151 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 4D45BF1F1CC7A10B003F0151 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4D45BF221CC7A10B003F0151 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 4D45BF241CC7A10B003F0151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4D45BF291CC7A10B003F0151 /* WMPageController-SwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WMPageController-SwiftTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 4D45BF2D1CC7A10B003F0151 /* WMPageController_SwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WMPageController_SwiftTests.swift; sourceTree = ""; }; 4D45BF2F1CC7A10B003F0151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4D45BF341CC7A10B003F0151 /* WMPageController-SwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WMPageController-SwiftUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 4D45BF381CC7A10B003F0151 /* WMPageController_SwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WMPageController_SwiftUITests.swift; sourceTree = ""; }; 4D45BF3A1CC7A10B003F0151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4D45BF511CC7A1EB003F0151 /* TableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; 4D45BF631CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WMPageControllerSwiftFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4D45BF651CC7BC12003F0151 /* WMPageControllerSwiftFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WMPageControllerSwiftFramework.h; sourceTree = ""; }; 4D45BF671CC7BC12003F0151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4DCCF8431CE855F200C31A07 /* FloodView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloodView.swift; sourceTree = ""; }; 4DCCF8441CE855F200C31A07 /* MenuItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; }; 4DCCF8451CE855F200C31A07 /* MenuView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = ""; }; 4DCCF8461CE855F200C31A07 /* PageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageController.swift; sourceTree = ""; }; 4DCCF8471CE855F200C31A07 /* ProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 4D45BF121CC7A10B003F0151 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4D45BF6A1CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF261CC7A10B003F0151 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF311CC7A10B003F0151 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF5F1CC7BC12003F0151 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 4D45BF0C1CC7A10B003F0151 = { isa = PBXGroup; children = ( 4D45BF171CC7A10B003F0151 /* WMPageController-Swift */, 4D45BF2C1CC7A10B003F0151 /* WMPageController-SwiftTests */, 4D45BF371CC7A10B003F0151 /* WMPageController-SwiftUITests */, 4D45BF641CC7BC12003F0151 /* WMPageControllerSwiftFramework */, 4D45BF161CC7A10B003F0151 /* Products */, ); sourceTree = ""; }; 4D45BF161CC7A10B003F0151 /* Products */ = { isa = PBXGroup; children = ( 4D45BF151CC7A10B003F0151 /* WMPageController-Swift.app */, 4D45BF291CC7A10B003F0151 /* WMPageController-SwiftTests.xctest */, 4D45BF341CC7A10B003F0151 /* WMPageController-SwiftUITests.xctest */, 4D45BF631CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework */, ); name = Products; sourceTree = ""; }; 4D45BF171CC7A10B003F0151 /* WMPageController-Swift */ = { isa = PBXGroup; children = ( 4DCCF8421CE855F200C31A07 /* PageController */, 4D45BF181CC7A10B003F0151 /* AppDelegate.swift */, 4D45BF1A1CC7A10B003F0151 /* ViewController.swift */, 4D45BF511CC7A1EB003F0151 /* TableViewController.swift */, 4D45BF1C1CC7A10B003F0151 /* Main.storyboard */, 4D45BF1F1CC7A10B003F0151 /* Assets.xcassets */, 4D45BF211CC7A10B003F0151 /* LaunchScreen.storyboard */, 4D45BF241CC7A10B003F0151 /* Info.plist */, ); path = "WMPageController-Swift"; sourceTree = ""; }; 4D45BF2C1CC7A10B003F0151 /* WMPageController-SwiftTests */ = { isa = PBXGroup; children = ( 4D45BF2D1CC7A10B003F0151 /* WMPageController_SwiftTests.swift */, 4D45BF2F1CC7A10B003F0151 /* Info.plist */, ); path = "WMPageController-SwiftTests"; sourceTree = ""; }; 4D45BF371CC7A10B003F0151 /* WMPageController-SwiftUITests */ = { isa = PBXGroup; children = ( 4D45BF381CC7A10B003F0151 /* WMPageController_SwiftUITests.swift */, 4D45BF3A1CC7A10B003F0151 /* Info.plist */, ); path = "WMPageController-SwiftUITests"; sourceTree = ""; }; 4D45BF641CC7BC12003F0151 /* WMPageControllerSwiftFramework */ = { isa = PBXGroup; children = ( 4D45BF651CC7BC12003F0151 /* WMPageControllerSwiftFramework.h */, 4D45BF671CC7BC12003F0151 /* Info.plist */, ); path = WMPageControllerSwiftFramework; sourceTree = ""; }; 4DCCF8421CE855F200C31A07 /* PageController */ = { isa = PBXGroup; children = ( 4DCCF8431CE855F200C31A07 /* FloodView.swift */, 4DCCF8441CE855F200C31A07 /* MenuItem.swift */, 4DCCF8451CE855F200C31A07 /* MenuView.swift */, 4DCCF8461CE855F200C31A07 /* PageController.swift */, 4DCCF8471CE855F200C31A07 /* ProgressView.swift */, ); path = PageController; sourceTree = SOURCE_ROOT; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 4D45BF601CC7BC12003F0151 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4D45BF661CC7BC12003F0151 /* WMPageControllerSwiftFramework.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 4D45BF141CC7A10B003F0151 /* WMPageController-Swift */ = { isa = PBXNativeTarget; buildConfigurationList = 4D45BF3D1CC7A10B003F0151 /* Build configuration list for PBXNativeTarget "WMPageController-Swift" */; buildPhases = ( 4D45BF111CC7A10B003F0151 /* Sources */, 4D45BF121CC7A10B003F0151 /* Frameworks */, 4D45BF131CC7A10B003F0151 /* Resources */, 4D45BF6F1CC7BC12003F0151 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( 4D45BF691CC7BC12003F0151 /* PBXTargetDependency */, ); name = "WMPageController-Swift"; productName = "WMPageController-Swift"; productReference = 4D45BF151CC7A10B003F0151 /* WMPageController-Swift.app */; productType = "com.apple.product-type.application"; }; 4D45BF281CC7A10B003F0151 /* WMPageController-SwiftTests */ = { isa = PBXNativeTarget; buildConfigurationList = 4D45BF401CC7A10B003F0151 /* Build configuration list for PBXNativeTarget "WMPageController-SwiftTests" */; buildPhases = ( 4D45BF251CC7A10B003F0151 /* Sources */, 4D45BF261CC7A10B003F0151 /* Frameworks */, 4D45BF271CC7A10B003F0151 /* Resources */, ); buildRules = ( ); dependencies = ( 4D45BF2B1CC7A10B003F0151 /* PBXTargetDependency */, ); name = "WMPageController-SwiftTests"; productName = "WMPageController-SwiftTests"; productReference = 4D45BF291CC7A10B003F0151 /* WMPageController-SwiftTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 4D45BF331CC7A10B003F0151 /* WMPageController-SwiftUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 4D45BF431CC7A10B003F0151 /* Build configuration list for PBXNativeTarget "WMPageController-SwiftUITests" */; buildPhases = ( 4D45BF301CC7A10B003F0151 /* Sources */, 4D45BF311CC7A10B003F0151 /* Frameworks */, 4D45BF321CC7A10B003F0151 /* Resources */, ); buildRules = ( ); dependencies = ( 4D45BF361CC7A10B003F0151 /* PBXTargetDependency */, ); name = "WMPageController-SwiftUITests"; productName = "WMPageController-SwiftUITests"; productReference = 4D45BF341CC7A10B003F0151 /* WMPageController-SwiftUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; 4D45BF621CC7BC12003F0151 /* WMPageControllerSwiftFramework */ = { isa = PBXNativeTarget; buildConfigurationList = 4D45BF6E1CC7BC12003F0151 /* Build configuration list for PBXNativeTarget "WMPageControllerSwiftFramework" */; buildPhases = ( 4D45BF5E1CC7BC12003F0151 /* Sources */, 4D45BF5F1CC7BC12003F0151 /* Frameworks */, 4D45BF601CC7BC12003F0151 /* Headers */, 4D45BF611CC7BC12003F0151 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = WMPageControllerSwiftFramework; productName = WMPageControllerSwiftFramework; productReference = 4D45BF631CC7BC12003F0151 /* WMPageControllerSwiftFramework.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 4D45BF0D1CC7A10B003F0151 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0830; ORGANIZATIONNAME = "Wecan Studio"; TargetAttributes = { 4D45BF141CC7A10B003F0151 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0800; }; 4D45BF281CC7A10B003F0151 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0800; TestTargetID = 4D45BF141CC7A10B003F0151; }; 4D45BF331CC7A10B003F0151 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0800; TestTargetID = 4D45BF141CC7A10B003F0151; }; 4D45BF621CC7BC12003F0151 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0830; }; }; }; buildConfigurationList = 4D45BF101CC7A10B003F0151 /* Build configuration list for PBXProject "WMPageController-Swift" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 4D45BF0C1CC7A10B003F0151; productRefGroup = 4D45BF161CC7A10B003F0151 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 4D45BF141CC7A10B003F0151 /* WMPageController-Swift */, 4D45BF281CC7A10B003F0151 /* WMPageController-SwiftTests */, 4D45BF331CC7A10B003F0151 /* WMPageController-SwiftUITests */, 4D45BF621CC7BC12003F0151 /* WMPageControllerSwiftFramework */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 4D45BF131CC7A10B003F0151 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4D45BF231CC7A10B003F0151 /* LaunchScreen.storyboard in Resources */, 4D45BF201CC7A10B003F0151 /* Assets.xcassets in Resources */, 4D45BF1E1CC7A10B003F0151 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF271CC7A10B003F0151 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF321CC7A10B003F0151 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF611CC7BC12003F0151 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 4D45BF111CC7A10B003F0151 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4D45BF1B1CC7A10B003F0151 /* ViewController.swift in Sources */, 4DCCF84A1CE855F200C31A07 /* MenuView.swift in Sources */, 4DCCF8481CE855F200C31A07 /* FloodView.swift in Sources */, 4DCCF84B1CE855F200C31A07 /* PageController.swift in Sources */, 4D45BF521CC7A1EB003F0151 /* TableViewController.swift in Sources */, 4DCCF84C1CE855F200C31A07 /* ProgressView.swift in Sources */, 4D45BF191CC7A10B003F0151 /* AppDelegate.swift in Sources */, 4DCCF8491CE855F200C31A07 /* MenuItem.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF251CC7A10B003F0151 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4D45BF2E1CC7A10B003F0151 /* WMPageController_SwiftTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF301CC7A10B003F0151 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4D45BF391CC7A10B003F0151 /* WMPageController_SwiftUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4D45BF5E1CC7BC12003F0151 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F73DD37B1F403F3500FAC00A /* FloodView.swift in Sources */, F73DD37C1F403F3500FAC00A /* MenuItem.swift in Sources */, F73DD37D1F403F3500FAC00A /* MenuView.swift in Sources */, F73DD37E1F403F3500FAC00A /* PageController.swift in Sources */, F73DD37F1F403F3500FAC00A /* ProgressView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 4D45BF2B1CC7A10B003F0151 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4D45BF141CC7A10B003F0151 /* WMPageController-Swift */; targetProxy = 4D45BF2A1CC7A10B003F0151 /* PBXContainerItemProxy */; }; 4D45BF361CC7A10B003F0151 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4D45BF141CC7A10B003F0151 /* WMPageController-Swift */; targetProxy = 4D45BF351CC7A10B003F0151 /* PBXContainerItemProxy */; }; 4D45BF691CC7BC12003F0151 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4D45BF621CC7BC12003F0151 /* WMPageControllerSwiftFramework */; targetProxy = 4D45BF681CC7BC12003F0151 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 4D45BF1C1CC7A10B003F0151 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 4D45BF1D1CC7A10B003F0151 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 4D45BF211CC7A10B003F0151 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 4D45BF221CC7A10B003F0151 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 4D45BF3B1CC7A10B003F0151 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 4D45BF3C1CC7A10B003F0151 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; }; 4D45BF3E1CC7A10B003F0151 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = "WMPageController-Swift/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.wecan.WMPageController-Swift"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 3.0; }; name = Debug; }; 4D45BF3F1CC7A10B003F0151 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = "WMPageController-Swift/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.wecan.WMPageController-Swift"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 3.0; }; name = Release; }; 4D45BF411CC7A10B003F0151 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = "WMPageController-SwiftTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.wecan.WMPageController-SwiftTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WMPageController-Swift.app/WMPageController-Swift"; }; name = Debug; }; 4D45BF421CC7A10B003F0151 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = "WMPageController-SwiftTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.wecan.WMPageController-SwiftTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WMPageController-Swift.app/WMPageController-Swift"; }; name = Release; }; 4D45BF441CC7A10B003F0151 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = "WMPageController-SwiftUITests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.wecan.WMPageController-SwiftUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 3.0; TEST_TARGET_NAME = "WMPageController-Swift"; }; name = Debug; }; 4D45BF451CC7A10B003F0151 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = "WMPageController-SwiftUITests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.wecan.WMPageController-SwiftUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 3.0; TEST_TARGET_NAME = "WMPageController-Swift"; }; name = Release; }; 4D45BF6C1CC7BC12003F0151 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = WMPageControllerSwiftFramework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.WMPageControllerSwiftFramework; PRODUCT_MODULE_NAME = WMPageControllerSwiftFramework; PRODUCT_NAME = WMPageControllerSwiftFramework; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 4D45BF6D1CC7BC12003F0151 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = WMPageControllerSwiftFramework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.wecan.WMPageControllerSwiftFramework; PRODUCT_MODULE_NAME = WMPageControllerSwiftFramework; PRODUCT_NAME = WMPageControllerSwiftFramework; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 4D45BF101CC7A10B003F0151 /* Build configuration list for PBXProject "WMPageController-Swift" */ = { isa = XCConfigurationList; buildConfigurations = ( 4D45BF3B1CC7A10B003F0151 /* Debug */, 4D45BF3C1CC7A10B003F0151 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4D45BF3D1CC7A10B003F0151 /* Build configuration list for PBXNativeTarget "WMPageController-Swift" */ = { isa = XCConfigurationList; buildConfigurations = ( 4D45BF3E1CC7A10B003F0151 /* Debug */, 4D45BF3F1CC7A10B003F0151 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4D45BF401CC7A10B003F0151 /* Build configuration list for PBXNativeTarget "WMPageController-SwiftTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 4D45BF411CC7A10B003F0151 /* Debug */, 4D45BF421CC7A10B003F0151 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4D45BF431CC7A10B003F0151 /* Build configuration list for PBXNativeTarget "WMPageController-SwiftUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 4D45BF441CC7A10B003F0151 /* Debug */, 4D45BF451CC7A10B003F0151 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4D45BF6E1CC7BC12003F0151 /* Build configuration list for PBXNativeTarget "WMPageControllerSwiftFramework" */ = { isa = XCConfigurationList; buildConfigurations = ( 4D45BF6C1CC7BC12003F0151 /* Debug */, 4D45BF6D1CC7BC12003F0151 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 4D45BF0D1CC7A10B003F0151 /* Project object */; } ================================================ FILE: WMPageController-Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: WMPageController-Swift.xcodeproj/xcshareddata/xcschemes/WMPageController-Swift.xcscheme ================================================ ================================================ FILE: WMPageController-Swift.xcodeproj/xcshareddata/xcschemes/WMPageControllerSwiftFramework.xcscheme ================================================ ================================================ FILE: WMPageController-SwiftTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: WMPageController-SwiftTests/WMPageController_SwiftTests.swift ================================================ // // WMPageController_SwiftTests.swift // WMPageController-SwiftTests // // Created by Mark on 16/4/20. // Copyright © 2016年 Wecan Studio. All rights reserved. // import XCTest @testable import WMPageController_Swift class WMPageController_SwiftTests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. } func testPerformanceExample() { // This is an example of a performance test case. self.measure { // Put the code you want to measure the time of here. } } } ================================================ FILE: WMPageController-SwiftUITests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: WMPageController-SwiftUITests/WMPageController_SwiftUITests.swift ================================================ // // WMPageController_SwiftUITests.swift // WMPageController-SwiftUITests // // Created by Mark on 16/4/20. // Copyright © 2016年 Wecan Studio. All rights reserved. // import XCTest class WMPageController_SwiftUITests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. // In UI tests it is usually best to stop immediately when a failure occurs. continueAfterFailure = false // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. XCUIApplication().launch() // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // Use recording to get started writing UI tests. // Use XCTAssert and related functions to verify your tests produce the correct results. } } ================================================ FILE: WMPageControllerSwiftFramework/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString 1.5.1 CFBundleSignature ???? CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass ================================================ FILE: WMPageControllerSwiftFramework/WMPageControllerSwiftFramework.h ================================================ // // WMPageControllerSwiftFramework.h // WMPageControllerSwiftFramework // // Created by Mark on 16/4/20. // Copyright © 2016年 Wecan Studio. All rights reserved. // #import //! Project version number for WMPageControllerSwiftFramework. FOUNDATION_EXPORT double WMPageControllerSwiftFrameworkVersionNumber; //! Project version string for WMPageControllerSwiftFramework. FOUNDATION_EXPORT const unsigned char WMPageControllerSwiftFrameworkVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import