├── .gitignore ├── .swift-version ├── .swiftlint.yml ├── 2017-03-21 20_24_31.gif ├── Classes ├── Array+Extensions.swift ├── Bridging.h ├── MTPopupContainerViewController.swift ├── MTPopupController.swift ├── MTPopupControllerTransitioning.swift ├── MTPopupControllerTransitioningContext.swift ├── MTPopupControllerTransitioningFade.swift ├── MTPopupControllerTransitioningSlideVertical.swift ├── MTPopupLeftBarItem.swift ├── MTPopupNavigationBar.swift ├── UIResponder+MTPopup.h ├── UIResponder+MTPopup.m ├── UIResponder+STPopup.swift ├── UIViewController+MTPopup.h ├── UIViewController+MTPopup.m └── UIViewController+STPopup.swift ├── Demo ├── Cartfile ├── Cartfile.resolved ├── Carthage │ └── Checkouts │ │ └── MTPopup │ │ ├── .gitignore │ │ ├── .swift-version │ │ ├── .swiftlint.yml │ │ ├── 2017-03-21 20_24_31.gif │ │ ├── Classes │ │ ├── Array+Extensions.swift │ │ ├── Bridging.h │ │ ├── MTPopupContainerViewController.swift │ │ ├── MTPopupController.swift │ │ ├── MTPopupControllerTransitioning.swift │ │ ├── MTPopupControllerTransitioningContext.swift │ │ ├── MTPopupControllerTransitioningFade.swift │ │ ├── MTPopupControllerTransitioningSlideVertical.swift │ │ ├── MTPopupLeftBarItem.swift │ │ ├── MTPopupNavigationBar.swift │ │ ├── UIResponder+STPopup.swift │ │ └── UIViewController+STPopup.swift │ │ ├── Demo │ │ ├── Cartfile │ │ ├── Demo.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── project.xcworkspace │ │ │ │ └── contents.xcworkspacedata │ │ ├── Demo │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ ├── TestControllers │ │ │ │ ├── BottomSheetController.swift │ │ │ │ ├── PopupViewController1.swift │ │ │ │ └── PopupViewController2.swift │ │ │ └── ViewController.swift │ │ ├── DemoUITests │ │ │ ├── DemoUITests.swift │ │ │ └── Info.plist │ │ └── MTPopup │ │ │ ├── MTPopup.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ └── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── MTPopup.xcscheme │ │ │ ├── MTPopup.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ │ └── MTPopup │ │ │ ├── Info.plist │ │ │ └── MTPopup.h │ │ ├── LICENSE │ │ ├── MTPopup.podspec │ │ └── README.md ├── Demo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Demo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── TestControllers │ │ ├── BottomSheetController.swift │ │ ├── PopupViewController1.swift │ │ └── PopupViewController2.swift │ └── ViewController.swift ├── DemoUITests │ ├── DemoUITests.swift │ └── Info.plist └── MTPopup │ ├── MTPopup.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── MTPopup.xcscheme │ ├── MTPopup.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── MTPopup │ ├── Info.plist │ └── MTPopup.h ├── LICENSE ├── MTPopup.podspec └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | Packages/ 36 | .build/ 37 | 38 | # CocoaPods 39 | Pods/ 40 | 41 | # Carthage 42 | Carthage/Checkouts 43 | Carthage/Build 44 | 45 | # fastlane 46 | fastlane/report.xml 47 | fastlane/Preview.html 48 | fastlane/screenshots 49 | fastlane/test_output 50 | 51 | # OSX 52 | .DS_Store 53 | 54 | # Byte-compiled / optimized / DLL files 55 | __pycache__/ 56 | *.py[cod] 57 | *$py.class 58 | 59 | build_deploy.sh 60 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 2 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: # rule identifiers to exclude from running 2 | - cyclomatic_complexity 3 | - fixme 4 | - function_body_length 5 | - function_parameter_count 6 | - todo 7 | - valid_docs 8 | - variable_name 9 | - type_name 10 | opt_in_rules: # some rules are only opt-in 11 | #- empty_count 12 | # Find all the available rules by running: 13 | # swiftlint rules 14 | included: # paths to include during linting. `--path` is ignored if present. 15 | - STPopup 16 | excluded: # paths to ignore during linting. Takes precedence over `included`. 17 | # - Carthage 18 | # - Pods 19 | - Source/ExcludedFolder 20 | - Source/ExcludedFile.swift 21 | # configurable rules can be customized from this configuration file 22 | # binary rules can set their severity level 23 | force_cast: warning # implicitly 24 | force_try: 25 | severity: warning # explicitly 26 | # rules that have both warning and error levels, can set just the warning level 27 | # implicitly 28 | line_length: 400 # 29 | # they can set both implicitly with an array 30 | type_body_length: 31 | - 300 # warning 32 | - 400 # error 33 | # or they can set both explicitly 34 | file_length: 35 | warning: 500 36 | error: 1200 37 | # naming rules can set warnings/errors for min_length and max_length 38 | # additionally they can set excluded names 39 | type_name: 40 | min_length: 2 # only warning 41 | max_length: # warning and error 42 | warning: 40 43 | error: 50 44 | excluded: iPhone # excluded via string 45 | variable_name: 46 | min_length: 1 # only min_length 47 | excluded: # excluded via string array 48 | - id 49 | - URL 50 | - GlobalAPIKey 51 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle) 52 | -------------------------------------------------------------------------------- /2017-03-21 20_24_31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangboju/MTPopup/a03237ca898154264d83fb0dbc7df97c6ccffea4/2017-03-21 20_24_31.gif -------------------------------------------------------------------------------- /Classes/Array+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2016年 伯驹 黄. All rights reserved. 3 | // 4 | 5 | extension Array where Element: Equatable { 6 | 7 | // Remove first collection element that is equal to the given `object`: 8 | mutating func remove(_ object: Element) { 9 | guard let index = firstIndex(of: object) else { return } 10 | remove(at: index) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Classes/Bridging.h: -------------------------------------------------------------------------------- 1 | // 2 | // Bridging.h 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/12/2. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import 10 | -------------------------------------------------------------------------------- /Classes/MTPopupContainerViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupContainerViewController.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/6. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | public class MTPopupContainerViewController: UIViewController { 10 | 11 | override public var preferredStatusBarStyle: UIStatusBarStyle { 12 | guard let presentingViewController = presentingViewController, !children.isEmpty else { 13 | return super.preferredStatusBarStyle 14 | } 15 | return presentingViewController.preferredStatusBarStyle 16 | } 17 | 18 | override public var childForStatusBarHidden: UIViewController? { 19 | return children.last 20 | } 21 | 22 | override public var childForStatusBarStyle: UIViewController? { 23 | return children.last 24 | } 25 | 26 | override public func show(_ vc: UIViewController, sender _: Any?) { 27 | method(vc: vc) 28 | } 29 | 30 | override public func showDetailViewController(_ vc: UIViewController, sender _: Any?) { 31 | method(vc: vc) 32 | } 33 | 34 | private func method(vc: UIViewController) { 35 | let size = vc.landscapeContentSizeInPopup 36 | let contentSize = vc.contentSizeInPopup 37 | if contentSize != .zero || size != .zero { 38 | let childViewController = children.last 39 | childViewController?.popupController?.push(vc, animated: true) 40 | } else { 41 | present(vc, animated: true, completion: nil) 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Classes/MTPopupControllerTransitioning.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2016年 伯驹 黄. All rights reserved. 3 | // 4 | 5 | protocol MTPopupControllerTransitioning { 6 | /** 7 | Return duration of transitioning, it will be used to animate transitioning of background view. 8 | */ 9 | func popupControllerTransitionDuration(_ context: MTPopupControllerTransitioningContext) -> TimeInterval 10 | /** 11 | Animate transitioning the container view of popup controller. "completion" need to be called after transitioning is finished. 12 | Initially "containerView" will be placed at the final position with transform = CGAffineTransformIdentity if it's presenting. 13 | */ 14 | func popupControllerAnimateTransition(_ context: MTPopupControllerTransitioningContext, completion: (() -> Void)?) 15 | } 16 | 17 | extension MTPopupControllerTransitioning { 18 | func popupControllerTransitionDuration(_ context: MTPopupControllerTransitioningContext) -> TimeInterval { 19 | if self is MTPopupControllerTransitioningFade { 20 | return context.action == .present ? 0.25 : 0.2 21 | } else { 22 | return context.action == .present ? 0.5 : 0.35 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Classes/MTPopupControllerTransitioningContext.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupControllerTransitioningContext.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | public class MTPopupControllerTransitioningContext { 10 | var action: MTPopupControllerTransitioningAction = .present 11 | var containerView: UIView? 12 | 13 | init(containerView: UIView, action: MTPopupControllerTransitioningAction) { 14 | self.containerView = containerView 15 | self.action = action 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Classes/MTPopupControllerTransitioningFade.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupControllerTransitioningFade.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | class MTPopupControllerTransitioningFade: MTPopupControllerTransitioning { 10 | 11 | func popupControllerAnimateTransition(_ context: MTPopupControllerTransitioningContext, completion: (() -> Void)?) { 12 | let containerView = context.containerView 13 | let duration = popupControllerTransitionDuration(context) 14 | 15 | if context.action == .present { 16 | containerView?.alpha = 0 17 | containerView?.transform = CGAffineTransform(scaleX: 1.05, y: 1.05) 18 | 19 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 20 | containerView?.alpha = 1 21 | containerView?.transform = CGAffineTransform.identity 22 | }, completion: { _ in 23 | completion?() 24 | }) 25 | } else { 26 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 27 | containerView?.alpha = 0 28 | }, completion: { _ in 29 | containerView?.alpha = 1 30 | completion?() 31 | }) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Classes/MTPopupControllerTransitioningSlideVertical.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupControllerTransitioningSlideVertical.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | class MTPopupControllerTransitioningSlideVertical: MTPopupControllerTransitioning { 10 | 11 | func popupControllerAnimateTransition(_ context: MTPopupControllerTransitioningContext, completion: (() -> Void)?) { 12 | guard let containerView = context.containerView else { return } 13 | let duration = popupControllerTransitionDuration(context) 14 | if context.action == .present { 15 | containerView.transform = CGAffineTransform(translationX: 0, y: containerView.superview!.bounds.height - containerView.frame.minY) 16 | 17 | UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: { 18 | containerView.transform = CGAffineTransform.identity 19 | }, completion: { _ in 20 | completion?() 21 | }) 22 | } else { 23 | let lastTransform = containerView.transform 24 | containerView.transform = CGAffineTransform.identity 25 | let originY = containerView.frame.minY 26 | containerView.transform = lastTransform 27 | 28 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 29 | containerView.transform = CGAffineTransform(translationX: 0, y: containerView.superview!.bounds.height - originY + containerView.frame.height) 30 | }, completion: { _ in 31 | containerView.transform = CGAffineTransform.identity 32 | completion?() 33 | }) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Classes/MTPopupLeftBarItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupLeftBarItem.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | enum MTPopupLeftBarItemType { 10 | case cross, arrow 11 | } 12 | 13 | class MTPopupLeftBarItem: UIBarButtonItem { 14 | var type: MTPopupLeftBarItemType = .cross 15 | 16 | private lazy var bar1: UIView = { 17 | let bar1 = UIView() 18 | bar1.backgroundColor = UIColor(white: 0.4, alpha: 1) 19 | bar1.isUserInteractionEnabled = false 20 | bar1.layer.allowsEdgeAntialiasing = true 21 | return bar1 22 | }() 23 | 24 | private lazy var bar2: UIView = { 25 | let bar2 = UIView() 26 | bar2.backgroundColor = UIColor(white: 0.4, alpha: 1) 27 | bar2.isUserInteractionEnabled = false 28 | bar2.layer.allowsEdgeAntialiasing = true 29 | return bar2 30 | }() 31 | 32 | convenience init(with target: Any?, action: Selector) { 33 | self.init() 34 | customView = UIControl(frame: CGRect(x: 0, y: 0, width: 18, height: 44)) 35 | (customView as? UIControl)?.addTarget(target, action: action, for: .touchUpInside) 36 | 37 | customView?.addSubview(bar1) 38 | 39 | customView?.addSubview(bar2) 40 | } 41 | 42 | func set(_ type: MTPopupLeftBarItemType, animated: Bool) { 43 | self.type = type 44 | if animated { 45 | UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 46 | self.updateLayout() 47 | }, completion: nil) 48 | } else { 49 | updateLayout() 50 | } 51 | } 52 | 53 | private func updateLayout() { 54 | var barWidth: CGFloat = 0 55 | let barHeight: CGFloat = 1.5 56 | var barX: CGFloat = 0 57 | var bar1Y: CGFloat = 0 58 | var bar2Y: CGFloat = 0 59 | guard let customView = customView else { return } 60 | switch type { 61 | case .cross: 62 | barWidth = customView.frame.height * 2 / 5 63 | barX = (customView.frame.width - barWidth) / 2 64 | bar1Y = (customView.frame.height - barHeight) / 2 65 | bar2Y = bar1Y 66 | case .arrow: 67 | barWidth = customView.frame.height / 4 68 | barX = (customView.frame.width - barWidth) / 2 - barWidth / 2 69 | bar1Y = (customView.frame.height - barHeight) / 2 + barWidth / 2 * sin(.pi / 4) 70 | bar2Y = (customView.frame.height - barHeight) / 2 - barWidth / 2 * sin(.pi / 4) 71 | } 72 | 73 | bar1.transform = CGAffineTransform.identity 74 | bar2.transform = CGAffineTransform.identity 75 | bar1.frame = CGRect(x: barX, y: bar1Y, width: barWidth, height: barHeight) 76 | bar2.frame = CGRect(x: barX, y: bar2Y, width: barWidth, height: barHeight) 77 | 78 | bar1.transform = CGAffineTransform(rotationAngle: .pi / 4) 79 | bar2.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 4) 80 | } 81 | 82 | override var tintColor: UIColor? { 83 | didSet { 84 | bar1.backgroundColor = tintColor 85 | bar2.backgroundColor = tintColor 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Classes/MTPopupNavigationBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupNavigationBar.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | protocol MTPopupNavigationTouchEventDelegate: AnyObject { 10 | func popup(_ navigationBar: MTPopupNavigationBar, touchDidMoveWith offset: CGFloat) 11 | func popup(_ navigationBar: MTPopupNavigationBar, touchDidEndWith offset: CGFloat) 12 | } 13 | 14 | public class MTPopupNavigationBar: UINavigationBar { 15 | var draggable = true 16 | weak var touchEventDelegate: MTPopupNavigationTouchEventDelegate? 17 | 18 | private var moving = false 19 | private var movingStartY: CGFloat = 0 20 | 21 | override public func touchesBegan(_ touches: Set, with event: UIEvent?) { 22 | if !draggable { 23 | super.touchesBegan(touches, with: event) 24 | return 25 | } 26 | guard let touch = touches.first else { return } 27 | if (touch.view == self || touch.view?.superview == self) && !moving { 28 | moving = true 29 | movingStartY = touch.location(in: window).y 30 | } 31 | } 32 | 33 | override public func touchesMoved(_ touches: Set, with event: UIEvent?) { 34 | if !draggable { 35 | super.touchesMoved(touches, with: event) 36 | return 37 | } 38 | 39 | if moving { 40 | guard let touch = touches.first else { return } 41 | let offset = touch.location(in: window).y - movingStartY 42 | touchEventDelegate?.popup(self, touchDidMoveWith: offset) 43 | } 44 | } 45 | 46 | override public func touchesCancelled(_ touches: Set, with event: UIEvent?) { 47 | if !draggable { 48 | super.touchesCancelled(touches, with: event) 49 | return 50 | } 51 | 52 | if moving { 53 | guard let touch = touches.first else { return } 54 | let offset = touch.location(in: window).y - movingStartY 55 | movingDidEnd(with: offset) 56 | } 57 | } 58 | 59 | override public func touchesEnded(_ touches: Set, with event: UIEvent?) { 60 | if !draggable { 61 | super.touchesEnded(touches, with: event) 62 | return 63 | } 64 | 65 | if moving { 66 | guard let touch = touches.first else { 67 | super.touchesBegan(touches, with: event) 68 | return 69 | } 70 | let offset = touch.location(in: window).y - movingStartY 71 | movingDidEnd(with: offset) 72 | } 73 | } 74 | 75 | private func movingDidEnd(with offset: CGFloat) { 76 | moving = false 77 | touchEventDelegate?.popup(self, touchDidEndWith: offset) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Classes/UIResponder+MTPopup.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+MTPopup.h 3 | // MTPopup 4 | // 5 | // Created by 黄伯驹 on 2017/10/30. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | CG_INLINE void 13 | ReplaceMethod(Class _class, SEL _originSelector, SEL _newSelector) { 14 | Method oriMethod = class_getInstanceMethod(_class, _originSelector); 15 | Method newMethod = class_getInstanceMethod(_class, _newSelector); 16 | BOOL isAddedMethod = class_addMethod(_class, _originSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)); 17 | if (isAddedMethod) { 18 | class_replaceMethod(_class, _newSelector, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod)); 19 | } else { 20 | method_exchangeImplementations(oriMethod, newMethod); 21 | } 22 | } 23 | 24 | @interface UIResponder (MTPopup) 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/UIResponder+MTPopup.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+MTPopup.m 3 | // MTPopup 4 | // 5 | // Created by 黄伯驹 on 2017/10/30. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import "UIResponder+MTPopup.h" 10 | 11 | 12 | @implementation UIResponder (MTPopup) 13 | + (void)load { 14 | static dispatch_once_t onceToken; 15 | dispatch_once(&onceToken, ^{ 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wundeclared-selector" 18 | 19 | ReplaceMethod(self, @selector(becomeFirstResponder), @selector(mt_becomeFirstResponder)); 20 | 21 | #pragma clang diagnostic pop 22 | }); 23 | } 24 | @end 25 | -------------------------------------------------------------------------------- /Classes/UIResponder+STPopup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+MTPopup.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | let MTPopupFirstResponderDidChange = Notification.Name(rawValue: "MTPopupFirstResponderDidChange") 10 | 11 | extension UIResponder { 12 | 13 | @objc func mt_becomeFirstResponder() -> Bool { 14 | let accepted = mt_becomeFirstResponder() 15 | if accepted { 16 | NotificationCenter.default.post(name: MTPopupFirstResponderDidChange, object: self) 17 | } 18 | return accepted 19 | } 20 | } 21 | 22 | extension DispatchQueue { 23 | 24 | private static var _onceTracker = [String]() 25 | 26 | public class func once(token: String, block: () -> Void) { 27 | objc_sync_enter(self); defer { objc_sync_exit(self) } 28 | 29 | if _onceTracker.contains(token) { 30 | return 31 | } 32 | 33 | _onceTracker.append(token) 34 | block() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Classes/UIViewController+MTPopup.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MTPopup.h 3 | // MTPopup 4 | // 5 | // Created by 黄伯驹 on 2017/10/30. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (MTPopup) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/UIViewController+MTPopup.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MTPopup.m 3 | // MTPopup 4 | // 5 | // Created by 黄伯驹 on 2017/10/30. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+MTPopup.h" 10 | #import "UIResponder+MTPopup.h" 11 | 12 | @implementation UIViewController (MTPopup) 13 | + (void)load { 14 | static dispatch_once_t onceToken; 15 | dispatch_once(&onceToken, ^{ 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wundeclared-selector" 18 | ReplaceMethod(self, @selector(viewDidLoad), @selector(mt_viewDidLoad)); 19 | ReplaceMethod(self, @selector(presentViewController:animated:completion:), @selector(mt_presentViewController:animated:completion:)); 20 | ReplaceMethod(self, @selector(dismissViewControllerAnimated:completion:), @selector(mt_dismissViewControllerAnimated:completion:)); 21 | ReplaceMethod(self, @selector(presentedViewController), @selector(mt_presentedViewController)); 22 | ReplaceMethod(self, @selector(presentingViewController), @selector(mt_presentingViewController)); 23 | #pragma clang diagnostic pop 24 | }); 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/UIViewController+STPopup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MTPopup.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | extension UIViewController { 10 | private struct AssociatedKeys { 11 | static var landscapeContentSizeInPopupKey: String? = "landscapeContentSizeInPopup" 12 | static var contentSizeInPopupKey: String? = "contentSizeInPopup" 13 | static var popupControllerKey: String? = "popupController" 14 | } 15 | 16 | func mt_viewDidLoad() { 17 | var contentSize = CGSize.zero 18 | switch UIApplication.shared.statusBarOrientation { 19 | case .landscapeLeft, .landscapeRight: 20 | contentSize = landscapeContentSizeInPopup 21 | if contentSize == .zero { 22 | contentSize = contentSizeInPopup 23 | } 24 | default: 25 | contentSize = contentSizeInPopup 26 | } 27 | 28 | if contentSize != .zero { 29 | view.frame = CGRect(origin: .zero, size: contentSize) 30 | } 31 | mt_viewDidLoad() 32 | } 33 | 34 | func mt_presentViewController(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?) { 35 | guard let popupController = popupController else { 36 | mt_presentViewController(viewControllerToPresent, animated: animated, completion: completion) 37 | return 38 | } 39 | 40 | let controller = popupController.value(forKey: "containerViewController") as? UIViewController 41 | controller?.present(viewControllerToPresent, animated: animated, completion: completion) 42 | } 43 | 44 | func mt_dismissViewControllerAnimated(_ animated: Bool, completion: (() -> Void)?) { 45 | guard let popupController = popupController else { 46 | mt_dismissViewControllerAnimated(animated, completion: completion) 47 | return 48 | } 49 | 50 | popupController.dismiss(with: completion) 51 | } 52 | 53 | var mt_presentedViewController: UIViewController? { 54 | guard let popupController = popupController else { return self.mt_presentedViewController } 55 | 56 | let controller = popupController.value(forKey: "containerViewController") as? UIViewController 57 | return controller?.presentedViewController 58 | } 59 | 60 | var mt_presentingViewController: UIViewController? { 61 | guard let popupController = popupController else { return self.mt_presentingViewController } 62 | let controller = popupController.value(forKey: "containerViewController") as? UIViewController 63 | return controller?.presentingViewController 64 | } 65 | 66 | static let screenW = UIScreen.main.bounds.width 67 | static let screenH = UIScreen.main.bounds.height 68 | 69 | public var contentSizeInPopup: CGSize { 70 | set { 71 | var value = newValue 72 | if value != .zero && value.width == 0 { 73 | switch UIApplication.shared.statusBarOrientation { 74 | case .landscapeLeft, .landscapeRight: 75 | value.width = UIViewController.screenH 76 | default: 77 | value.width = UIViewController.screenW 78 | } 79 | } 80 | 81 | objc_setAssociatedObject(self, &AssociatedKeys.contentSizeInPopupKey, NSValue(cgSize: value), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 82 | } 83 | 84 | get { 85 | return (objc_getAssociatedObject(self, &AssociatedKeys.contentSizeInPopupKey) as? CGSize) ?? .zero 86 | } 87 | } 88 | 89 | public var landscapeContentSizeInPopup: CGSize { 90 | set { 91 | var value = newValue 92 | if value != .zero && value.width == 0 { 93 | switch UIApplication.shared.statusBarOrientation { 94 | case .landscapeLeft, .landscapeRight: 95 | value.width = UIViewController.screenW 96 | default: 97 | value.width = UIViewController.screenH 98 | } 99 | } 100 | objc_setAssociatedObject(self, &AssociatedKeys.landscapeContentSizeInPopupKey, NSValue(cgSize: value), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 101 | } 102 | 103 | get { 104 | return (objc_getAssociatedObject(self, &AssociatedKeys.landscapeContentSizeInPopupKey) as? CGSize) ?? .zero 105 | } 106 | } 107 | 108 | public var popupController: MTPopupController? { 109 | set { 110 | guard let newValue = newValue else { return } 111 | objc_setAssociatedObject(self, &AssociatedKeys.popupControllerKey, newValue, .OBJC_ASSOCIATION_ASSIGN) 112 | } 113 | 114 | get { 115 | let popupController = objc_getAssociatedObject(self, &AssociatedKeys.popupControllerKey) as? MTPopupController 116 | guard let controller = popupController else { 117 | return parent?.popupController 118 | } 119 | return controller 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Demo/Cartfile: -------------------------------------------------------------------------------- 1 | 2 | github "huangboju/MTPopup" 3 | -------------------------------------------------------------------------------- /Demo/Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "huangboju/MTPopup" "1.0.2" 2 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | Packages/ 36 | .build/ 37 | 38 | # CocoaPods 39 | Pods/ 40 | 41 | # Carthage 42 | Carthage/Checkouts 43 | Carthage/Build 44 | 45 | # fastlane 46 | fastlane/report.xml 47 | fastlane/Preview.html 48 | fastlane/screenshots 49 | fastlane/test_output 50 | 51 | # OSX 52 | .DS_Store 53 | 54 | # Byte-compiled / optimized / DLL files 55 | __pycache__/ 56 | *.py[cod] 57 | *$py.class 58 | 59 | build_deploy.sh 60 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: # rule identifiers to exclude from running 2 | - cyclomatic_complexity 3 | - fixme 4 | - function_body_length 5 | - function_parameter_count 6 | - todo 7 | - valid_docs 8 | - variable_name 9 | - type_name 10 | opt_in_rules: # some rules are only opt-in 11 | #- empty_count 12 | # Find all the available rules by running: 13 | # swiftlint rules 14 | included: # paths to include during linting. `--path` is ignored if present. 15 | - STPopup 16 | excluded: # paths to ignore during linting. Takes precedence over `included`. 17 | # - Carthage 18 | # - Pods 19 | - Source/ExcludedFolder 20 | - Source/ExcludedFile.swift 21 | # configurable rules can be customized from this configuration file 22 | # binary rules can set their severity level 23 | force_cast: warning # implicitly 24 | force_try: 25 | severity: warning # explicitly 26 | # rules that have both warning and error levels, can set just the warning level 27 | # implicitly 28 | line_length: 400 # 29 | # they can set both implicitly with an array 30 | type_body_length: 31 | - 300 # warning 32 | - 400 # error 33 | # or they can set both explicitly 34 | file_length: 35 | warning: 500 36 | error: 1200 37 | # naming rules can set warnings/errors for min_length and max_length 38 | # additionally they can set excluded names 39 | type_name: 40 | min_length: 2 # only warning 41 | max_length: # warning and error 42 | warning: 40 43 | error: 50 44 | excluded: iPhone # excluded via string 45 | variable_name: 46 | min_length: 1 # only min_length 47 | excluded: # excluded via string array 48 | - id 49 | - URL 50 | - GlobalAPIKey 51 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle) 52 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/2017-03-21 20_24_31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangboju/MTPopup/a03237ca898154264d83fb0dbc7df97c6ccffea4/Demo/Carthage/Checkouts/MTPopup/2017-03-21 20_24_31.gif -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/Array+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2016年 伯驹 黄. All rights reserved. 3 | // 4 | 5 | extension Array where Element: Equatable { 6 | 7 | // Remove first collection element that is equal to the given `object`: 8 | mutating func remove(_ object: Element) { 9 | guard let index = index(of: object) else { return } 10 | remove(at: index) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/Bridging.h: -------------------------------------------------------------------------------- 1 | // 2 | // Bridging.h 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/12/2. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import 10 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupContainerViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupContainerViewController.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/6. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | public class MTPopupContainerViewController: UIViewController { 10 | 11 | override public var preferredStatusBarStyle: UIStatusBarStyle { 12 | guard let presentingViewController = presentingViewController, !childViewControllers.isEmpty else { 13 | return super.preferredStatusBarStyle 14 | } 15 | return presentingViewController.preferredStatusBarStyle 16 | } 17 | 18 | override public var childViewControllerForStatusBarHidden: UIViewController? { 19 | return childViewControllers.last 20 | } 21 | 22 | override public var childViewControllerForStatusBarStyle: UIViewController? { 23 | return childViewControllers.last 24 | } 25 | 26 | override public func show(_ vc: UIViewController, sender _: Any?) { 27 | method(vc: vc) 28 | } 29 | 30 | override public func showDetailViewController(_ vc: UIViewController, sender _: Any?) { 31 | method(vc: vc) 32 | } 33 | 34 | private func method(vc: UIViewController) { 35 | let size = vc.landscapeContentSizeInPopup 36 | let contentSize = vc.contentSizeInPopup 37 | if contentSize != .zero || size != .zero { 38 | let childViewController = childViewControllers.last 39 | childViewController?.popupController?.push(vc, animated: true) 40 | } else { 41 | present(vc, animated: true, completion: nil) 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupController.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | enum MTPopupControllerTransitioningAction { 10 | case present, dismiss 11 | } 12 | 13 | public enum MTPopupStyle { 14 | case formSheet, bottomSheet 15 | } 16 | 17 | public enum MTPopupTransitionStyle { 18 | case slideVertical, fade, custom 19 | } 20 | 21 | public class MTPopupController: NSObject { 22 | public var style: MTPopupStyle = .formSheet 23 | public var transitionStyle = MTPopupTransitionStyle.slideVertical 24 | public var transitioning: MTPopupControllerTransitioning? 25 | public var navigationBarHidden = false { 26 | didSet { 27 | set(navigationBarHidden: navigationBarHidden, animated: false) 28 | } 29 | } 30 | public var hidesCloseButton = false { 31 | didSet { 32 | updateNavigationBar(animated: false) 33 | } 34 | } 35 | public var navigationBar: MTPopupNavigationBar? 36 | public var backgroundView: UIView? { 37 | willSet { 38 | backgroundView?.removeFromSuperview() 39 | newValue?.autoresizingMask = [.flexibleWidth, .flexibleHeight] 40 | newValue?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(bgViewDidTap))) 41 | 42 | containerViewController?.view.insertSubview(newValue!, at: 0) 43 | } 44 | } 45 | public var containerView: UIView? 46 | public var topViewController: UIViewController? { 47 | return viewControllers.last 48 | } 49 | public var presented: Bool { 50 | return containerViewController!.presentingViewController != nil 51 | } 52 | 53 | public var containerViewController: MTPopupContainerViewController? 54 | 55 | fileprivate let MTPopupBottomSheetExtraHeight: CGFloat = 80 56 | 57 | private var viewControllers: [UIViewController] = [] 58 | private var defaultTitleLabel: UILabel? 59 | private var defaultLeftBarItem: MTPopupLeftBarItem? 60 | private var keyboardInfo: [String: Any]? 61 | private var observing = false 62 | fileprivate var contentView: UIView? 63 | fileprivate let transitioningSlideVertical = MTPopupControllerTransitioningSlideVertical() 64 | fileprivate let transitioningFade = MTPopupControllerTransitioningFade() 65 | 66 | override init() { 67 | super.init() 68 | 69 | containerViewController = MTPopupContainerViewController() 70 | containerViewController?.view.backgroundColor = .clear 71 | 72 | let flag = UIDevice.current.systemVersion.compare("8.0", options: .numeric) != .orderedAscending 73 | containerViewController?.modalPresentationStyle = flag ? .overCurrentContext : .custom 74 | 75 | containerViewController?.transitioningDelegate = self 76 | 77 | setupBackgroundView() 78 | setupContainerView() 79 | setupNavigationBar() 80 | } 81 | 82 | public convenience init(rootViewController: UIViewController) { 83 | self.init() 84 | push(rootViewController, animated: false) 85 | } 86 | 87 | deinit { 88 | destroyObservers() 89 | viewControllers.forEach { 90 | $0.popupController = nil 91 | destroyObservers(of: $0) 92 | } 93 | } 94 | 95 | func setupObservers() { 96 | if observing { return } 97 | observing = true 98 | 99 | navigationBar?.addObserver(self, forKeyPath: "tintColor", options: .new, context: nil) 100 | navigationBar?.addObserver(self, forKeyPath: "titleTextAttributes", options: .new, context: nil) 101 | 102 | NotificationCenter.default.addObserver(self, selector: #selector(orientationDidChange), name: .UIApplicationDidChangeStatusBarOrientation, object: nil) 103 | 104 | let keyboardShowing = #selector(keyboardWillShow) 105 | let items: [(Selector, Notification.Name)] = [ 106 | (keyboardShowing, .UIKeyboardWillShow), 107 | (keyboardShowing, .UIKeyboardWillChangeFrame), 108 | (#selector(keyboardWillHide), .UIKeyboardWillHide), 109 | (#selector(firstResponderDidChange), MTPopupFirstResponderDidChange) 110 | ] 111 | 112 | items.forEach { 113 | NotificationCenter.default.addObserver(self, selector: $0.0, name: $0.1, object: nil) 114 | } 115 | } 116 | 117 | func destroyObservers() { 118 | if !observing { return } 119 | 120 | observing = false 121 | 122 | navigationBar?.removeObserver(self, forKeyPath: "tintColor") 123 | navigationBar?.removeObserver(self, forKeyPath: "titleTextAttributes") 124 | NotificationCenter.default.removeObserver(self) 125 | } 126 | 127 | func setupObservers(for viewController: UIViewController) { 128 | viewController.addObserver(self, forKeyPath: "contentSizeInPopup", options: .new, context: nil) 129 | viewController.addObserver(self, forKeyPath: "landscapeContentSizeInPopup", options: .new, context: nil) 130 | 131 | let keys = [ 132 | "title", 133 | "titleView", 134 | "leftBarButtonItem", 135 | "leftBarButtonItems", 136 | "rightBarButtonItem", 137 | "rightBarButtonItems", 138 | "hidesBackButton" 139 | ] 140 | 141 | keys.forEach { 142 | viewController.navigationItem.addObserver(self, forKeyPath: $0, options: .new, context: nil) 143 | } 144 | } 145 | 146 | func destroyObservers(of viewController: UIViewController) { 147 | viewController.removeObserver(self, forKeyPath: "contentSizeInPopup") 148 | viewController.removeObserver(self, forKeyPath: "landscapeContentSizeInPopup") 149 | 150 | let keys = [ 151 | "title", 152 | "titleView", 153 | "leftBarButtonItem", 154 | "leftBarButtonItems", 155 | "rightBarButtonItem", 156 | "rightBarButtonItems", 157 | "hidesBackButton" 158 | ] 159 | 160 | keys.forEach { 161 | viewController.navigationItem.removeObserver(self, forKeyPath: $0) 162 | } 163 | } 164 | 165 | override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) { 166 | let topViewController = self.topViewController! 167 | let condition = topViewController.isViewLoaded && topViewController.view.superview != nil 168 | if object is MTPopupNavigationBar || object is UINavigationItem { 169 | if condition { 170 | updateNavigationBar(animated: false) 171 | } 172 | } else if object is UIViewController { 173 | guard condition else { return } 174 | UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 175 | self.layoutContainerView() 176 | }, completion: nil) 177 | } 178 | } 179 | 180 | // MARK: - MTPopupController present & dismiss & push & pop 181 | var retainedPopupControllers: Set = [] 182 | 183 | public func present(in viewController: UIViewController) { 184 | present(in: viewController, completion: nil) 185 | } 186 | 187 | public func present(in viewController: UIViewController, completion: (() -> Void)?) { 188 | if presented { return } 189 | 190 | setupObservers() 191 | 192 | retainedPopupControllers.insert(self) 193 | 194 | let controller = viewController.tabBarController ?? viewController 195 | controller.present(containerViewController!, animated: true, completion: completion) 196 | } 197 | 198 | public func dismiss() { 199 | dismiss(with: nil) 200 | } 201 | 202 | public func dismiss(with completion: (() -> Void)?) { 203 | if !presented { return } 204 | 205 | destroyObservers() 206 | 207 | containerViewController?.dismiss(animated: true, completion: { 208 | _ = self.retainedPopupControllers.remove(self) 209 | completion?() 210 | }) 211 | } 212 | 213 | public func push(_ viewController: UIViewController, animated: Bool) { 214 | let topViewController = self.topViewController 215 | 216 | viewController.popupController = self 217 | 218 | viewControllers.append(viewController) 219 | 220 | if presented { 221 | transit(from: topViewController!, toVC: viewController, animated: animated) 222 | } 223 | 224 | setupObservers(for: viewController) 225 | } 226 | 227 | public func popViewController(_ animated: Bool) { 228 | if viewControllers.count <= 1 { 229 | dismiss() 230 | return 231 | } 232 | 233 | let topViewController = self.topViewController 234 | destroyObservers(of: topViewController!) 235 | viewControllers.remove(topViewController!) 236 | 237 | if presented { 238 | transit(from: topViewController!, toVC: self.topViewController!, animated: animated) 239 | } 240 | 241 | topViewController?.popupController = nil 242 | } 243 | 244 | func transit(from fromVC: UIViewController, toVC: UIViewController, animated: Bool) { 245 | fromVC.beginAppearanceTransition(false, animated: animated) 246 | toVC.beginAppearanceTransition(true, animated: animated) 247 | 248 | fromVC.willMove(toParentViewController: nil) 249 | containerViewController?.addChildViewController(toVC) 250 | 251 | if animated { 252 | UIGraphicsBeginImageContextWithOptions(fromVC.view.bounds.size, false, UIScreen.main.scale) 253 | fromVC.view.drawHierarchy(in: fromVC.view.bounds, afterScreenUpdates: false) 254 | 255 | let capturedView = UIImageView(image: UIGraphicsGetImageFromCurrentImageContext()) 256 | UIGraphicsEndImageContext() 257 | 258 | capturedView.frame = CGRect(origin: contentView!.frame.origin, size: fromVC.view.bounds.size) 259 | 260 | containerView?.insertSubview(capturedView, at: 0) 261 | 262 | fromVC.view.removeFromSuperview() 263 | 264 | containerView?.isUserInteractionEnabled = false 265 | toVC.view.alpha = 0 266 | UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 267 | self.layoutContainerView() 268 | self.contentView?.addSubview(toVC.view) 269 | capturedView.alpha = 0 270 | toVC.view.alpha = 1 271 | self.containerViewController?.setNeedsStatusBarAppearanceUpdate() 272 | }, completion: { (flag) in 273 | capturedView.removeFromSuperview() 274 | fromVC.removeFromParentViewController() 275 | 276 | self.containerView?.isUserInteractionEnabled = true 277 | toVC.didMove(toParentViewController: self.containerViewController) 278 | 279 | fromVC.endAppearanceTransition() 280 | toVC.endAppearanceTransition() 281 | }) 282 | updateNavigationBar(animated: animated) 283 | } else { 284 | layoutContainerView() 285 | contentView?.addSubview(toVC.view) 286 | containerViewController?.setNeedsStatusBarAppearanceUpdate() 287 | updateNavigationBar(animated: animated) 288 | 289 | fromVC.view.removeFromSuperview() 290 | fromVC.removeFromParentViewController() 291 | 292 | toVC.didMove(toParentViewController: containerViewController) 293 | 294 | fromVC.endAppearanceTransition() 295 | toVC.endAppearanceTransition() 296 | } 297 | } 298 | 299 | func updateNavigationBar(animated: Bool) { 300 | guard let topViewController = topViewController else { 301 | return 302 | } 303 | let shouldAnimateDefaultLeftBarItem = animated && navigationBar?.topItem?.leftBarButtonItem == defaultLeftBarItem 304 | 305 | let lastTitleView = navigationBar?.topItem?.titleView 306 | navigationBar?.items = [UINavigationItem()] 307 | if topViewController.navigationItem.leftBarButtonItems == nil { 308 | if topViewController.navigationItem.hidesBackButton { 309 | topViewController.navigationItem.leftBarButtonItems = nil 310 | } else { 311 | navigationBar?.topItem?.leftBarButtonItems = [defaultLeftBarItem!] 312 | } 313 | } 314 | navigationBar?.topItem?.rightBarButtonItems = topViewController.navigationItem.rightBarButtonItems 315 | if hidesCloseButton && topViewController == viewControllers.first && navigationBar?.topItem?.leftBarButtonItem == defaultLeftBarItem { 316 | navigationBar?.topItem?.leftBarButtonItems = nil 317 | } 318 | 319 | if animated { 320 | var fromTitleView: UIView?, toTitleView: UIView? 321 | if lastTitleView == defaultTitleLabel { 322 | let tempLabel = UILabel(frame: defaultTitleLabel!.frame) 323 | tempLabel.textColor = defaultTitleLabel?.textColor 324 | tempLabel.font = defaultTitleLabel?.font 325 | tempLabel.attributedText = NSAttributedString(string: defaultTitleLabel?.text ?? "", attributes: navigationBar?.titleTextAttributes) 326 | fromTitleView = tempLabel 327 | } else { 328 | fromTitleView = lastTitleView 329 | } 330 | 331 | if let titleView = topViewController.navigationItem.titleView { 332 | toTitleView = titleView 333 | } else { 334 | let title = topViewController.title ?? (topViewController.navigationItem.title ?? "") 335 | defaultTitleLabel = UILabel() 336 | defaultTitleLabel?.attributedText = NSAttributedString(string: title, attributes: navigationBar!.titleTextAttributes) 337 | defaultTitleLabel?.sizeToFit() 338 | toTitleView = defaultTitleLabel 339 | } 340 | 341 | navigationBar?.addSubview(fromTitleView!) 342 | navigationBar?.topItem?.titleView = toTitleView 343 | toTitleView?.alpha = 0 344 | 345 | UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 346 | fromTitleView?.alpha = 0 347 | toTitleView?.alpha = 1 348 | }, completion: { _ in 349 | fromTitleView?.removeFromSuperview() 350 | }) 351 | } else { 352 | if let titleView = topViewController.navigationItem.titleView { 353 | navigationBar?.topItem?.titleView = titleView 354 | } else { 355 | let title = topViewController.title ?? (topViewController.navigationItem.title ?? "") 356 | defaultTitleLabel = UILabel() 357 | defaultTitleLabel?.attributedText = NSAttributedString(string: title, attributes: navigationBar!.titleTextAttributes) 358 | defaultTitleLabel?.sizeToFit() 359 | navigationBar?.topItem?.titleView = defaultTitleLabel 360 | } 361 | } 362 | 363 | defaultLeftBarItem?.tintColor = navigationBar?.tintColor 364 | defaultLeftBarItem?.set(viewControllers.count > 1 ? .arrow : .cross, animated: shouldAnimateDefaultLeftBarItem) 365 | } 366 | 367 | func set(navigationBarHidden: Bool, animated: Bool) { 368 | navigationBar?.alpha = navigationBarHidden ? 1 : 0 369 | 370 | if !animated { 371 | layoutContainerView() 372 | navigationBar?.isHidden = navigationBarHidden 373 | return 374 | } 375 | 376 | if !navigationBarHidden { 377 | navigationBar?.isHidden = navigationBarHidden 378 | } 379 | 380 | UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 381 | self.navigationBar?.alpha = navigationBarHidden ? 0 : 1 382 | self.layoutContainerView() 383 | }, completion: { flag in 384 | self.navigationBar?.isHidden = navigationBarHidden 385 | }) 386 | } 387 | 388 | func layoutContainerView() { 389 | 390 | guard let containerViewController = containerViewController else { return } 391 | 392 | backgroundView?.frame = containerViewController.view.bounds 393 | 394 | let navigationBarHeight = navigationBarHidden ? 0 : preferredNavigationBarHeight 395 | let containerViewWidth = contentSizeOfTopView.width 396 | var containerViewHeight = contentSizeOfTopView.height + navigationBarHeight 397 | var containerViewY = (containerViewController.view.bounds.height - containerViewHeight) / 2 398 | 399 | if style == .bottomSheet { 400 | containerViewY = containerViewController.view.bounds.height - containerViewHeight 401 | containerViewHeight += MTPopupBottomSheetExtraHeight 402 | } 403 | 404 | containerView?.frame = CGRect(x: (containerViewController.view.bounds.width - containerViewWidth) / 2, y: containerViewY, width: containerViewWidth, height: containerViewHeight) 405 | 406 | navigationBar?.frame = CGRect(x: 0, y: 0, width: containerViewWidth, height: preferredNavigationBarHeight) 407 | contentView?.frame = CGRect(x: 0, y: navigationBarHeight, width: contentSizeOfTopView.width, height: contentSizeOfTopView.height) 408 | 409 | let topViewController = self.topViewController 410 | topViewController?.view.frame = contentView!.bounds 411 | } 412 | 413 | var contentSizeOfTopView: CGSize { 414 | var contentSize = CGSize.zero 415 | 416 | guard let topViewController = topViewController else { return contentSize } 417 | 418 | switch UIApplication.shared.statusBarOrientation { 419 | case .landscapeLeft, .landscapeRight: 420 | contentSize = topViewController.landscapeContentSizeInPopup 421 | if contentSize == .zero { 422 | contentSize = topViewController.contentSizeInPopup 423 | } 424 | default: 425 | contentSize = topViewController.contentSizeInPopup 426 | } 427 | 428 | return contentSize 429 | } 430 | 431 | var preferredNavigationBarHeight: CGFloat { 432 | let navigationController = UINavigationController() 433 | return navigationController.navigationBar.bounds.height 434 | } 435 | 436 | func setupBackgroundView() { 437 | backgroundView = UIView() 438 | backgroundView?.backgroundColor = UIColor(white: 0, alpha: 0.5) 439 | } 440 | 441 | func setupContainerView() { 442 | containerView = UIView() 443 | containerView?.backgroundColor = UIColor.white 444 | containerView?.layer.cornerRadius = 4 445 | containerView?.clipsToBounds = true 446 | containerViewController?.view.addSubview(containerView!) 447 | 448 | contentView = UIView() 449 | containerView?.addSubview(contentView!) 450 | } 451 | 452 | func setupNavigationBar() { 453 | navigationBar = MTPopupNavigationBar() 454 | navigationBar?.touchEventDelegate = self 455 | 456 | containerView?.addSubview(navigationBar!) 457 | 458 | defaultTitleLabel = UILabel() 459 | defaultLeftBarItem = MTPopupLeftBarItem(with: self, action: #selector(leftBarItemDidTap)) 460 | } 461 | 462 | func leftBarItemDidTap() { 463 | switch defaultLeftBarItem!.type { 464 | case .cross: 465 | dismiss() 466 | case .arrow: 467 | popViewController(true) 468 | } 469 | } 470 | 471 | func bgViewDidTap() { 472 | containerView?.endEditing(true) 473 | } 474 | 475 | // MARK: - UIApplicationDidChangeStatusBarOrientationNotification 476 | func orientationDidChange() { 477 | containerView?.endEditing(true) 478 | UIView.animate(withDuration: 0.2, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 479 | self.containerView?.alpha = 0 480 | }, completion: { flag in 481 | self.layoutContainerView() 482 | UIView.animate(withDuration: 0.2, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 483 | self.containerView?.alpha = 1 484 | }, completion: nil) 485 | }) 486 | } 487 | 488 | // MARK: - UIKeyboardWillShowNotification & UIKeyboardWillHideNotification 489 | func keyboardWillShow(notification: Notification) { 490 | guard getCurrentTextInput(in: containerView!) != nil else { return } 491 | 492 | keyboardInfo = notification.userInfo as? [String: Any] 493 | adjustContainerViewOrigin() 494 | } 495 | 496 | func keyboardWillHide(notification: Notification) { 497 | keyboardInfo = nil 498 | 499 | guard let keyboardInfo = notification.userInfo as? [String: Any] else { return } 500 | 501 | setAnimation(with: keyboardInfo, transform: CGAffineTransform.identity) 502 | } 503 | 504 | func adjustContainerViewOrigin() { 505 | guard let keyboardInfo = keyboardInfo else { return } 506 | guard let currentTextInput = getCurrentTextInput(in: containerView!) else { return } 507 | 508 | let lastTransform = containerView?.transform 509 | containerView?.transform = CGAffineTransform.identity 510 | 511 | let textFieldBottomY = currentTextInput.convert(.zero, to: containerViewController?.view).y + currentTextInput.bounds.height 512 | let keyboardHeight = (keyboardInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0 513 | 514 | var offsetY: CGFloat = 0 515 | guard let minY = containerView?.frame.minY else { return } 516 | if style == .bottomSheet { 517 | offsetY = keyboardHeight 518 | } else { 519 | let spacing: CGFloat = 5 520 | let height = containerViewController!.view.bounds.height - keyboardHeight - spacing 521 | offsetY = minY + containerView!.bounds.height - height 522 | if offsetY <= 0 { return } 523 | 524 | let statusBarHeight = UIApplication.shared.statusBarFrame.height 525 | 526 | if minY - offsetY < statusBarHeight { 527 | offsetY = minY - statusBarHeight 528 | guard textFieldBottomY - offsetY > height else { return } 529 | offsetY = textFieldBottomY - height 530 | } 531 | } 532 | 533 | containerView?.transform = lastTransform! 534 | 535 | setAnimation(with: keyboardInfo, transform: CGAffineTransform(translationX: 0, y: -offsetY)) 536 | } 537 | 538 | func setAnimation(with keyboardInfo: [String: Any], transform: CGAffineTransform) { 539 | guard let duration = (keyboardInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue else { return } 540 | guard let curve = (keyboardInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int) else { return } 541 | 542 | UIView.beginAnimations(nil, context: nil) 543 | UIView.setAnimationBeginsFromCurrentState(true) 544 | UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: curve)!) 545 | UIView.setAnimationDuration(duration) 546 | 547 | containerView?.transform = transform 548 | 549 | UIView.commitAnimations() 550 | } 551 | 552 | func getCurrentTextInput(in view: UIView) -> UIView? { 553 | if view.conforms(to: UIKeyInput.self) && view.isFirstResponder { 554 | if let webBrowserClass = NSClassFromString("UIWebBrowserView"), let contentClass = NSClassFromString("WKContentView") { 555 | if view.isKind(of: webBrowserClass) || view.isKind(of: contentClass) { 556 | return nil 557 | } 558 | } 559 | return view 560 | } 561 | 562 | for subview in view.subviews { 563 | let v = getCurrentTextInput(in: subview) 564 | if let v = v { 565 | return v 566 | } 567 | } 568 | 569 | return nil 570 | } 571 | 572 | // MARK: - MTPopupFirstResponderDidChangeNotification 573 | func firstResponderDidChange() { 574 | adjustContainerViewOrigin() 575 | } 576 | } 577 | 578 | extension MTPopupController: UIViewControllerTransitioningDelegate { 579 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 580 | return self 581 | } 582 | 583 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 584 | return self 585 | } 586 | } 587 | 588 | extension MTPopupController: UIViewControllerAnimatedTransitioning { 589 | func convert(_ transitioningContext: UIViewControllerContextTransitioning?) -> MTPopupControllerTransitioningContext { 590 | var action: MTPopupControllerTransitioningAction = .present 591 | if transitioningContext?.viewController(forKey: .to) != containerViewController { 592 | action = .dismiss 593 | } 594 | return MTPopupControllerTransitioningContext(containerView: containerView!, action: action) 595 | } 596 | 597 | public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 598 | let context = convert(transitionContext) 599 | switch transitionStyle { 600 | case .slideVertical: 601 | return transitioningSlideVertical.popupControllerTransitionDuration(context) 602 | case .fade: 603 | return transitioningFade.popupControllerTransitionDuration(context) 604 | case .custom: 605 | return transitioning!.popupControllerTransitionDuration(context) 606 | } 607 | } 608 | 609 | public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 610 | guard let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to) else { return } 611 | 612 | toVC.view.frame = fromVC.view.frame 613 | 614 | let topViewController = self.topViewController 615 | 616 | let context = convert(transitionContext) 617 | var transitioning: MTPopupControllerTransitioning? 618 | switch transitionStyle { 619 | case .slideVertical: 620 | transitioning = transitioningSlideVertical 621 | case .fade: 622 | transitioning = transitioningFade 623 | case .custom: 624 | transitioning = self.transitioning 625 | } 626 | 627 | let duration = transitioning!.popupControllerTransitionDuration(context) 628 | if context.action == .present { 629 | fromVC.beginAppearanceTransition(false, animated: true) 630 | transitionContext.containerView.addSubview(toVC.view) 631 | 632 | topViewController?.beginAppearanceTransition(true, animated: true) 633 | toVC.addChildViewController(topViewController!) 634 | 635 | layoutContainerView() 636 | contentView?.addSubview(topViewController!.view) 637 | topViewController?.setNeedsStatusBarAppearanceUpdate() 638 | updateNavigationBar(animated: false) 639 | 640 | let lastBackgroundViewAlpha = backgroundView?.alpha ?? 0 641 | backgroundView?.alpha = 0 642 | backgroundView?.isUserInteractionEnabled = false 643 | containerView?.isUserInteractionEnabled = false 644 | containerView?.transform = CGAffineTransform.identity 645 | 646 | UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: { 647 | self.backgroundView?.alpha = lastBackgroundViewAlpha 648 | }, completion: nil) 649 | 650 | transitioning?.popupControllerAnimateTransition(context, completion: { 651 | self.backgroundView?.isUserInteractionEnabled = true 652 | self.containerView?.isUserInteractionEnabled = true 653 | 654 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 655 | topViewController?.didMove(toParentViewController: toVC) 656 | fromVC.endAppearanceTransition() 657 | }) 658 | } else { 659 | toVC.beginAppearanceTransition(true, animated: true) 660 | 661 | topViewController?.beginAppearanceTransition(false, animated: true) 662 | topViewController?.willMove(toParentViewController: nil) 663 | 664 | let lastBackgroundViewAlpha = backgroundView?.alpha 665 | backgroundView?.isUserInteractionEnabled = false 666 | containerView?.isUserInteractionEnabled = false 667 | 668 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 669 | self.backgroundView?.alpha = 0 670 | }, completion: nil) 671 | 672 | transitioning?.popupControllerAnimateTransition(context, completion: { 673 | self.backgroundView?.isUserInteractionEnabled = true 674 | self.containerView?.isUserInteractionEnabled = true 675 | 676 | fromVC.view.removeFromSuperview() 677 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 678 | 679 | topViewController?.view.removeFromSuperview() 680 | topViewController?.removeFromParentViewController() 681 | 682 | toVC.endAppearanceTransition() 683 | 684 | self.backgroundView?.alpha = lastBackgroundViewAlpha! 685 | }) 686 | } 687 | } 688 | } 689 | 690 | extension MTPopupController: MTPopupNavigationTouchEventDelegate { 691 | func popup(_ navigationBar: MTPopupNavigationBar, touchDidMoveWith offset: CGFloat) { 692 | containerView?.endEditing(true) 693 | if style == .bottomSheet && offset < -MTPopupBottomSheetExtraHeight { 694 | return 695 | } 696 | 697 | containerView?.transform = CGAffineTransform(translationX: 0, y: offset) 698 | } 699 | 700 | func popup(_ navigationBar: MTPopupNavigationBar, touchDidEndWith offset: CGFloat) { 701 | if offset > 150 { 702 | let transitionStyle = self.transitionStyle 703 | self.transitionStyle = .slideVertical 704 | dismiss() { 705 | self.transitionStyle = transitionStyle 706 | } 707 | } else { 708 | containerView?.endEditing(true) 709 | UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 710 | self.containerView?.transform = CGAffineTransform.identity 711 | }, completion: nil) 712 | } 713 | } 714 | } 715 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupControllerTransitioning.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2016年 伯驹 黄. All rights reserved. 3 | // 4 | 5 | public protocol MTPopupControllerTransitioning { 6 | /** 7 | Return duration of transitioning, it will be used to animate transitioning of background view. 8 | */ 9 | func popupControllerTransitionDuration(_ context: MTPopupControllerTransitioningContext) -> TimeInterval 10 | /** 11 | Animate transitioning the container view of popup controller. "completion" need to be called after transitioning is finished. 12 | Initially "containerView" will be placed at the final position with transform = CGAffineTransformIdentity if it's presenting. 13 | */ 14 | func popupControllerAnimateTransition(_ context: MTPopupControllerTransitioningContext, completion: (() -> Void)?) 15 | } 16 | 17 | extension MTPopupControllerTransitioning { 18 | func popupControllerTransitionDuration(_ context: MTPopupControllerTransitioningContext) -> TimeInterval { 19 | if self is MTPopupControllerTransitioningFade { 20 | return context.action == .present ? 0.25 : 0.2 21 | } else { 22 | return context.action == .present ? 0.5 : 0.35 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupControllerTransitioningContext.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupControllerTransitioningContext.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | public class MTPopupControllerTransitioningContext { 10 | var action: MTPopupControllerTransitioningAction = .present 11 | var containerView: UIView? 12 | 13 | init(containerView: UIView, action: MTPopupControllerTransitioningAction) { 14 | self.containerView = containerView 15 | self.action = action 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupControllerTransitioningFade.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupControllerTransitioningFade.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | class MTPopupControllerTransitioningFade: MTPopupControllerTransitioning { 10 | 11 | func popupControllerAnimateTransition(_ context: MTPopupControllerTransitioningContext, completion: (() -> Void)?) { 12 | let containerView = context.containerView 13 | let duration = popupControllerTransitionDuration(context) 14 | 15 | if context.action == .present { 16 | containerView?.alpha = 0 17 | containerView?.transform = CGAffineTransform(scaleX: 1.05, y: 1.05) 18 | 19 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 20 | containerView?.alpha = 1 21 | containerView?.transform = CGAffineTransform.identity 22 | }, completion: { _ in 23 | completion?() 24 | }) 25 | } else { 26 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 27 | containerView?.alpha = 0 28 | }, completion: { _ in 29 | containerView?.alpha = 1 30 | completion?() 31 | }) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupControllerTransitioningSlideVertical.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupControllerTransitioningSlideVertical.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | class MTPopupControllerTransitioningSlideVertical: MTPopupControllerTransitioning { 10 | 11 | func popupControllerAnimateTransition(_ context: MTPopupControllerTransitioningContext, completion: (() -> Void)?) { 12 | guard let containerView = context.containerView else { return } 13 | let duration = popupControllerTransitionDuration(context) 14 | if context.action == .present { 15 | containerView.transform = CGAffineTransform(translationX: 0, y: containerView.superview!.bounds.height - containerView.frame.minY) 16 | 17 | UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: { 18 | containerView.transform = CGAffineTransform.identity 19 | }, completion: { _ in 20 | completion?() 21 | }) 22 | } else { 23 | let lastTransform = containerView.transform 24 | containerView.transform = CGAffineTransform.identity 25 | let originY = containerView.frame.minY 26 | containerView.transform = lastTransform 27 | 28 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 29 | containerView.transform = CGAffineTransform(translationX: 0, y: containerView.superview!.bounds.height - originY + containerView.frame.height) 30 | }, completion: { _ in 31 | containerView.transform = CGAffineTransform.identity 32 | completion?() 33 | }) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupLeftBarItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupLeftBarItem.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | enum MTPopupLeftBarItemType { 10 | case cross, arrow 11 | } 12 | 13 | class MTPopupLeftBarItem: UIBarButtonItem { 14 | var type: MTPopupLeftBarItemType = .cross 15 | 16 | private lazy var bar1: UIView = { 17 | let bar1 = UIView() 18 | bar1.backgroundColor = UIColor(white: 0.4, alpha: 1) 19 | bar1.isUserInteractionEnabled = false 20 | bar1.layer.allowsEdgeAntialiasing = true 21 | return bar1 22 | }() 23 | 24 | private lazy var bar2: UIView = { 25 | let bar2 = UIView() 26 | bar2.backgroundColor = UIColor(white: 0.4, alpha: 1) 27 | bar2.isUserInteractionEnabled = false 28 | bar2.layer.allowsEdgeAntialiasing = true 29 | return bar2 30 | }() 31 | 32 | convenience init(with target: Any?, action: Selector) { 33 | self.init() 34 | customView = UIControl(frame: CGRect(x: 0, y: 0, width: 18, height: 44)) 35 | (customView as? UIControl)?.addTarget(target, action: action, for: .touchUpInside) 36 | 37 | customView?.addSubview(bar1) 38 | 39 | customView?.addSubview(bar2) 40 | } 41 | 42 | func set(_ type: MTPopupLeftBarItemType, animated: Bool) { 43 | self.type = type 44 | if animated { 45 | UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: { 46 | self.updateLayout() 47 | }, completion: nil) 48 | } else { 49 | updateLayout() 50 | } 51 | } 52 | 53 | private func updateLayout() { 54 | var barWidth: CGFloat = 0 55 | let barHeight: CGFloat = 1.5 56 | var barX: CGFloat = 0 57 | var bar1Y: CGFloat = 0 58 | var bar2Y: CGFloat = 0 59 | guard let customView = customView else { return } 60 | switch type { 61 | case .cross: 62 | barWidth = customView.frame.height * 2 / 5 63 | barX = (customView.frame.width - barWidth) / 2 64 | bar1Y = (customView.frame.height - barHeight) / 2 65 | bar2Y = bar1Y 66 | case .arrow: 67 | barWidth = customView.frame.height / 4 68 | barX = (customView.frame.width - barWidth) / 2 - barWidth / 2 69 | bar1Y = (customView.frame.height - barHeight) / 2 + barWidth / 2 * sin(.pi / 4) 70 | bar2Y = (customView.frame.height - barHeight) / 2 - barWidth / 2 * sin(.pi / 4) 71 | } 72 | 73 | bar1.transform = CGAffineTransform.identity 74 | bar2.transform = CGAffineTransform.identity 75 | bar1.frame = CGRect(x: barX, y: bar1Y, width: barWidth, height: barHeight) 76 | bar2.frame = CGRect(x: barX, y: bar2Y, width: barWidth, height: barHeight) 77 | 78 | bar1.transform = CGAffineTransform(rotationAngle: .pi / 4) 79 | bar2.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 4) 80 | } 81 | 82 | override var tintColor: UIColor? { 83 | didSet { 84 | bar1.backgroundColor = tintColor 85 | bar2.backgroundColor = tintColor 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/MTPopupNavigationBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopupNavigationBar.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | protocol MTPopupNavigationTouchEventDelegate: class { 10 | func popup(_ navigationBar: MTPopupNavigationBar, touchDidMoveWith offset: CGFloat) 11 | func popup(_ navigationBar: MTPopupNavigationBar, touchDidEndWith offset: CGFloat) 12 | } 13 | 14 | public class MTPopupNavigationBar: UINavigationBar { 15 | var draggable = true 16 | weak var touchEventDelegate: MTPopupNavigationTouchEventDelegate? 17 | 18 | private var moving = false 19 | private var movingStartY: CGFloat = 0 20 | 21 | override public func touchesBegan(_ touches: Set, with event: UIEvent?) { 22 | if !draggable { 23 | super.touchesBegan(touches, with: event) 24 | return 25 | } 26 | guard let touch = touches.first else { return } 27 | if (touch.view == self || touch.view?.superview == self) && !moving { 28 | moving = true 29 | movingStartY = touch.location(in: window).y 30 | } 31 | } 32 | 33 | override public func touchesMoved(_ touches: Set, with event: UIEvent?) { 34 | if !draggable { 35 | super.touchesMoved(touches, with: event) 36 | return 37 | } 38 | 39 | if moving { 40 | guard let touch = touches.first else { return } 41 | let offset = touch.location(in: window).y - movingStartY 42 | touchEventDelegate?.popup(self, touchDidMoveWith: offset) 43 | } 44 | } 45 | 46 | override public func touchesCancelled(_ touches: Set, with event: UIEvent?) { 47 | if !draggable { 48 | super.touchesCancelled(touches, with: event) 49 | return 50 | } 51 | 52 | if moving { 53 | guard let touch = touches.first else { return } 54 | let offset = touch.location(in: window).y - movingStartY 55 | movingDidEnd(with: offset) 56 | } 57 | } 58 | 59 | override public func touchesEnded(_ touches: Set, with event: UIEvent?) { 60 | if !draggable { 61 | super.touchesEnded(touches, with: event) 62 | return 63 | } 64 | 65 | if moving { 66 | guard let touch = touches.first else { 67 | super.touchesBegan(touches, with: event) 68 | return 69 | } 70 | let offset = touch.location(in: window).y - movingStartY 71 | movingDidEnd(with: offset) 72 | } 73 | } 74 | 75 | private func movingDidEnd(with offset: CGFloat) { 76 | moving = false 77 | touchEventDelegate?.popup(self, touchDidEndWith: offset) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/UIResponder+STPopup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+MTPopup.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | let MTPopupFirstResponderDidChange = Notification.Name(rawValue: "MTPopupFirstResponderDidChange") 10 | 11 | extension UIResponder { 12 | 13 | static let _onceToken = UUID().uuidString 14 | 15 | open override class func initialize() { 16 | 17 | DispatchQueue.once(token: _onceToken) { 18 | swizzle(selector: #selector(becomeFirstResponder), to: #selector(st_becomeFirstResponder)) 19 | } 20 | } 21 | 22 | class func swizzle(selector: Selector, to swizzledSelector: Selector) { 23 | let originalMethod = class_getInstanceMethod(self, selector) 24 | let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) 25 | method_exchangeImplementations(originalMethod, swizzledMethod) 26 | } 27 | 28 | func st_becomeFirstResponder() -> Bool { 29 | let accepted = st_becomeFirstResponder() 30 | if accepted { 31 | NotificationCenter.default.post(name: MTPopupFirstResponderDidChange, object: self) 32 | } 33 | return accepted 34 | } 35 | } 36 | 37 | extension DispatchQueue { 38 | 39 | private static var _onceTracker = [String]() 40 | 41 | public class func once(token: String, block: () -> Void) { 42 | objc_sync_enter(self); defer { objc_sync_exit(self) } 43 | 44 | if _onceTracker.contains(token) { 45 | return 46 | } 47 | 48 | _onceTracker.append(token) 49 | block() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Classes/UIViewController+STPopup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MTPopup.swift 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | extension UIViewController { 10 | private struct AssociatedKeys { 11 | static var landscapeContentSizeInPopupKey: String? = "landscapeContentSizeInPopup" 12 | static var contentSizeInPopupKey: String? = "contentSizeInPopup" 13 | static var popupControllerKey: String? = "popupController" 14 | } 15 | 16 | static let controllerOnceToken = UUID().uuidString 17 | 18 | open override class func initialize() { 19 | DispatchQueue.once(token: controllerOnceToken) { 20 | let selectors: [Selector] = [ 21 | #selector(viewDidLoad), 22 | #selector(present), 23 | #selector(dismiss), 24 | #selector(getter: presentedViewController), 25 | #selector(getter: presentingViewController) 26 | ] 27 | selectors.forEach { 28 | swizzle($0, to: Selector("st_" + $0.description)) 29 | } 30 | } 31 | } 32 | 33 | class func swizzle(_ originalSelector: Selector, to swizzledSelector: Selector) { 34 | let originalMethod = class_getInstanceMethod(self, originalSelector) 35 | let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) 36 | method_exchangeImplementations(originalMethod, swizzledMethod) 37 | } 38 | 39 | func st_viewDidLoad() { 40 | var contentSize = CGSize.zero 41 | switch UIApplication.shared.statusBarOrientation { 42 | case .landscapeLeft, .landscapeRight: 43 | contentSize = landscapeContentSizeInPopup 44 | if contentSize == .zero { 45 | contentSize = contentSizeInPopup 46 | } 47 | default: 48 | contentSize = contentSizeInPopup 49 | } 50 | 51 | if contentSize != .zero { 52 | view.frame = CGRect(origin: .zero, size: contentSize) 53 | } 54 | st_viewDidLoad() 55 | } 56 | 57 | func st_presentViewController(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?) { 58 | guard let popupController = popupController else { 59 | st_presentViewController(viewControllerToPresent, animated: animated, completion: completion) 60 | return 61 | } 62 | 63 | let controller = popupController.value(forKey: "containerViewController") as? UIViewController 64 | controller?.present(viewControllerToPresent, animated: animated, completion: completion) 65 | } 66 | 67 | func st_dismissViewControllerAnimated(_ animated: Bool, completion: (() -> Void)?) { 68 | guard let popupController = popupController else { 69 | st_dismissViewControllerAnimated(animated, completion: completion) 70 | return 71 | } 72 | 73 | popupController.dismiss(with: completion) 74 | } 75 | 76 | var st_presentedViewController: UIViewController? { 77 | guard let popupController = popupController else { return self.st_presentedViewController } 78 | 79 | let controller = popupController.value(forKey: "containerViewController") as? UIViewController 80 | return controller?.presentedViewController 81 | } 82 | 83 | var st_presentingViewController: UIViewController? { 84 | guard let popupController = popupController else { return self.st_presentingViewController } 85 | let controller = popupController.value(forKey: "containerViewController") as? UIViewController 86 | return controller?.presentingViewController 87 | } 88 | 89 | static let screenW = UIScreen.main.bounds.width 90 | static let screenH = UIScreen.main.bounds.height 91 | 92 | public var contentSizeInPopup: CGSize { 93 | set { 94 | var value = newValue 95 | if value != .zero && value.width == 0 { 96 | switch UIApplication.shared.statusBarOrientation { 97 | case .landscapeLeft, .landscapeRight: 98 | value.width = UIViewController.screenH 99 | default: 100 | value.width = UIViewController.screenW 101 | } 102 | } 103 | 104 | objc_setAssociatedObject(self, &AssociatedKeys.contentSizeInPopupKey, NSValue(cgSize: value), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 105 | } 106 | 107 | get { 108 | return (objc_getAssociatedObject(self, &AssociatedKeys.contentSizeInPopupKey) as? CGSize) ?? .zero 109 | } 110 | } 111 | 112 | public var landscapeContentSizeInPopup: CGSize { 113 | set { 114 | var value = newValue 115 | if value != .zero && value.width == 0 { 116 | switch UIApplication.shared.statusBarOrientation { 117 | case .landscapeLeft, .landscapeRight: 118 | value.width = UIViewController.screenW 119 | default: 120 | value.width = UIViewController.screenH 121 | } 122 | } 123 | objc_setAssociatedObject(self, &AssociatedKeys.landscapeContentSizeInPopupKey, NSValue(cgSize: value), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 124 | } 125 | 126 | get { 127 | return (objc_getAssociatedObject(self, &AssociatedKeys.landscapeContentSizeInPopupKey) as? CGSize) ?? .zero 128 | } 129 | } 130 | 131 | public var popupController: MTPopupController? { 132 | set { 133 | guard let newValue = newValue else { return } 134 | objc_setAssociatedObject(self, &AssociatedKeys.popupControllerKey, newValue, .OBJC_ASSOCIATION_ASSIGN) 135 | } 136 | 137 | get { 138 | let popupController = objc_getAssociatedObject(self, &AssociatedKeys.popupControllerKey) as? MTPopupController 139 | guard let controller = popupController else { 140 | return parent?.popupController 141 | } 142 | return controller 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Cartfile: -------------------------------------------------------------------------------- 1 | 2 | github "huangboju/MTPopup" 3 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D88DC4F21E9A61B500F8FA1A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC4F11E9A61B500F8FA1A /* AppDelegate.swift */; }; 11 | D88DC4F41E9A61B500F8FA1A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC4F31E9A61B500F8FA1A /* ViewController.swift */; }; 12 | D88DC4F71E9A61B500F8FA1A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D88DC4F51E9A61B500F8FA1A /* Main.storyboard */; }; 13 | D88DC4F91E9A61B500F8FA1A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D88DC4F81E9A61B500F8FA1A /* Assets.xcassets */; }; 14 | D88DC4FC1E9A61B500F8FA1A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D88DC4FA1E9A61B500F8FA1A /* LaunchScreen.storyboard */; }; 15 | D88DC5071E9A61B500F8FA1A /* DemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5061E9A61B500F8FA1A /* DemoUITests.swift */; }; 16 | D88DC5151E9A622700F8FA1A /* BottomSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5121E9A622700F8FA1A /* BottomSheetController.swift */; }; 17 | D88DC5161E9A622700F8FA1A /* PopupViewController1.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5131E9A622700F8FA1A /* PopupViewController1.swift */; }; 18 | D88DC5171E9A622700F8FA1A /* PopupViewController2.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5141E9A622700F8FA1A /* PopupViewController2.swift */; }; 19 | D88DC5A31E9A69DE00F8FA1A /* MTPopup.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D88DC5A11E9A69D400F8FA1A /* MTPopup.framework */; }; 20 | D88DC5A41E9A69DE00F8FA1A /* MTPopup.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D88DC5A11E9A69D400F8FA1A /* MTPopup.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | D88DC5031E9A61B500F8FA1A /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = D88DC4E61E9A61B500F8FA1A /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = D88DC4ED1E9A61B500F8FA1A; 29 | remoteInfo = Demo; 30 | }; 31 | D88DC5AB1E9A6C0600F8FA1A /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */; 34 | proxyType = 2; 35 | remoteGlobalIDString = D88DC57D1E9A691900F8FA1A; 36 | remoteInfo = MTPopup; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXCopyFilesBuildPhase section */ 41 | D88DC5221E9A640800F8FA1A /* Embed Frameworks */ = { 42 | isa = PBXCopyFilesBuildPhase; 43 | buildActionMask = 2147483647; 44 | dstPath = ""; 45 | dstSubfolderSpec = 10; 46 | files = ( 47 | D88DC5A41E9A69DE00F8FA1A /* MTPopup.framework in Embed Frameworks */, 48 | ); 49 | name = "Embed Frameworks"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXCopyFilesBuildPhase section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | D88DC4EE1E9A61B500F8FA1A /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | D88DC4F11E9A61B500F8FA1A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 57 | D88DC4F31E9A61B500F8FA1A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 58 | D88DC4F61E9A61B500F8FA1A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 59 | D88DC4F81E9A61B500F8FA1A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 60 | D88DC4FB1E9A61B500F8FA1A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 61 | D88DC4FD1E9A61B500F8FA1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 62 | D88DC5021E9A61B500F8FA1A /* DemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | D88DC5061E9A61B500F8FA1A /* DemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoUITests.swift; sourceTree = ""; }; 64 | D88DC5081E9A61B500F8FA1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | D88DC5121E9A622700F8FA1A /* BottomSheetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomSheetController.swift; sourceTree = ""; }; 66 | D88DC5131E9A622700F8FA1A /* PopupViewController1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopupViewController1.swift; sourceTree = ""; }; 67 | D88DC5141E9A622700F8FA1A /* PopupViewController2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopupViewController2.swift; sourceTree = ""; }; 68 | D88DC5A11E9A69D400F8FA1A /* MTPopup.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MTPopup.framework; path = MTPopup/Carthage/Build/iOS/MTPopup.framework; sourceTree = ""; }; 69 | D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MTPopup.xcodeproj; path = MTPopup/MTPopup.xcodeproj; sourceTree = ""; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | D88DC4EB1E9A61B500F8FA1A /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | D88DC5A31E9A69DE00F8FA1A /* MTPopup.framework in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | D88DC4FF1E9A61B500F8FA1A /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | D88DC4E51E9A61B500F8FA1A = { 92 | isa = PBXGroup; 93 | children = ( 94 | D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */, 95 | D88DC4F01E9A61B500F8FA1A /* Demo */, 96 | D88DC5051E9A61B500F8FA1A /* DemoUITests */, 97 | D88DC4EF1E9A61B500F8FA1A /* Products */, 98 | D88DC5181E9A628D00F8FA1A /* Frameworks */, 99 | ); 100 | sourceTree = ""; 101 | }; 102 | D88DC4EF1E9A61B500F8FA1A /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | D88DC4EE1E9A61B500F8FA1A /* Demo.app */, 106 | D88DC5021E9A61B500F8FA1A /* DemoUITests.xctest */, 107 | ); 108 | name = Products; 109 | sourceTree = ""; 110 | }; 111 | D88DC4F01E9A61B500F8FA1A /* Demo */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | D88DC5111E9A622700F8FA1A /* TestControllers */, 115 | D88DC4F11E9A61B500F8FA1A /* AppDelegate.swift */, 116 | D88DC4F31E9A61B500F8FA1A /* ViewController.swift */, 117 | D88DC4F51E9A61B500F8FA1A /* Main.storyboard */, 118 | D88DC4F81E9A61B500F8FA1A /* Assets.xcassets */, 119 | D88DC4FA1E9A61B500F8FA1A /* LaunchScreen.storyboard */, 120 | D88DC4FD1E9A61B500F8FA1A /* Info.plist */, 121 | ); 122 | path = Demo; 123 | sourceTree = ""; 124 | }; 125 | D88DC5051E9A61B500F8FA1A /* DemoUITests */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | D88DC5061E9A61B500F8FA1A /* DemoUITests.swift */, 129 | D88DC5081E9A61B500F8FA1A /* Info.plist */, 130 | ); 131 | path = DemoUITests; 132 | sourceTree = ""; 133 | }; 134 | D88DC5111E9A622700F8FA1A /* TestControllers */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | D88DC5121E9A622700F8FA1A /* BottomSheetController.swift */, 138 | D88DC5131E9A622700F8FA1A /* PopupViewController1.swift */, 139 | D88DC5141E9A622700F8FA1A /* PopupViewController2.swift */, 140 | ); 141 | path = TestControllers; 142 | sourceTree = ""; 143 | }; 144 | D88DC5181E9A628D00F8FA1A /* Frameworks */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | D88DC5A11E9A69D400F8FA1A /* MTPopup.framework */, 148 | ); 149 | name = Frameworks; 150 | sourceTree = ""; 151 | }; 152 | D88DC5A81E9A6C0600F8FA1A /* Products */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | D88DC5AC1E9A6C0600F8FA1A /* MTPopup.framework */, 156 | ); 157 | name = Products; 158 | sourceTree = ""; 159 | }; 160 | /* End PBXGroup section */ 161 | 162 | /* Begin PBXNativeTarget section */ 163 | D88DC4ED1E9A61B500F8FA1A /* Demo */ = { 164 | isa = PBXNativeTarget; 165 | buildConfigurationList = D88DC50B1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "Demo" */; 166 | buildPhases = ( 167 | D88DC4EA1E9A61B500F8FA1A /* Sources */, 168 | D88DC4EB1E9A61B500F8FA1A /* Frameworks */, 169 | D88DC4EC1E9A61B500F8FA1A /* Resources */, 170 | D88DC5221E9A640800F8FA1A /* Embed Frameworks */, 171 | ); 172 | buildRules = ( 173 | ); 174 | dependencies = ( 175 | ); 176 | name = Demo; 177 | productName = Demo; 178 | productReference = D88DC4EE1E9A61B500F8FA1A /* Demo.app */; 179 | productType = "com.apple.product-type.application"; 180 | }; 181 | D88DC5011E9A61B500F8FA1A /* DemoUITests */ = { 182 | isa = PBXNativeTarget; 183 | buildConfigurationList = D88DC50E1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "DemoUITests" */; 184 | buildPhases = ( 185 | D88DC4FE1E9A61B500F8FA1A /* Sources */, 186 | D88DC4FF1E9A61B500F8FA1A /* Frameworks */, 187 | D88DC5001E9A61B500F8FA1A /* Resources */, 188 | ); 189 | buildRules = ( 190 | ); 191 | dependencies = ( 192 | D88DC5041E9A61B500F8FA1A /* PBXTargetDependency */, 193 | ); 194 | name = DemoUITests; 195 | productName = DemoUITests; 196 | productReference = D88DC5021E9A61B500F8FA1A /* DemoUITests.xctest */; 197 | productType = "com.apple.product-type.bundle.ui-testing"; 198 | }; 199 | /* End PBXNativeTarget section */ 200 | 201 | /* Begin PBXProject section */ 202 | D88DC4E61E9A61B500F8FA1A /* Project object */ = { 203 | isa = PBXProject; 204 | attributes = { 205 | LastSwiftUpdateCheck = 0820; 206 | LastUpgradeCheck = 0820; 207 | ORGANIZATIONNAME = "伯驹 黄"; 208 | TargetAttributes = { 209 | D88DC4ED1E9A61B500F8FA1A = { 210 | CreatedOnToolsVersion = 8.2.1; 211 | ProvisioningStyle = Automatic; 212 | }; 213 | D88DC5011E9A61B500F8FA1A = { 214 | CreatedOnToolsVersion = 8.2.1; 215 | ProvisioningStyle = Automatic; 216 | TestTargetID = D88DC4ED1E9A61B500F8FA1A; 217 | }; 218 | }; 219 | }; 220 | buildConfigurationList = D88DC4E91E9A61B500F8FA1A /* Build configuration list for PBXProject "Demo" */; 221 | compatibilityVersion = "Xcode 3.2"; 222 | developmentRegion = English; 223 | hasScannedForEncodings = 0; 224 | knownRegions = ( 225 | en, 226 | Base, 227 | ); 228 | mainGroup = D88DC4E51E9A61B500F8FA1A; 229 | productRefGroup = D88DC4EF1E9A61B500F8FA1A /* Products */; 230 | projectDirPath = ""; 231 | projectReferences = ( 232 | { 233 | ProductGroup = D88DC5A81E9A6C0600F8FA1A /* Products */; 234 | ProjectRef = D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */; 235 | }, 236 | ); 237 | projectRoot = ""; 238 | targets = ( 239 | D88DC4ED1E9A61B500F8FA1A /* Demo */, 240 | D88DC5011E9A61B500F8FA1A /* DemoUITests */, 241 | ); 242 | }; 243 | /* End PBXProject section */ 244 | 245 | /* Begin PBXReferenceProxy section */ 246 | D88DC5AC1E9A6C0600F8FA1A /* MTPopup.framework */ = { 247 | isa = PBXReferenceProxy; 248 | fileType = wrapper.framework; 249 | path = MTPopup.framework; 250 | remoteRef = D88DC5AB1E9A6C0600F8FA1A /* PBXContainerItemProxy */; 251 | sourceTree = BUILT_PRODUCTS_DIR; 252 | }; 253 | /* End PBXReferenceProxy section */ 254 | 255 | /* Begin PBXResourcesBuildPhase section */ 256 | D88DC4EC1E9A61B500F8FA1A /* Resources */ = { 257 | isa = PBXResourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | D88DC4FC1E9A61B500F8FA1A /* LaunchScreen.storyboard in Resources */, 261 | D88DC4F91E9A61B500F8FA1A /* Assets.xcassets in Resources */, 262 | D88DC4F71E9A61B500F8FA1A /* Main.storyboard in Resources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | D88DC5001E9A61B500F8FA1A /* Resources */ = { 267 | isa = PBXResourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | /* End PBXResourcesBuildPhase section */ 274 | 275 | /* Begin PBXSourcesBuildPhase section */ 276 | D88DC4EA1E9A61B500F8FA1A /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | D88DC5151E9A622700F8FA1A /* BottomSheetController.swift in Sources */, 281 | D88DC5161E9A622700F8FA1A /* PopupViewController1.swift in Sources */, 282 | D88DC4F41E9A61B500F8FA1A /* ViewController.swift in Sources */, 283 | D88DC5171E9A622700F8FA1A /* PopupViewController2.swift in Sources */, 284 | D88DC4F21E9A61B500F8FA1A /* AppDelegate.swift in Sources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | D88DC4FE1E9A61B500F8FA1A /* Sources */ = { 289 | isa = PBXSourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | D88DC5071E9A61B500F8FA1A /* DemoUITests.swift in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | /* End PBXSourcesBuildPhase section */ 297 | 298 | /* Begin PBXTargetDependency section */ 299 | D88DC5041E9A61B500F8FA1A /* PBXTargetDependency */ = { 300 | isa = PBXTargetDependency; 301 | target = D88DC4ED1E9A61B500F8FA1A /* Demo */; 302 | targetProxy = D88DC5031E9A61B500F8FA1A /* PBXContainerItemProxy */; 303 | }; 304 | /* End PBXTargetDependency section */ 305 | 306 | /* Begin PBXVariantGroup section */ 307 | D88DC4F51E9A61B500F8FA1A /* Main.storyboard */ = { 308 | isa = PBXVariantGroup; 309 | children = ( 310 | D88DC4F61E9A61B500F8FA1A /* Base */, 311 | ); 312 | name = Main.storyboard; 313 | sourceTree = ""; 314 | }; 315 | D88DC4FA1E9A61B500F8FA1A /* LaunchScreen.storyboard */ = { 316 | isa = PBXVariantGroup; 317 | children = ( 318 | D88DC4FB1E9A61B500F8FA1A /* Base */, 319 | ); 320 | name = LaunchScreen.storyboard; 321 | sourceTree = ""; 322 | }; 323 | /* End PBXVariantGroup section */ 324 | 325 | /* Begin XCBuildConfiguration section */ 326 | D88DC5091E9A61B500F8FA1A /* Debug */ = { 327 | isa = XCBuildConfiguration; 328 | buildSettings = { 329 | ALWAYS_SEARCH_USER_PATHS = NO; 330 | CLANG_ANALYZER_NONNULL = YES; 331 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 332 | CLANG_CXX_LIBRARY = "libc++"; 333 | CLANG_ENABLE_MODULES = YES; 334 | CLANG_ENABLE_OBJC_ARC = YES; 335 | CLANG_WARN_BOOL_CONVERSION = YES; 336 | CLANG_WARN_CONSTANT_CONVERSION = YES; 337 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 338 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 339 | CLANG_WARN_EMPTY_BODY = YES; 340 | CLANG_WARN_ENUM_CONVERSION = YES; 341 | CLANG_WARN_INFINITE_RECURSION = YES; 342 | CLANG_WARN_INT_CONVERSION = YES; 343 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 344 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 345 | CLANG_WARN_UNREACHABLE_CODE = YES; 346 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 347 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 348 | COPY_PHASE_STRIP = NO; 349 | DEBUG_INFORMATION_FORMAT = dwarf; 350 | ENABLE_STRICT_OBJC_MSGSEND = YES; 351 | ENABLE_TESTABILITY = YES; 352 | GCC_C_LANGUAGE_STANDARD = gnu99; 353 | GCC_DYNAMIC_NO_PIC = NO; 354 | GCC_NO_COMMON_BLOCKS = YES; 355 | GCC_OPTIMIZATION_LEVEL = 0; 356 | GCC_PREPROCESSOR_DEFINITIONS = ( 357 | "DEBUG=1", 358 | "$(inherited)", 359 | ); 360 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 361 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 362 | GCC_WARN_UNDECLARED_SELECTOR = YES; 363 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 364 | GCC_WARN_UNUSED_FUNCTION = YES; 365 | GCC_WARN_UNUSED_VARIABLE = YES; 366 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 367 | MTL_ENABLE_DEBUG_INFO = YES; 368 | ONLY_ACTIVE_ARCH = YES; 369 | SDKROOT = iphoneos; 370 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 371 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 372 | }; 373 | name = Debug; 374 | }; 375 | D88DC50A1E9A61B500F8FA1A /* Release */ = { 376 | isa = XCBuildConfiguration; 377 | buildSettings = { 378 | ALWAYS_SEARCH_USER_PATHS = NO; 379 | CLANG_ANALYZER_NONNULL = YES; 380 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 381 | CLANG_CXX_LIBRARY = "libc++"; 382 | CLANG_ENABLE_MODULES = YES; 383 | CLANG_ENABLE_OBJC_ARC = YES; 384 | CLANG_WARN_BOOL_CONVERSION = YES; 385 | CLANG_WARN_CONSTANT_CONVERSION = YES; 386 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 387 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 388 | CLANG_WARN_EMPTY_BODY = YES; 389 | CLANG_WARN_ENUM_CONVERSION = YES; 390 | CLANG_WARN_INFINITE_RECURSION = YES; 391 | CLANG_WARN_INT_CONVERSION = YES; 392 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 393 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 394 | CLANG_WARN_UNREACHABLE_CODE = YES; 395 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 396 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 397 | COPY_PHASE_STRIP = NO; 398 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 399 | ENABLE_NS_ASSERTIONS = NO; 400 | ENABLE_STRICT_OBJC_MSGSEND = YES; 401 | GCC_C_LANGUAGE_STANDARD = gnu99; 402 | GCC_NO_COMMON_BLOCKS = YES; 403 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 404 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 405 | GCC_WARN_UNDECLARED_SELECTOR = YES; 406 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 407 | GCC_WARN_UNUSED_FUNCTION = YES; 408 | GCC_WARN_UNUSED_VARIABLE = YES; 409 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 410 | MTL_ENABLE_DEBUG_INFO = NO; 411 | SDKROOT = iphoneos; 412 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 413 | VALIDATE_PRODUCT = YES; 414 | }; 415 | name = Release; 416 | }; 417 | D88DC50C1E9A61B500F8FA1A /* Debug */ = { 418 | isa = XCBuildConfiguration; 419 | buildSettings = { 420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 421 | FRAMEWORK_SEARCH_PATHS = ( 422 | "$(inherited)", 423 | "$(PROJECT_DIR)/MTPopup/Carthage/Build/iOS", 424 | ); 425 | INFOPLIST_FILE = Demo/Info.plist; 426 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 427 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 428 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.Demo; 429 | PRODUCT_NAME = "$(TARGET_NAME)"; 430 | SWIFT_VERSION = 3.0; 431 | }; 432 | name = Debug; 433 | }; 434 | D88DC50D1E9A61B500F8FA1A /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 438 | FRAMEWORK_SEARCH_PATHS = ( 439 | "$(inherited)", 440 | "$(PROJECT_DIR)/MTPopup/Carthage/Build/iOS", 441 | ); 442 | INFOPLIST_FILE = Demo/Info.plist; 443 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 444 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 445 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.Demo; 446 | PRODUCT_NAME = "$(TARGET_NAME)"; 447 | SWIFT_VERSION = 3.0; 448 | }; 449 | name = Release; 450 | }; 451 | D88DC50F1E9A61B500F8FA1A /* Debug */ = { 452 | isa = XCBuildConfiguration; 453 | buildSettings = { 454 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 455 | INFOPLIST_FILE = DemoUITests/Info.plist; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 457 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.DemoUITests; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | SWIFT_VERSION = 3.0; 460 | TEST_TARGET_NAME = Demo; 461 | }; 462 | name = Debug; 463 | }; 464 | D88DC5101E9A61B500F8FA1A /* Release */ = { 465 | isa = XCBuildConfiguration; 466 | buildSettings = { 467 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 468 | INFOPLIST_FILE = DemoUITests/Info.plist; 469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 470 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.DemoUITests; 471 | PRODUCT_NAME = "$(TARGET_NAME)"; 472 | SWIFT_VERSION = 3.0; 473 | TEST_TARGET_NAME = Demo; 474 | }; 475 | name = Release; 476 | }; 477 | /* End XCBuildConfiguration section */ 478 | 479 | /* Begin XCConfigurationList section */ 480 | D88DC4E91E9A61B500F8FA1A /* Build configuration list for PBXProject "Demo" */ = { 481 | isa = XCConfigurationList; 482 | buildConfigurations = ( 483 | D88DC5091E9A61B500F8FA1A /* Debug */, 484 | D88DC50A1E9A61B500F8FA1A /* Release */, 485 | ); 486 | defaultConfigurationIsVisible = 0; 487 | defaultConfigurationName = Release; 488 | }; 489 | D88DC50B1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "Demo" */ = { 490 | isa = XCConfigurationList; 491 | buildConfigurations = ( 492 | D88DC50C1E9A61B500F8FA1A /* Debug */, 493 | D88DC50D1E9A61B500F8FA1A /* Release */, 494 | ); 495 | defaultConfigurationIsVisible = 0; 496 | defaultConfigurationName = Release; 497 | }; 498 | D88DC50E1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "DemoUITests" */ = { 499 | isa = XCConfigurationList; 500 | buildConfigurations = ( 501 | D88DC50F1E9A61B500F8FA1A /* Debug */, 502 | D88DC5101E9A61B500F8FA1A /* Release */, 503 | ); 504 | defaultConfigurationIsVisible = 0; 505 | defaultConfigurationName = Release; 506 | }; 507 | /* End XCConfigurationList section */ 508 | }; 509 | rootObject = D88DC4E61E9A61B500F8FA1A /* Project object */; 510 | } 511 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by 伯驹 黄 on 2017/4/9. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeRight 35 | UIInterfaceOrientationLandscapeLeft 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/TestControllers/BottomSheetController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BottomSheetController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/12/10. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class BottomSheetController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | contentSizeInPopup = CGSize(width: view.frame.width, height: 300) 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/TestControllers/PopupViewController1.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/14. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | let scaleW = UIScreen.main.bounds.width / 320 12 | let scaleH = UIScreen.main.bounds.height / 568 13 | 14 | class PopupViewController1: UIViewController { 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | title = "Apple" 20 | 21 | contentSizeInPopup = CGSize(width: 280 * scaleW, height: 380 * scaleH) 22 | landscapeContentSizeInPopup = CGSize(width: 400 * scaleH, height: 200 * scaleW) 23 | 24 | view.backgroundColor = UIColor.groupTableViewBackground 25 | 26 | let textLabel = UILabel(frame: CGRect(x: 15, y: 0, width: contentSizeInPopup.width - 30, height: 380)) 27 | textLabel.numberOfLines = 0 28 | textLabel.text = "Apple Inc. (commonly known as Apple) is an American multinational technology company headquartered in Cupertino, California, that designs, develops, and sells consumer electronics, computer software, and online services. Its best-known hardware products are the Mac personal computers, the iPod portable media player, the iPhone smartphone, the iPad tablet computer, and the Apple Watch smartwatch. Apple's consumer software includes the OS X and iOS operating systems, the iTunes media player, the Safari web browser, and the iLife and iWork creativity and productivity suites. Its online services include the iTunes Store, the iOS App Store and Mac App Store, and iCloud." 29 | view.addSubview(textLabel) 30 | 31 | navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(nextAction)) 32 | } 33 | 34 | func nextAction() { 35 | popupController?.push(PopupViewController2(), animated: true) 36 | } 37 | 38 | override func didReceiveMemoryWarning() { 39 | super.didReceiveMemoryWarning() 40 | // Dispose of any resources that can be recreated. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/TestControllers/PopupViewController2.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/12/5. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PopupViewController2: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | contentSizeInPopup = CGSize(width: 300 * scaleW, height: 200 * scaleH) 17 | landscapeContentSizeInPopup = CGSize(width: 400 * scaleH, height: 200 * scaleW) 18 | } 19 | 20 | override func didReceiveMemoryWarning() { 21 | super.didReceiveMemoryWarning() 22 | // Dispose of any resources that can be recreated. 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MTPopup 11 | 12 | class ViewController: UIViewController { 13 | 14 | fileprivate lazy var tableView: UITableView = { 15 | let tableView = UITableView(frame: self.view.bounds, style: .grouped) 16 | tableView.dataSource = self 17 | tableView.delegate = self 18 | return tableView 19 | }() 20 | 21 | lazy var controllers: [UIViewController.Type] = [ 22 | PopupViewController1.self, 23 | PopupViewController1.self, 24 | BottomSheetController.self 25 | ] 26 | 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | title = "MTPopupController" 30 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") 31 | view.addSubview(tableView) 32 | } 33 | 34 | override func didReceiveMemoryWarning() { 35 | super.didReceiveMemoryWarning() 36 | // Dispose of any resources that can be recreated. 37 | } 38 | } 39 | 40 | extension ViewController: UITableViewDataSource { 41 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 42 | return controllers.count 43 | } 44 | 45 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 46 | return tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 47 | } 48 | } 49 | 50 | extension ViewController: UITableViewDelegate { 51 | 52 | func tableView(_: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 53 | cell.textLabel?.text = "\(controllers[indexPath.row].classForCoder())" 54 | } 55 | 56 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 57 | tableView.deselectRow(at: indexPath, animated: false) 58 | 59 | let popupController = MTPopupController(rootViewController: controllers[indexPath.row].init()) 60 | 61 | if indexPath == IndexPath(row: 1, section: 0) { 62 | let blurEffect = UIBlurEffect(style: .dark) 63 | popupController.backgroundView = UIVisualEffectView(effect: blurEffect) 64 | popupController.backgroundView?.alpha = 0.8 65 | } else if indexPath == IndexPath(row: 2, section: 0) { 66 | popupController.style = .bottomSheet 67 | } 68 | popupController.present(in: self) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/DemoUITests/DemoUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoUITests.swift 3 | // DemoUITests 4 | // 5 | // Created by 伯驹 黄 on 2017/4/9. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class DemoUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // 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. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/DemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/MTPopup/MTPopup.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D88DC5821E9A691900F8FA1A /* MTPopup.h in Headers */ = {isa = PBXBuildFile; fileRef = D88DC5801E9A691900F8FA1A /* MTPopup.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | D88DC5951E9A695B00F8FA1A /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5891E9A695B00F8FA1A /* Array+Extensions.swift */; }; 12 | D88DC5961E9A695B00F8FA1A /* Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = D88DC58A1E9A695B00F8FA1A /* Bridging.h */; }; 13 | D88DC5971E9A695B00F8FA1A /* MTPopupContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58B1E9A695B00F8FA1A /* MTPopupContainerViewController.swift */; }; 14 | D88DC5981E9A695B00F8FA1A /* MTPopupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58C1E9A695B00F8FA1A /* MTPopupController.swift */; }; 15 | D88DC5991E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58D1E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift */; }; 16 | D88DC59A1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58E1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift */; }; 17 | D88DC59B1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58F1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift */; }; 18 | D88DC59C1E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5901E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift */; }; 19 | D88DC59D1E9A695B00F8FA1A /* MTPopupLeftBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5911E9A695B00F8FA1A /* MTPopupLeftBarItem.swift */; }; 20 | D88DC59E1E9A695B00F8FA1A /* MTPopupNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5921E9A695B00F8FA1A /* MTPopupNavigationBar.swift */; }; 21 | D88DC59F1E9A695B00F8FA1A /* UIResponder+STPopup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5931E9A695B00F8FA1A /* UIResponder+STPopup.swift */; }; 22 | D88DC5A01E9A695B00F8FA1A /* UIViewController+STPopup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5941E9A695B00F8FA1A /* UIViewController+STPopup.swift */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | D88DC57D1E9A691900F8FA1A /* MTPopup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MTPopup.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | D88DC5801E9A691900F8FA1A /* MTPopup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTPopup.h; sourceTree = ""; }; 28 | D88DC5811E9A691900F8FA1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | D88DC5891E9A695B00F8FA1A /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Extensions.swift"; sourceTree = ""; }; 30 | D88DC58A1E9A695B00F8FA1A /* Bridging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridging.h; sourceTree = ""; }; 31 | D88DC58B1E9A695B00F8FA1A /* MTPopupContainerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupContainerViewController.swift; sourceTree = ""; }; 32 | D88DC58C1E9A695B00F8FA1A /* MTPopupController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupController.swift; sourceTree = ""; }; 33 | D88DC58D1E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioning.swift; sourceTree = ""; }; 34 | D88DC58E1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioningContext.swift; sourceTree = ""; }; 35 | D88DC58F1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioningFade.swift; sourceTree = ""; }; 36 | D88DC5901E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioningSlideVertical.swift; sourceTree = ""; }; 37 | D88DC5911E9A695B00F8FA1A /* MTPopupLeftBarItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupLeftBarItem.swift; sourceTree = ""; }; 38 | D88DC5921E9A695B00F8FA1A /* MTPopupNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupNavigationBar.swift; sourceTree = ""; }; 39 | D88DC5931E9A695B00F8FA1A /* UIResponder+STPopup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+STPopup.swift"; sourceTree = ""; }; 40 | D88DC5941E9A695B00F8FA1A /* UIViewController+STPopup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+STPopup.swift"; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | D88DC5791E9A691900F8FA1A /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | /* End PBXFrameworksBuildPhase section */ 52 | 53 | /* Begin PBXGroup section */ 54 | D88DC5731E9A691900F8FA1A = { 55 | isa = PBXGroup; 56 | children = ( 57 | D88DC57F1E9A691900F8FA1A /* MTPopup */, 58 | D88DC57E1E9A691900F8FA1A /* Products */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | D88DC57E1E9A691900F8FA1A /* Products */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | D88DC57D1E9A691900F8FA1A /* MTPopup.framework */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | D88DC57F1E9A691900F8FA1A /* MTPopup */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | D88DC5881E9A695B00F8FA1A /* Classes */, 74 | D88DC5801E9A691900F8FA1A /* MTPopup.h */, 75 | D88DC5811E9A691900F8FA1A /* Info.plist */, 76 | ); 77 | path = MTPopup; 78 | sourceTree = ""; 79 | }; 80 | D88DC5881E9A695B00F8FA1A /* Classes */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | D88DC5891E9A695B00F8FA1A /* Array+Extensions.swift */, 84 | D88DC58A1E9A695B00F8FA1A /* Bridging.h */, 85 | D88DC58B1E9A695B00F8FA1A /* MTPopupContainerViewController.swift */, 86 | D88DC58C1E9A695B00F8FA1A /* MTPopupController.swift */, 87 | D88DC58D1E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift */, 88 | D88DC58E1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift */, 89 | D88DC58F1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift */, 90 | D88DC5901E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift */, 91 | D88DC5911E9A695B00F8FA1A /* MTPopupLeftBarItem.swift */, 92 | D88DC5921E9A695B00F8FA1A /* MTPopupNavigationBar.swift */, 93 | D88DC5931E9A695B00F8FA1A /* UIResponder+STPopup.swift */, 94 | D88DC5941E9A695B00F8FA1A /* UIViewController+STPopup.swift */, 95 | ); 96 | name = Classes; 97 | path = ../../../Classes; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXHeadersBuildPhase section */ 103 | D88DC57A1E9A691900F8FA1A /* Headers */ = { 104 | isa = PBXHeadersBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | D88DC5961E9A695B00F8FA1A /* Bridging.h in Headers */, 108 | D88DC5821E9A691900F8FA1A /* MTPopup.h in Headers */, 109 | ); 110 | runOnlyForDeploymentPostprocessing = 0; 111 | }; 112 | /* End PBXHeadersBuildPhase section */ 113 | 114 | /* Begin PBXNativeTarget section */ 115 | D88DC57C1E9A691900F8FA1A /* MTPopup */ = { 116 | isa = PBXNativeTarget; 117 | buildConfigurationList = D88DC5851E9A691900F8FA1A /* Build configuration list for PBXNativeTarget "MTPopup" */; 118 | buildPhases = ( 119 | D88DC5781E9A691900F8FA1A /* Sources */, 120 | D88DC5791E9A691900F8FA1A /* Frameworks */, 121 | D88DC57A1E9A691900F8FA1A /* Headers */, 122 | D88DC57B1E9A691900F8FA1A /* Resources */, 123 | ); 124 | buildRules = ( 125 | ); 126 | dependencies = ( 127 | ); 128 | name = MTPopup; 129 | productName = MTPopup; 130 | productReference = D88DC57D1E9A691900F8FA1A /* MTPopup.framework */; 131 | productType = "com.apple.product-type.framework"; 132 | }; 133 | /* End PBXNativeTarget section */ 134 | 135 | /* Begin PBXProject section */ 136 | D88DC5741E9A691900F8FA1A /* Project object */ = { 137 | isa = PBXProject; 138 | attributes = { 139 | LastUpgradeCheck = 0820; 140 | ORGANIZATIONNAME = "伯驹 黄"; 141 | TargetAttributes = { 142 | D88DC57C1E9A691900F8FA1A = { 143 | CreatedOnToolsVersion = 8.2.1; 144 | ProvisioningStyle = Automatic; 145 | }; 146 | }; 147 | }; 148 | buildConfigurationList = D88DC5771E9A691900F8FA1A /* Build configuration list for PBXProject "MTPopup" */; 149 | compatibilityVersion = "Xcode 3.2"; 150 | developmentRegion = English; 151 | hasScannedForEncodings = 0; 152 | knownRegions = ( 153 | en, 154 | ); 155 | mainGroup = D88DC5731E9A691900F8FA1A; 156 | productRefGroup = D88DC57E1E9A691900F8FA1A /* Products */; 157 | projectDirPath = ""; 158 | projectRoot = ""; 159 | targets = ( 160 | D88DC57C1E9A691900F8FA1A /* MTPopup */, 161 | ); 162 | }; 163 | /* End PBXProject section */ 164 | 165 | /* Begin PBXResourcesBuildPhase section */ 166 | D88DC57B1E9A691900F8FA1A /* Resources */ = { 167 | isa = PBXResourcesBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | ); 171 | runOnlyForDeploymentPostprocessing = 0; 172 | }; 173 | /* End PBXResourcesBuildPhase section */ 174 | 175 | /* Begin PBXSourcesBuildPhase section */ 176 | D88DC5781E9A691900F8FA1A /* Sources */ = { 177 | isa = PBXSourcesBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | D88DC59F1E9A695B00F8FA1A /* UIResponder+STPopup.swift in Sources */, 181 | D88DC5981E9A695B00F8FA1A /* MTPopupController.swift in Sources */, 182 | D88DC59C1E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift in Sources */, 183 | D88DC59E1E9A695B00F8FA1A /* MTPopupNavigationBar.swift in Sources */, 184 | D88DC5991E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift in Sources */, 185 | D88DC5971E9A695B00F8FA1A /* MTPopupContainerViewController.swift in Sources */, 186 | D88DC59A1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift in Sources */, 187 | D88DC5951E9A695B00F8FA1A /* Array+Extensions.swift in Sources */, 188 | D88DC59B1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift in Sources */, 189 | D88DC5A01E9A695B00F8FA1A /* UIViewController+STPopup.swift in Sources */, 190 | D88DC59D1E9A695B00F8FA1A /* MTPopupLeftBarItem.swift in Sources */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | /* End PBXSourcesBuildPhase section */ 195 | 196 | /* Begin XCBuildConfiguration section */ 197 | D88DC5831E9A691900F8FA1A /* Debug */ = { 198 | isa = XCBuildConfiguration; 199 | buildSettings = { 200 | ALWAYS_SEARCH_USER_PATHS = NO; 201 | CLANG_ANALYZER_NONNULL = YES; 202 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 203 | CLANG_CXX_LIBRARY = "libc++"; 204 | CLANG_ENABLE_MODULES = YES; 205 | CLANG_ENABLE_OBJC_ARC = YES; 206 | CLANG_WARN_BOOL_CONVERSION = YES; 207 | CLANG_WARN_CONSTANT_CONVERSION = YES; 208 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 209 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 210 | CLANG_WARN_EMPTY_BODY = YES; 211 | CLANG_WARN_ENUM_CONVERSION = YES; 212 | CLANG_WARN_INFINITE_RECURSION = YES; 213 | CLANG_WARN_INT_CONVERSION = YES; 214 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 215 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 216 | CLANG_WARN_UNREACHABLE_CODE = YES; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 219 | COPY_PHASE_STRIP = NO; 220 | CURRENT_PROJECT_VERSION = 1; 221 | DEBUG_INFORMATION_FORMAT = dwarf; 222 | ENABLE_STRICT_OBJC_MSGSEND = YES; 223 | ENABLE_TESTABILITY = YES; 224 | GCC_C_LANGUAGE_STANDARD = gnu99; 225 | GCC_DYNAMIC_NO_PIC = NO; 226 | GCC_NO_COMMON_BLOCKS = YES; 227 | GCC_OPTIMIZATION_LEVEL = 0; 228 | GCC_PREPROCESSOR_DEFINITIONS = ( 229 | "DEBUG=1", 230 | "$(inherited)", 231 | ); 232 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 233 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 234 | GCC_WARN_UNDECLARED_SELECTOR = YES; 235 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 236 | GCC_WARN_UNUSED_FUNCTION = YES; 237 | GCC_WARN_UNUSED_VARIABLE = YES; 238 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 239 | MTL_ENABLE_DEBUG_INFO = YES; 240 | ONLY_ACTIVE_ARCH = YES; 241 | SDKROOT = iphoneos; 242 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 243 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 244 | TARGETED_DEVICE_FAMILY = "1,2"; 245 | VERSIONING_SYSTEM = "apple-generic"; 246 | VERSION_INFO_PREFIX = ""; 247 | }; 248 | name = Debug; 249 | }; 250 | D88DC5841E9A691900F8FA1A /* Release */ = { 251 | isa = XCBuildConfiguration; 252 | buildSettings = { 253 | ALWAYS_SEARCH_USER_PATHS = NO; 254 | CLANG_ANALYZER_NONNULL = YES; 255 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 256 | CLANG_CXX_LIBRARY = "libc++"; 257 | CLANG_ENABLE_MODULES = YES; 258 | CLANG_ENABLE_OBJC_ARC = YES; 259 | CLANG_WARN_BOOL_CONVERSION = YES; 260 | CLANG_WARN_CONSTANT_CONVERSION = YES; 261 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 262 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 263 | CLANG_WARN_EMPTY_BODY = YES; 264 | CLANG_WARN_ENUM_CONVERSION = YES; 265 | CLANG_WARN_INFINITE_RECURSION = YES; 266 | CLANG_WARN_INT_CONVERSION = YES; 267 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 268 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 269 | CLANG_WARN_UNREACHABLE_CODE = YES; 270 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 271 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 272 | COPY_PHASE_STRIP = NO; 273 | CURRENT_PROJECT_VERSION = 1; 274 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 275 | ENABLE_NS_ASSERTIONS = NO; 276 | ENABLE_STRICT_OBJC_MSGSEND = YES; 277 | GCC_C_LANGUAGE_STANDARD = gnu99; 278 | GCC_NO_COMMON_BLOCKS = YES; 279 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 280 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 281 | GCC_WARN_UNDECLARED_SELECTOR = YES; 282 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 283 | GCC_WARN_UNUSED_FUNCTION = YES; 284 | GCC_WARN_UNUSED_VARIABLE = YES; 285 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 286 | MTL_ENABLE_DEBUG_INFO = NO; 287 | SDKROOT = iphoneos; 288 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 289 | TARGETED_DEVICE_FAMILY = "1,2"; 290 | VALIDATE_PRODUCT = YES; 291 | VERSIONING_SYSTEM = "apple-generic"; 292 | VERSION_INFO_PREFIX = ""; 293 | }; 294 | name = Release; 295 | }; 296 | D88DC5861E9A691900F8FA1A /* Debug */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | CODE_SIGN_IDENTITY = ""; 300 | DEFINES_MODULE = YES; 301 | DYLIB_COMPATIBILITY_VERSION = 1; 302 | DYLIB_CURRENT_VERSION = 1; 303 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 304 | INFOPLIST_FILE = MTPopup/Info.plist; 305 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 306 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 307 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 308 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.MTPopup; 309 | PRODUCT_NAME = "$(TARGET_NAME)"; 310 | SKIP_INSTALL = YES; 311 | SWIFT_VERSION = 3.0; 312 | TARGETED_DEVICE_FAMILY = 1; 313 | }; 314 | name = Debug; 315 | }; 316 | D88DC5871E9A691900F8FA1A /* Release */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | CODE_SIGN_IDENTITY = ""; 320 | DEFINES_MODULE = YES; 321 | DYLIB_COMPATIBILITY_VERSION = 1; 322 | DYLIB_CURRENT_VERSION = 1; 323 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 324 | INFOPLIST_FILE = MTPopup/Info.plist; 325 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 326 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 327 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 328 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.MTPopup; 329 | PRODUCT_NAME = "$(TARGET_NAME)"; 330 | SKIP_INSTALL = YES; 331 | SWIFT_VERSION = 3.0; 332 | TARGETED_DEVICE_FAMILY = 1; 333 | }; 334 | name = Release; 335 | }; 336 | /* End XCBuildConfiguration section */ 337 | 338 | /* Begin XCConfigurationList section */ 339 | D88DC5771E9A691900F8FA1A /* Build configuration list for PBXProject "MTPopup" */ = { 340 | isa = XCConfigurationList; 341 | buildConfigurations = ( 342 | D88DC5831E9A691900F8FA1A /* Debug */, 343 | D88DC5841E9A691900F8FA1A /* Release */, 344 | ); 345 | defaultConfigurationIsVisible = 0; 346 | defaultConfigurationName = Release; 347 | }; 348 | D88DC5851E9A691900F8FA1A /* Build configuration list for PBXNativeTarget "MTPopup" */ = { 349 | isa = XCConfigurationList; 350 | buildConfigurations = ( 351 | D88DC5861E9A691900F8FA1A /* Debug */, 352 | D88DC5871E9A691900F8FA1A /* Release */, 353 | ); 354 | defaultConfigurationIsVisible = 0; 355 | }; 356 | /* End XCConfigurationList section */ 357 | }; 358 | rootObject = D88DC5741E9A691900F8FA1A /* Project object */; 359 | } 360 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/MTPopup/MTPopup.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/MTPopup/MTPopup.xcodeproj/xcshareddata/xcschemes/MTPopup.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/MTPopup/MTPopup.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/MTPopup/MTPopup/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/Demo/MTPopup/MTPopup/MTPopup.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopup.h 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2017/4/9. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MTPopup. 12 | FOUNDATION_EXPORT double MTPopupVersionNumber; 13 | 14 | //! Project version string for MTPopup. 15 | FOUNDATION_EXPORT const unsigned char MTPopupVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 xiAo-Ju 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/MTPopup.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = "MTPopup" 5 | s.version = "1.0.2" 6 | s.summary = "You will like it" 7 | s.homepage = "https://github.com/huangboju/MTPopup" 8 | s.license = "MIT" 9 | s.author = { "huangboju" => "529940945@qq.com" } 10 | s.platform = :ios,'8.0' 11 | s.source = { :git => "https://github.com/huangboju/MTPopup.git", :tag => "#{s.version}" } 12 | s.source_files = "Classes/**/*.swift" 13 | s.framework = "UIKit" 14 | s.requires_arc = true 15 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' } 16 | end 17 | -------------------------------------------------------------------------------- /Demo/Carthage/Checkouts/MTPopup/README.md: -------------------------------------------------------------------------------- 1 | # MTPopup 2 | 3 | # Overview 4 | 5 | ![](https://github.com/huangboju/SwiftySTPopup/blob/master/2017-03-21%2020_24_31.gif) 6 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | BEB635191FA6FEC700525EBB /* MTPopup.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D88DC5AC1E9A6C0600F8FA1A /* MTPopup.framework */; }; 11 | BEB6351A1FA6FEC700525EBB /* MTPopup.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D88DC5AC1E9A6C0600F8FA1A /* MTPopup.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 12 | D88DC4F21E9A61B500F8FA1A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC4F11E9A61B500F8FA1A /* AppDelegate.swift */; }; 13 | D88DC4F41E9A61B500F8FA1A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC4F31E9A61B500F8FA1A /* ViewController.swift */; }; 14 | D88DC4F71E9A61B500F8FA1A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D88DC4F51E9A61B500F8FA1A /* Main.storyboard */; }; 15 | D88DC4F91E9A61B500F8FA1A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D88DC4F81E9A61B500F8FA1A /* Assets.xcassets */; }; 16 | D88DC4FC1E9A61B500F8FA1A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D88DC4FA1E9A61B500F8FA1A /* LaunchScreen.storyboard */; }; 17 | D88DC5071E9A61B500F8FA1A /* DemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5061E9A61B500F8FA1A /* DemoUITests.swift */; }; 18 | D88DC5151E9A622700F8FA1A /* BottomSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5121E9A622700F8FA1A /* BottomSheetController.swift */; }; 19 | D88DC5161E9A622700F8FA1A /* PopupViewController1.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5131E9A622700F8FA1A /* PopupViewController1.swift */; }; 20 | D88DC5171E9A622700F8FA1A /* PopupViewController2.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5141E9A622700F8FA1A /* PopupViewController2.swift */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | BEB6351B1FA6FEC700525EBB /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */; 27 | proxyType = 1; 28 | remoteGlobalIDString = D88DC57C1E9A691900F8FA1A; 29 | remoteInfo = MTPopup; 30 | }; 31 | D88DC5031E9A61B500F8FA1A /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = D88DC4E61E9A61B500F8FA1A /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = D88DC4ED1E9A61B500F8FA1A; 36 | remoteInfo = Demo; 37 | }; 38 | D88DC5AB1E9A6C0600F8FA1A /* PBXContainerItemProxy */ = { 39 | isa = PBXContainerItemProxy; 40 | containerPortal = D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */; 41 | proxyType = 2; 42 | remoteGlobalIDString = D88DC57D1E9A691900F8FA1A; 43 | remoteInfo = MTPopup; 44 | }; 45 | /* End PBXContainerItemProxy section */ 46 | 47 | /* Begin PBXCopyFilesBuildPhase section */ 48 | BEB6351D1FA6FEC700525EBB /* Embed Frameworks */ = { 49 | isa = PBXCopyFilesBuildPhase; 50 | buildActionMask = 2147483647; 51 | dstPath = ""; 52 | dstSubfolderSpec = 10; 53 | files = ( 54 | BEB6351A1FA6FEC700525EBB /* MTPopup.framework in Embed Frameworks */, 55 | ); 56 | name = "Embed Frameworks"; 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | /* End PBXCopyFilesBuildPhase section */ 60 | 61 | /* Begin PBXFileReference section */ 62 | D88DC4EE1E9A61B500F8FA1A /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | D88DC4F11E9A61B500F8FA1A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 64 | D88DC4F31E9A61B500F8FA1A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 65 | D88DC4F61E9A61B500F8FA1A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 66 | D88DC4F81E9A61B500F8FA1A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 67 | D88DC4FB1E9A61B500F8FA1A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 68 | D88DC4FD1E9A61B500F8FA1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | D88DC5021E9A61B500F8FA1A /* DemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 70 | D88DC5061E9A61B500F8FA1A /* DemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoUITests.swift; sourceTree = ""; }; 71 | D88DC5081E9A61B500F8FA1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 72 | D88DC5121E9A622700F8FA1A /* BottomSheetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomSheetController.swift; sourceTree = ""; }; 73 | D88DC5131E9A622700F8FA1A /* PopupViewController1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopupViewController1.swift; sourceTree = ""; }; 74 | D88DC5141E9A622700F8FA1A /* PopupViewController2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopupViewController2.swift; sourceTree = ""; }; 75 | D88DC5A11E9A69D400F8FA1A /* MTPopup.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MTPopup.framework; path = MTPopup/Carthage/Build/iOS/MTPopup.framework; sourceTree = ""; }; 76 | D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MTPopup.xcodeproj; path = MTPopup/MTPopup.xcodeproj; sourceTree = ""; }; 77 | /* End PBXFileReference section */ 78 | 79 | /* Begin PBXFrameworksBuildPhase section */ 80 | D88DC4EB1E9A61B500F8FA1A /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | BEB635191FA6FEC700525EBB /* MTPopup.framework in Frameworks */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | D88DC4FF1E9A61B500F8FA1A /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | D88DC4E51E9A61B500F8FA1A = { 99 | isa = PBXGroup; 100 | children = ( 101 | D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */, 102 | D88DC4F01E9A61B500F8FA1A /* Demo */, 103 | D88DC5051E9A61B500F8FA1A /* DemoUITests */, 104 | D88DC4EF1E9A61B500F8FA1A /* Products */, 105 | D88DC5181E9A628D00F8FA1A /* Frameworks */, 106 | ); 107 | sourceTree = ""; 108 | }; 109 | D88DC4EF1E9A61B500F8FA1A /* Products */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | D88DC4EE1E9A61B500F8FA1A /* Demo.app */, 113 | D88DC5021E9A61B500F8FA1A /* DemoUITests.xctest */, 114 | ); 115 | name = Products; 116 | sourceTree = ""; 117 | }; 118 | D88DC4F01E9A61B500F8FA1A /* Demo */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | D88DC5111E9A622700F8FA1A /* TestControllers */, 122 | D88DC4F11E9A61B500F8FA1A /* AppDelegate.swift */, 123 | D88DC4F31E9A61B500F8FA1A /* ViewController.swift */, 124 | D88DC4F51E9A61B500F8FA1A /* Main.storyboard */, 125 | D88DC4F81E9A61B500F8FA1A /* Assets.xcassets */, 126 | D88DC4FA1E9A61B500F8FA1A /* LaunchScreen.storyboard */, 127 | D88DC4FD1E9A61B500F8FA1A /* Info.plist */, 128 | ); 129 | path = Demo; 130 | sourceTree = ""; 131 | }; 132 | D88DC5051E9A61B500F8FA1A /* DemoUITests */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | D88DC5061E9A61B500F8FA1A /* DemoUITests.swift */, 136 | D88DC5081E9A61B500F8FA1A /* Info.plist */, 137 | ); 138 | path = DemoUITests; 139 | sourceTree = ""; 140 | }; 141 | D88DC5111E9A622700F8FA1A /* TestControllers */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | D88DC5121E9A622700F8FA1A /* BottomSheetController.swift */, 145 | D88DC5131E9A622700F8FA1A /* PopupViewController1.swift */, 146 | D88DC5141E9A622700F8FA1A /* PopupViewController2.swift */, 147 | ); 148 | path = TestControllers; 149 | sourceTree = ""; 150 | }; 151 | D88DC5181E9A628D00F8FA1A /* Frameworks */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | D88DC5A11E9A69D400F8FA1A /* MTPopup.framework */, 155 | ); 156 | name = Frameworks; 157 | sourceTree = ""; 158 | }; 159 | D88DC5A81E9A6C0600F8FA1A /* Products */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | D88DC5AC1E9A6C0600F8FA1A /* MTPopup.framework */, 163 | ); 164 | name = Products; 165 | sourceTree = ""; 166 | }; 167 | /* End PBXGroup section */ 168 | 169 | /* Begin PBXNativeTarget section */ 170 | D88DC4ED1E9A61B500F8FA1A /* Demo */ = { 171 | isa = PBXNativeTarget; 172 | buildConfigurationList = D88DC50B1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "Demo" */; 173 | buildPhases = ( 174 | D88DC4EA1E9A61B500F8FA1A /* Sources */, 175 | D88DC4EB1E9A61B500F8FA1A /* Frameworks */, 176 | D88DC4EC1E9A61B500F8FA1A /* Resources */, 177 | BEB6351D1FA6FEC700525EBB /* Embed Frameworks */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | BEB6351C1FA6FEC700525EBB /* PBXTargetDependency */, 183 | ); 184 | name = Demo; 185 | productName = Demo; 186 | productReference = D88DC4EE1E9A61B500F8FA1A /* Demo.app */; 187 | productType = "com.apple.product-type.application"; 188 | }; 189 | D88DC5011E9A61B500F8FA1A /* DemoUITests */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = D88DC50E1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "DemoUITests" */; 192 | buildPhases = ( 193 | D88DC4FE1E9A61B500F8FA1A /* Sources */, 194 | D88DC4FF1E9A61B500F8FA1A /* Frameworks */, 195 | D88DC5001E9A61B500F8FA1A /* Resources */, 196 | ); 197 | buildRules = ( 198 | ); 199 | dependencies = ( 200 | D88DC5041E9A61B500F8FA1A /* PBXTargetDependency */, 201 | ); 202 | name = DemoUITests; 203 | productName = DemoUITests; 204 | productReference = D88DC5021E9A61B500F8FA1A /* DemoUITests.xctest */; 205 | productType = "com.apple.product-type.bundle.ui-testing"; 206 | }; 207 | /* End PBXNativeTarget section */ 208 | 209 | /* Begin PBXProject section */ 210 | D88DC4E61E9A61B500F8FA1A /* Project object */ = { 211 | isa = PBXProject; 212 | attributes = { 213 | LastSwiftUpdateCheck = 0820; 214 | LastUpgradeCheck = 1250; 215 | ORGANIZATIONNAME = "伯驹 黄"; 216 | TargetAttributes = { 217 | D88DC4ED1E9A61B500F8FA1A = { 218 | CreatedOnToolsVersion = 8.2.1; 219 | LastSwiftMigration = 0900; 220 | ProvisioningStyle = Automatic; 221 | }; 222 | D88DC5011E9A61B500F8FA1A = { 223 | CreatedOnToolsVersion = 8.2.1; 224 | LastSwiftMigration = 1250; 225 | ProvisioningStyle = Automatic; 226 | TestTargetID = D88DC4ED1E9A61B500F8FA1A; 227 | }; 228 | }; 229 | }; 230 | buildConfigurationList = D88DC4E91E9A61B500F8FA1A /* Build configuration list for PBXProject "Demo" */; 231 | compatibilityVersion = "Xcode 3.2"; 232 | developmentRegion = en; 233 | hasScannedForEncodings = 0; 234 | knownRegions = ( 235 | en, 236 | Base, 237 | ); 238 | mainGroup = D88DC4E51E9A61B500F8FA1A; 239 | productRefGroup = D88DC4EF1E9A61B500F8FA1A /* Products */; 240 | projectDirPath = ""; 241 | projectReferences = ( 242 | { 243 | ProductGroup = D88DC5A81E9A6C0600F8FA1A /* Products */; 244 | ProjectRef = D88DC5A71E9A6C0600F8FA1A /* MTPopup.xcodeproj */; 245 | }, 246 | ); 247 | projectRoot = ""; 248 | targets = ( 249 | D88DC4ED1E9A61B500F8FA1A /* Demo */, 250 | D88DC5011E9A61B500F8FA1A /* DemoUITests */, 251 | ); 252 | }; 253 | /* End PBXProject section */ 254 | 255 | /* Begin PBXReferenceProxy section */ 256 | D88DC5AC1E9A6C0600F8FA1A /* MTPopup.framework */ = { 257 | isa = PBXReferenceProxy; 258 | fileType = wrapper.framework; 259 | path = MTPopup.framework; 260 | remoteRef = D88DC5AB1E9A6C0600F8FA1A /* PBXContainerItemProxy */; 261 | sourceTree = BUILT_PRODUCTS_DIR; 262 | }; 263 | /* End PBXReferenceProxy section */ 264 | 265 | /* Begin PBXResourcesBuildPhase section */ 266 | D88DC4EC1E9A61B500F8FA1A /* Resources */ = { 267 | isa = PBXResourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | D88DC4FC1E9A61B500F8FA1A /* LaunchScreen.storyboard in Resources */, 271 | D88DC4F91E9A61B500F8FA1A /* Assets.xcassets in Resources */, 272 | D88DC4F71E9A61B500F8FA1A /* Main.storyboard in Resources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | D88DC5001E9A61B500F8FA1A /* Resources */ = { 277 | isa = PBXResourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | /* End PBXResourcesBuildPhase section */ 284 | 285 | /* Begin PBXSourcesBuildPhase section */ 286 | D88DC4EA1E9A61B500F8FA1A /* Sources */ = { 287 | isa = PBXSourcesBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | D88DC5151E9A622700F8FA1A /* BottomSheetController.swift in Sources */, 291 | D88DC5161E9A622700F8FA1A /* PopupViewController1.swift in Sources */, 292 | D88DC4F41E9A61B500F8FA1A /* ViewController.swift in Sources */, 293 | D88DC5171E9A622700F8FA1A /* PopupViewController2.swift in Sources */, 294 | D88DC4F21E9A61B500F8FA1A /* AppDelegate.swift in Sources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | D88DC4FE1E9A61B500F8FA1A /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | D88DC5071E9A61B500F8FA1A /* DemoUITests.swift in Sources */, 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | /* End PBXSourcesBuildPhase section */ 307 | 308 | /* Begin PBXTargetDependency section */ 309 | BEB6351C1FA6FEC700525EBB /* PBXTargetDependency */ = { 310 | isa = PBXTargetDependency; 311 | name = MTPopup; 312 | targetProxy = BEB6351B1FA6FEC700525EBB /* PBXContainerItemProxy */; 313 | }; 314 | D88DC5041E9A61B500F8FA1A /* PBXTargetDependency */ = { 315 | isa = PBXTargetDependency; 316 | target = D88DC4ED1E9A61B500F8FA1A /* Demo */; 317 | targetProxy = D88DC5031E9A61B500F8FA1A /* PBXContainerItemProxy */; 318 | }; 319 | /* End PBXTargetDependency section */ 320 | 321 | /* Begin PBXVariantGroup section */ 322 | D88DC4F51E9A61B500F8FA1A /* Main.storyboard */ = { 323 | isa = PBXVariantGroup; 324 | children = ( 325 | D88DC4F61E9A61B500F8FA1A /* Base */, 326 | ); 327 | name = Main.storyboard; 328 | sourceTree = ""; 329 | }; 330 | D88DC4FA1E9A61B500F8FA1A /* LaunchScreen.storyboard */ = { 331 | isa = PBXVariantGroup; 332 | children = ( 333 | D88DC4FB1E9A61B500F8FA1A /* Base */, 334 | ); 335 | name = LaunchScreen.storyboard; 336 | sourceTree = ""; 337 | }; 338 | /* End PBXVariantGroup section */ 339 | 340 | /* Begin XCBuildConfiguration section */ 341 | D88DC5091E9A61B500F8FA1A /* Debug */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | ALWAYS_SEARCH_USER_PATHS = NO; 345 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 346 | CLANG_ANALYZER_NONNULL = YES; 347 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 348 | CLANG_CXX_LIBRARY = "libc++"; 349 | CLANG_ENABLE_MODULES = YES; 350 | CLANG_ENABLE_OBJC_ARC = YES; 351 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 352 | CLANG_WARN_BOOL_CONVERSION = YES; 353 | CLANG_WARN_COMMA = YES; 354 | CLANG_WARN_CONSTANT_CONVERSION = YES; 355 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 356 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 357 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 358 | CLANG_WARN_EMPTY_BODY = YES; 359 | CLANG_WARN_ENUM_CONVERSION = YES; 360 | CLANG_WARN_INFINITE_RECURSION = YES; 361 | CLANG_WARN_INT_CONVERSION = YES; 362 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 363 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 364 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 365 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 366 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 367 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 368 | CLANG_WARN_STRICT_PROTOTYPES = YES; 369 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 370 | CLANG_WARN_UNREACHABLE_CODE = YES; 371 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 372 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 373 | COPY_PHASE_STRIP = NO; 374 | DEBUG_INFORMATION_FORMAT = dwarf; 375 | ENABLE_STRICT_OBJC_MSGSEND = YES; 376 | ENABLE_TESTABILITY = YES; 377 | GCC_C_LANGUAGE_STANDARD = gnu99; 378 | GCC_DYNAMIC_NO_PIC = NO; 379 | GCC_NO_COMMON_BLOCKS = YES; 380 | GCC_OPTIMIZATION_LEVEL = 0; 381 | GCC_PREPROCESSOR_DEFINITIONS = ( 382 | "DEBUG=1", 383 | "$(inherited)", 384 | ); 385 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 386 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 387 | GCC_WARN_UNDECLARED_SELECTOR = YES; 388 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 389 | GCC_WARN_UNUSED_FUNCTION = YES; 390 | GCC_WARN_UNUSED_VARIABLE = YES; 391 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 392 | MTL_ENABLE_DEBUG_INFO = YES; 393 | ONLY_ACTIVE_ARCH = YES; 394 | SDKROOT = iphoneos; 395 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 396 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 397 | SWIFT_VERSION = 4.0; 398 | }; 399 | name = Debug; 400 | }; 401 | D88DC50A1E9A61B500F8FA1A /* Release */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | ALWAYS_SEARCH_USER_PATHS = NO; 405 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 406 | CLANG_ANALYZER_NONNULL = YES; 407 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 408 | CLANG_CXX_LIBRARY = "libc++"; 409 | CLANG_ENABLE_MODULES = YES; 410 | CLANG_ENABLE_OBJC_ARC = YES; 411 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 412 | CLANG_WARN_BOOL_CONVERSION = YES; 413 | CLANG_WARN_COMMA = YES; 414 | CLANG_WARN_CONSTANT_CONVERSION = YES; 415 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 416 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 417 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 418 | CLANG_WARN_EMPTY_BODY = YES; 419 | CLANG_WARN_ENUM_CONVERSION = YES; 420 | CLANG_WARN_INFINITE_RECURSION = YES; 421 | CLANG_WARN_INT_CONVERSION = YES; 422 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 423 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 424 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 427 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 428 | CLANG_WARN_STRICT_PROTOTYPES = YES; 429 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 430 | CLANG_WARN_UNREACHABLE_CODE = YES; 431 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 432 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 433 | COPY_PHASE_STRIP = NO; 434 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 435 | ENABLE_NS_ASSERTIONS = NO; 436 | ENABLE_STRICT_OBJC_MSGSEND = YES; 437 | GCC_C_LANGUAGE_STANDARD = gnu99; 438 | GCC_NO_COMMON_BLOCKS = YES; 439 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 440 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 441 | GCC_WARN_UNDECLARED_SELECTOR = YES; 442 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 443 | GCC_WARN_UNUSED_FUNCTION = YES; 444 | GCC_WARN_UNUSED_VARIABLE = YES; 445 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 446 | MTL_ENABLE_DEBUG_INFO = NO; 447 | SDKROOT = iphoneos; 448 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 449 | SWIFT_VERSION = 4.0; 450 | VALIDATE_PRODUCT = YES; 451 | }; 452 | name = Release; 453 | }; 454 | D88DC50C1E9A61B500F8FA1A /* Debug */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 458 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 459 | FRAMEWORK_SEARCH_PATHS = ( 460 | "$(inherited)", 461 | "$(PROJECT_DIR)/MTPopup/Carthage/Build/iOS", 462 | ); 463 | INFOPLIST_FILE = Demo/Info.plist; 464 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 465 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 466 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.Demo; 467 | PRODUCT_NAME = "$(TARGET_NAME)"; 468 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 469 | SWIFT_VERSION = 5.0; 470 | }; 471 | name = Debug; 472 | }; 473 | D88DC50D1E9A61B500F8FA1A /* Release */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 477 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 478 | FRAMEWORK_SEARCH_PATHS = ( 479 | "$(inherited)", 480 | "$(PROJECT_DIR)/MTPopup/Carthage/Build/iOS", 481 | ); 482 | INFOPLIST_FILE = Demo/Info.plist; 483 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 484 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 485 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.Demo; 486 | PRODUCT_NAME = "$(TARGET_NAME)"; 487 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 488 | SWIFT_VERSION = 5.0; 489 | }; 490 | name = Release; 491 | }; 492 | D88DC50F1E9A61B500F8FA1A /* Debug */ = { 493 | isa = XCBuildConfiguration; 494 | buildSettings = { 495 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 496 | INFOPLIST_FILE = DemoUITests/Info.plist; 497 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 498 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.DemoUITests; 499 | PRODUCT_NAME = "$(TARGET_NAME)"; 500 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 501 | SWIFT_VERSION = 5.0; 502 | TEST_TARGET_NAME = Demo; 503 | }; 504 | name = Debug; 505 | }; 506 | D88DC5101E9A61B500F8FA1A /* Release */ = { 507 | isa = XCBuildConfiguration; 508 | buildSettings = { 509 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 510 | INFOPLIST_FILE = DemoUITests/Info.plist; 511 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 512 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.DemoUITests; 513 | PRODUCT_NAME = "$(TARGET_NAME)"; 514 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 515 | SWIFT_VERSION = 5.0; 516 | TEST_TARGET_NAME = Demo; 517 | }; 518 | name = Release; 519 | }; 520 | /* End XCBuildConfiguration section */ 521 | 522 | /* Begin XCConfigurationList section */ 523 | D88DC4E91E9A61B500F8FA1A /* Build configuration list for PBXProject "Demo" */ = { 524 | isa = XCConfigurationList; 525 | buildConfigurations = ( 526 | D88DC5091E9A61B500F8FA1A /* Debug */, 527 | D88DC50A1E9A61B500F8FA1A /* Release */, 528 | ); 529 | defaultConfigurationIsVisible = 0; 530 | defaultConfigurationName = Release; 531 | }; 532 | D88DC50B1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "Demo" */ = { 533 | isa = XCConfigurationList; 534 | buildConfigurations = ( 535 | D88DC50C1E9A61B500F8FA1A /* Debug */, 536 | D88DC50D1E9A61B500F8FA1A /* Release */, 537 | ); 538 | defaultConfigurationIsVisible = 0; 539 | defaultConfigurationName = Release; 540 | }; 541 | D88DC50E1E9A61B500F8FA1A /* Build configuration list for PBXNativeTarget "DemoUITests" */ = { 542 | isa = XCConfigurationList; 543 | buildConfigurations = ( 544 | D88DC50F1E9A61B500F8FA1A /* Debug */, 545 | D88DC5101E9A61B500F8FA1A /* Release */, 546 | ); 547 | defaultConfigurationIsVisible = 0; 548 | defaultConfigurationName = Release; 549 | }; 550 | /* End XCConfigurationList section */ 551 | }; 552 | rootObject = D88DC4E61E9A61B500F8FA1A /* Project object */; 553 | } 554 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by 伯驹 黄 on 2017/4/9. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Demo/Demo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Demo/Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Demo/Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeRight 35 | UIInterfaceOrientationLandscapeLeft 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Demo/Demo/TestControllers/BottomSheetController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BottomSheetController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/12/10. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class BottomSheetController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | contentSizeInPopup = CGSize(width: view.frame.width, height: 300) 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Demo/Demo/TestControllers/PopupViewController1.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/14. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | let scaleW = UIScreen.main.bounds.width / 320 12 | let scaleH = UIScreen.main.bounds.height / 568 13 | 14 | class PopupViewController1: UIViewController { 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | title = "Apple" 20 | 21 | contentSizeInPopup = CGSize(width: 280 * scaleW, height: 380 * scaleH) 22 | landscapeContentSizeInPopup = CGSize(width: 400 * scaleH, height: 200 * scaleW) 23 | 24 | view.backgroundColor = UIColor.groupTableViewBackground 25 | 26 | let textLabel = UILabel(frame: CGRect(x: 15, y: 0, width: contentSizeInPopup.width - 30, height: 380)) 27 | textLabel.numberOfLines = 0 28 | textLabel.text = "Apple Inc. (commonly known as Apple) is an American multinational technology company headquartered in Cupertino, California, that designs, develops, and sells consumer electronics, computer software, and online services. Its best-known hardware products are the Mac personal computers, the iPod portable media player, the iPhone smartphone, the iPad tablet computer, and the Apple Watch smartwatch. Apple's consumer software includes the OS X and iOS operating systems, the iTunes media player, the Safari web browser, and the iLife and iWork creativity and productivity suites. Its online services include the iTunes Store, the iOS App Store and Mac App Store, and iCloud." 29 | view.addSubview(textLabel) 30 | 31 | navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(nextAction)) 32 | } 33 | 34 | @objc func nextAction() { 35 | popupController?.push(PopupViewController2(), animated: true) 36 | } 37 | 38 | override func didReceiveMemoryWarning() { 39 | super.didReceiveMemoryWarning() 40 | // Dispose of any resources that can be recreated. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Demo/Demo/TestControllers/PopupViewController2.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/12/5. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PopupViewController2: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | contentSizeInPopup = CGSize(width: 300 * scaleW, height: 200 * scaleH) 17 | landscapeContentSizeInPopup = CGSize(width: 400 * scaleH, height: 200 * scaleW) 18 | } 19 | 20 | override func didReceiveMemoryWarning() { 21 | super.didReceiveMemoryWarning() 22 | // Dispose of any resources that can be recreated. 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Demo/Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // STPopup 4 | // 5 | // Created by 伯驹 黄 on 2016/11/4. 6 | // Copyright © 2016年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MTPopup 11 | 12 | class ViewController: UIViewController { 13 | 14 | fileprivate lazy var tableView: UITableView = { 15 | let tableView = UITableView(frame: self.view.bounds, style: .grouped) 16 | tableView.dataSource = self 17 | tableView.delegate = self 18 | return tableView 19 | }() 20 | 21 | lazy var controllers: [UIViewController.Type] = [ 22 | PopupViewController1.self, 23 | PopupViewController1.self, 24 | BottomSheetController.self 25 | ] 26 | 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | title = "MTPopupController" 30 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") 31 | view.addSubview(tableView) 32 | } 33 | 34 | override func didReceiveMemoryWarning() { 35 | super.didReceiveMemoryWarning() 36 | // Dispose of any resources that can be recreated. 37 | } 38 | } 39 | 40 | extension ViewController: UITableViewDataSource { 41 | func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { 42 | return controllers.count 43 | } 44 | 45 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 46 | return tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 47 | } 48 | } 49 | 50 | extension ViewController: UITableViewDelegate { 51 | 52 | func tableView(_: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 53 | cell.textLabel?.text = "\(controllers[indexPath.row].classForCoder())" 54 | } 55 | 56 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 57 | tableView.deselectRow(at: indexPath, animated: false) 58 | 59 | let popupController = MTPopupController(rootViewController: controllers[indexPath.row].init()) 60 | popupController.autoAdjustKeyboardEvent = false 61 | 62 | if indexPath == IndexPath(row: 1, section: 0) { 63 | popupController.cornerRadius = 4 64 | let blurEffect = UIBlurEffect(style: .dark) 65 | popupController.backgroundView = UIVisualEffectView(effect: blurEffect) 66 | popupController.backgroundView?.alpha = 0.8 67 | } else if indexPath == IndexPath(row: 2, section: 0) { 68 | popupController.style = .bottomSheet 69 | } 70 | popupController.present(in: self) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Demo/DemoUITests/DemoUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoUITests.swift 3 | // DemoUITests 4 | // 5 | // Created by 伯驹 黄 on 2017/4/9. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class DemoUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // 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. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Demo/DemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/MTPopup/MTPopup.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | BEB635211FA6FFAE00525EBB /* UIResponder+MTPopup.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB6351F1FA6FFAE00525EBB /* UIResponder+MTPopup.h */; }; 11 | BEB635221FA6FFAE00525EBB /* UIResponder+MTPopup.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB635201FA6FFAE00525EBB /* UIResponder+MTPopup.m */; }; 12 | BEB635271FA702B500525EBB /* UIViewController+MTPopup.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB635251FA702B400525EBB /* UIViewController+MTPopup.h */; }; 13 | BEB635281FA702B500525EBB /* UIViewController+MTPopup.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB635261FA702B400525EBB /* UIViewController+MTPopup.m */; }; 14 | D88DC5821E9A691900F8FA1A /* MTPopup.h in Headers */ = {isa = PBXBuildFile; fileRef = D88DC5801E9A691900F8FA1A /* MTPopup.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | D88DC5951E9A695B00F8FA1A /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5891E9A695B00F8FA1A /* Array+Extensions.swift */; }; 16 | D88DC5961E9A695B00F8FA1A /* Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = D88DC58A1E9A695B00F8FA1A /* Bridging.h */; }; 17 | D88DC5971E9A695B00F8FA1A /* MTPopupContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58B1E9A695B00F8FA1A /* MTPopupContainerViewController.swift */; }; 18 | D88DC5981E9A695B00F8FA1A /* MTPopupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58C1E9A695B00F8FA1A /* MTPopupController.swift */; }; 19 | D88DC5991E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58D1E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift */; }; 20 | D88DC59A1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58E1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift */; }; 21 | D88DC59B1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC58F1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift */; }; 22 | D88DC59C1E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5901E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift */; }; 23 | D88DC59D1E9A695B00F8FA1A /* MTPopupLeftBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5911E9A695B00F8FA1A /* MTPopupLeftBarItem.swift */; }; 24 | D88DC59E1E9A695B00F8FA1A /* MTPopupNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5921E9A695B00F8FA1A /* MTPopupNavigationBar.swift */; }; 25 | D88DC59F1E9A695B00F8FA1A /* UIResponder+STPopup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5931E9A695B00F8FA1A /* UIResponder+STPopup.swift */; }; 26 | D88DC5A01E9A695B00F8FA1A /* UIViewController+STPopup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88DC5941E9A695B00F8FA1A /* UIViewController+STPopup.swift */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | BEB6351F1FA6FFAE00525EBB /* UIResponder+MTPopup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIResponder+MTPopup.h"; sourceTree = ""; }; 31 | BEB635201FA6FFAE00525EBB /* UIResponder+MTPopup.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIResponder+MTPopup.m"; sourceTree = ""; }; 32 | BEB635251FA702B400525EBB /* UIViewController+MTPopup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+MTPopup.h"; sourceTree = ""; }; 33 | BEB635261FA702B400525EBB /* UIViewController+MTPopup.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+MTPopup.m"; sourceTree = ""; }; 34 | D88DC57D1E9A691900F8FA1A /* MTPopup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MTPopup.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | D88DC5801E9A691900F8FA1A /* MTPopup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTPopup.h; sourceTree = ""; }; 36 | D88DC5811E9A691900F8FA1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | D88DC5891E9A695B00F8FA1A /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Extensions.swift"; sourceTree = ""; }; 38 | D88DC58A1E9A695B00F8FA1A /* Bridging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridging.h; sourceTree = ""; }; 39 | D88DC58B1E9A695B00F8FA1A /* MTPopupContainerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupContainerViewController.swift; sourceTree = ""; }; 40 | D88DC58C1E9A695B00F8FA1A /* MTPopupController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupController.swift; sourceTree = ""; }; 41 | D88DC58D1E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioning.swift; sourceTree = ""; }; 42 | D88DC58E1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioningContext.swift; sourceTree = ""; }; 43 | D88DC58F1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioningFade.swift; sourceTree = ""; }; 44 | D88DC5901E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupControllerTransitioningSlideVertical.swift; sourceTree = ""; }; 45 | D88DC5911E9A695B00F8FA1A /* MTPopupLeftBarItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupLeftBarItem.swift; sourceTree = ""; }; 46 | D88DC5921E9A695B00F8FA1A /* MTPopupNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTPopupNavigationBar.swift; sourceTree = ""; }; 47 | D88DC5931E9A695B00F8FA1A /* UIResponder+STPopup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+STPopup.swift"; sourceTree = ""; }; 48 | D88DC5941E9A695B00F8FA1A /* UIViewController+STPopup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+STPopup.swift"; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | D88DC5791E9A691900F8FA1A /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | /* End PBXFrameworksBuildPhase section */ 60 | 61 | /* Begin PBXGroup section */ 62 | D88DC5731E9A691900F8FA1A = { 63 | isa = PBXGroup; 64 | children = ( 65 | D88DC57F1E9A691900F8FA1A /* MTPopup */, 66 | D88DC57E1E9A691900F8FA1A /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | D88DC57E1E9A691900F8FA1A /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | D88DC57D1E9A691900F8FA1A /* MTPopup.framework */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | D88DC57F1E9A691900F8FA1A /* MTPopup */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | D88DC5881E9A695B00F8FA1A /* Classes */, 82 | D88DC5801E9A691900F8FA1A /* MTPopup.h */, 83 | D88DC5811E9A691900F8FA1A /* Info.plist */, 84 | ); 85 | path = MTPopup; 86 | sourceTree = ""; 87 | }; 88 | D88DC5881E9A695B00F8FA1A /* Classes */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | D88DC5891E9A695B00F8FA1A /* Array+Extensions.swift */, 92 | D88DC58A1E9A695B00F8FA1A /* Bridging.h */, 93 | D88DC58B1E9A695B00F8FA1A /* MTPopupContainerViewController.swift */, 94 | D88DC58C1E9A695B00F8FA1A /* MTPopupController.swift */, 95 | D88DC58D1E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift */, 96 | D88DC58E1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift */, 97 | D88DC58F1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift */, 98 | D88DC5901E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift */, 99 | D88DC5911E9A695B00F8FA1A /* MTPopupLeftBarItem.swift */, 100 | D88DC5921E9A695B00F8FA1A /* MTPopupNavigationBar.swift */, 101 | D88DC5931E9A695B00F8FA1A /* UIResponder+STPopup.swift */, 102 | D88DC5941E9A695B00F8FA1A /* UIViewController+STPopup.swift */, 103 | BEB6351F1FA6FFAE00525EBB /* UIResponder+MTPopup.h */, 104 | BEB635201FA6FFAE00525EBB /* UIResponder+MTPopup.m */, 105 | BEB635251FA702B400525EBB /* UIViewController+MTPopup.h */, 106 | BEB635261FA702B400525EBB /* UIViewController+MTPopup.m */, 107 | ); 108 | name = Classes; 109 | path = ../../../Classes; 110 | sourceTree = ""; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXHeadersBuildPhase section */ 115 | D88DC57A1E9A691900F8FA1A /* Headers */ = { 116 | isa = PBXHeadersBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | D88DC5961E9A695B00F8FA1A /* Bridging.h in Headers */, 120 | BEB635271FA702B500525EBB /* UIViewController+MTPopup.h in Headers */, 121 | D88DC5821E9A691900F8FA1A /* MTPopup.h in Headers */, 122 | BEB635211FA6FFAE00525EBB /* UIResponder+MTPopup.h in Headers */, 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | /* End PBXHeadersBuildPhase section */ 127 | 128 | /* Begin PBXNativeTarget section */ 129 | D88DC57C1E9A691900F8FA1A /* MTPopup */ = { 130 | isa = PBXNativeTarget; 131 | buildConfigurationList = D88DC5851E9A691900F8FA1A /* Build configuration list for PBXNativeTarget "MTPopup" */; 132 | buildPhases = ( 133 | D88DC5781E9A691900F8FA1A /* Sources */, 134 | D88DC5791E9A691900F8FA1A /* Frameworks */, 135 | D88DC57A1E9A691900F8FA1A /* Headers */, 136 | D88DC57B1E9A691900F8FA1A /* Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = MTPopup; 143 | productName = MTPopup; 144 | productReference = D88DC57D1E9A691900F8FA1A /* MTPopup.framework */; 145 | productType = "com.apple.product-type.framework"; 146 | }; 147 | /* End PBXNativeTarget section */ 148 | 149 | /* Begin PBXProject section */ 150 | D88DC5741E9A691900F8FA1A /* Project object */ = { 151 | isa = PBXProject; 152 | attributes = { 153 | LastUpgradeCheck = 1250; 154 | ORGANIZATIONNAME = "伯驹 黄"; 155 | TargetAttributes = { 156 | D88DC57C1E9A691900F8FA1A = { 157 | CreatedOnToolsVersion = 8.2.1; 158 | LastSwiftMigration = 1250; 159 | ProvisioningStyle = Automatic; 160 | }; 161 | }; 162 | }; 163 | buildConfigurationList = D88DC5771E9A691900F8FA1A /* Build configuration list for PBXProject "MTPopup" */; 164 | compatibilityVersion = "Xcode 3.2"; 165 | developmentRegion = en; 166 | hasScannedForEncodings = 0; 167 | knownRegions = ( 168 | en, 169 | Base, 170 | ); 171 | mainGroup = D88DC5731E9A691900F8FA1A; 172 | productRefGroup = D88DC57E1E9A691900F8FA1A /* Products */; 173 | projectDirPath = ""; 174 | projectRoot = ""; 175 | targets = ( 176 | D88DC57C1E9A691900F8FA1A /* MTPopup */, 177 | ); 178 | }; 179 | /* End PBXProject section */ 180 | 181 | /* Begin PBXResourcesBuildPhase section */ 182 | D88DC57B1E9A691900F8FA1A /* Resources */ = { 183 | isa = PBXResourcesBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXSourcesBuildPhase section */ 192 | D88DC5781E9A691900F8FA1A /* Sources */ = { 193 | isa = PBXSourcesBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | D88DC59F1E9A695B00F8FA1A /* UIResponder+STPopup.swift in Sources */, 197 | D88DC5981E9A695B00F8FA1A /* MTPopupController.swift in Sources */, 198 | D88DC59C1E9A695B00F8FA1A /* MTPopupControllerTransitioningSlideVertical.swift in Sources */, 199 | D88DC59E1E9A695B00F8FA1A /* MTPopupNavigationBar.swift in Sources */, 200 | D88DC5991E9A695B00F8FA1A /* MTPopupControllerTransitioning.swift in Sources */, 201 | BEB635281FA702B500525EBB /* UIViewController+MTPopup.m in Sources */, 202 | D88DC5971E9A695B00F8FA1A /* MTPopupContainerViewController.swift in Sources */, 203 | D88DC59A1E9A695B00F8FA1A /* MTPopupControllerTransitioningContext.swift in Sources */, 204 | D88DC5951E9A695B00F8FA1A /* Array+Extensions.swift in Sources */, 205 | BEB635221FA6FFAE00525EBB /* UIResponder+MTPopup.m in Sources */, 206 | D88DC59B1E9A695B00F8FA1A /* MTPopupControllerTransitioningFade.swift in Sources */, 207 | D88DC5A01E9A695B00F8FA1A /* UIViewController+STPopup.swift in Sources */, 208 | D88DC59D1E9A695B00F8FA1A /* MTPopupLeftBarItem.swift in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin XCBuildConfiguration section */ 215 | D88DC5831E9A691900F8FA1A /* Debug */ = { 216 | isa = XCBuildConfiguration; 217 | buildSettings = { 218 | ALWAYS_SEARCH_USER_PATHS = NO; 219 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 220 | CLANG_ANALYZER_NONNULL = YES; 221 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 222 | CLANG_CXX_LIBRARY = "libc++"; 223 | CLANG_ENABLE_MODULES = YES; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 226 | CLANG_WARN_BOOL_CONVERSION = YES; 227 | CLANG_WARN_COMMA = YES; 228 | CLANG_WARN_CONSTANT_CONVERSION = YES; 229 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 230 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 232 | CLANG_WARN_EMPTY_BODY = YES; 233 | CLANG_WARN_ENUM_CONVERSION = YES; 234 | CLANG_WARN_INFINITE_RECURSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 237 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 238 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 239 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 240 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 241 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 242 | CLANG_WARN_STRICT_PROTOTYPES = YES; 243 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 244 | CLANG_WARN_UNREACHABLE_CODE = YES; 245 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 246 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 247 | COPY_PHASE_STRIP = NO; 248 | CURRENT_PROJECT_VERSION = 1; 249 | DEBUG_INFORMATION_FORMAT = dwarf; 250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 251 | ENABLE_TESTABILITY = YES; 252 | GCC_C_LANGUAGE_STANDARD = gnu99; 253 | GCC_DYNAMIC_NO_PIC = NO; 254 | GCC_NO_COMMON_BLOCKS = YES; 255 | GCC_OPTIMIZATION_LEVEL = 0; 256 | GCC_PREPROCESSOR_DEFINITIONS = ( 257 | "DEBUG=1", 258 | "$(inherited)", 259 | ); 260 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 261 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 262 | GCC_WARN_UNDECLARED_SELECTOR = YES; 263 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 264 | GCC_WARN_UNUSED_FUNCTION = YES; 265 | GCC_WARN_UNUSED_VARIABLE = YES; 266 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 267 | MTL_ENABLE_DEBUG_INFO = YES; 268 | ONLY_ACTIVE_ARCH = YES; 269 | SDKROOT = iphoneos; 270 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 271 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 272 | TARGETED_DEVICE_FAMILY = "1,2"; 273 | VERSIONING_SYSTEM = "apple-generic"; 274 | VERSION_INFO_PREFIX = ""; 275 | }; 276 | name = Debug; 277 | }; 278 | D88DC5841E9A691900F8FA1A /* Release */ = { 279 | isa = XCBuildConfiguration; 280 | buildSettings = { 281 | ALWAYS_SEARCH_USER_PATHS = NO; 282 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 283 | CLANG_ANALYZER_NONNULL = YES; 284 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 285 | CLANG_CXX_LIBRARY = "libc++"; 286 | CLANG_ENABLE_MODULES = YES; 287 | CLANG_ENABLE_OBJC_ARC = YES; 288 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 289 | CLANG_WARN_BOOL_CONVERSION = YES; 290 | CLANG_WARN_COMMA = YES; 291 | CLANG_WARN_CONSTANT_CONVERSION = YES; 292 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 293 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 294 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 295 | CLANG_WARN_EMPTY_BODY = YES; 296 | CLANG_WARN_ENUM_CONVERSION = YES; 297 | CLANG_WARN_INFINITE_RECURSION = YES; 298 | CLANG_WARN_INT_CONVERSION = YES; 299 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 300 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 301 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 302 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 303 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 304 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 305 | CLANG_WARN_STRICT_PROTOTYPES = YES; 306 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 307 | CLANG_WARN_UNREACHABLE_CODE = YES; 308 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 309 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 310 | COPY_PHASE_STRIP = NO; 311 | CURRENT_PROJECT_VERSION = 1; 312 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 313 | ENABLE_NS_ASSERTIONS = NO; 314 | ENABLE_STRICT_OBJC_MSGSEND = YES; 315 | GCC_C_LANGUAGE_STANDARD = gnu99; 316 | GCC_NO_COMMON_BLOCKS = YES; 317 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 318 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 319 | GCC_WARN_UNDECLARED_SELECTOR = YES; 320 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 321 | GCC_WARN_UNUSED_FUNCTION = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 324 | MTL_ENABLE_DEBUG_INFO = NO; 325 | SDKROOT = iphoneos; 326 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 327 | TARGETED_DEVICE_FAMILY = "1,2"; 328 | VALIDATE_PRODUCT = YES; 329 | VERSIONING_SYSTEM = "apple-generic"; 330 | VERSION_INFO_PREFIX = ""; 331 | }; 332 | name = Release; 333 | }; 334 | D88DC5861E9A691900F8FA1A /* Debug */ = { 335 | isa = XCBuildConfiguration; 336 | buildSettings = { 337 | CLANG_ENABLE_MODULES = YES; 338 | CODE_SIGN_IDENTITY = ""; 339 | DEFINES_MODULE = YES; 340 | DYLIB_COMPATIBILITY_VERSION = 1; 341 | DYLIB_CURRENT_VERSION = 1; 342 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 343 | INFOPLIST_FILE = MTPopup/Info.plist; 344 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 345 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 346 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 347 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.MTPopup; 348 | PRODUCT_NAME = "$(TARGET_NAME)"; 349 | SKIP_INSTALL = YES; 350 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 351 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 352 | SWIFT_VERSION = 5.0; 353 | TARGETED_DEVICE_FAMILY = 1; 354 | }; 355 | name = Debug; 356 | }; 357 | D88DC5871E9A691900F8FA1A /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | CLANG_ENABLE_MODULES = YES; 361 | CODE_SIGN_IDENTITY = ""; 362 | DEFINES_MODULE = YES; 363 | DYLIB_COMPATIBILITY_VERSION = 1; 364 | DYLIB_CURRENT_VERSION = 1; 365 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 366 | INFOPLIST_FILE = MTPopup/Info.plist; 367 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 368 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 369 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 370 | PRODUCT_BUNDLE_IDENTIFIER = com.huangboju.MTPopup; 371 | PRODUCT_NAME = "$(TARGET_NAME)"; 372 | SKIP_INSTALL = YES; 373 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 374 | SWIFT_VERSION = 5.0; 375 | TARGETED_DEVICE_FAMILY = 1; 376 | }; 377 | name = Release; 378 | }; 379 | /* End XCBuildConfiguration section */ 380 | 381 | /* Begin XCConfigurationList section */ 382 | D88DC5771E9A691900F8FA1A /* Build configuration list for PBXProject "MTPopup" */ = { 383 | isa = XCConfigurationList; 384 | buildConfigurations = ( 385 | D88DC5831E9A691900F8FA1A /* Debug */, 386 | D88DC5841E9A691900F8FA1A /* Release */, 387 | ); 388 | defaultConfigurationIsVisible = 0; 389 | defaultConfigurationName = Release; 390 | }; 391 | D88DC5851E9A691900F8FA1A /* Build configuration list for PBXNativeTarget "MTPopup" */ = { 392 | isa = XCConfigurationList; 393 | buildConfigurations = ( 394 | D88DC5861E9A691900F8FA1A /* Debug */, 395 | D88DC5871E9A691900F8FA1A /* Release */, 396 | ); 397 | defaultConfigurationIsVisible = 0; 398 | defaultConfigurationName = Release; 399 | }; 400 | /* End XCConfigurationList section */ 401 | }; 402 | rootObject = D88DC5741E9A691900F8FA1A /* Project object */; 403 | } 404 | -------------------------------------------------------------------------------- /Demo/MTPopup/MTPopup.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/MTPopup/MTPopup.xcodeproj/xcshareddata/xcschemes/MTPopup.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Demo/MTPopup/MTPopup.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/MTPopup/MTPopup.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/MTPopup/MTPopup/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/MTPopup/MTPopup/MTPopup.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTPopup.h 3 | // MTPopup 4 | // 5 | // Created by 伯驹 黄 on 2017/4/9. 6 | // Copyright © 2017年 伯驹 黄. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MTPopup. 12 | FOUNDATION_EXPORT double MTPopupVersionNumber; 13 | 14 | //! Project version string for MTPopup. 15 | FOUNDATION_EXPORT const unsigned char MTPopupVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 xiAo-Ju 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MTPopup.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = "MTPopup" 5 | s.version = "1.1.0" 6 | s.summary = "You will like it" 7 | s.homepage = "https://github.com/huangboju/MTPopup" 8 | s.license = "MIT" 9 | s.author = { "huangboju" => "xiao-ju@foxmail.com" } 10 | s.platform = :ios,'8.0' 11 | s.source = { :git => "https://github.com/huangboju/MTPopup.git", :tag => "#{s.version}" } 12 | s.source_files = "Classes/**/*.{h,m,swift}" 13 | s.framework = "UIKit" 14 | s.requires_arc = true 15 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.0' } 16 | end 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Translation to [STPopup](https://github.com/kevin0571/STPopup) 3 | # Overview 4 | There are two ways to provide,`formSheet`、`bottomSheet`,and you can customize backgroundView. 5 | You just need to touch the bar and then move down to close. 6 | 7 | ![](https://github.com/huangboju/SwiftySTPopup/blob/master/2017-03-21%2020_24_31.gif) 8 | 9 | # Installtion 10 | 11 | * Cocoapods 12 | 13 | `pod MTPopup` 14 | 15 | * Carthage 16 | 17 | `github "huangboju/MTPopup"` 18 | 19 | # Usage 20 | 21 | * **BottomSheet** 22 | ```swift 23 | class YourController: UIViewController { 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | contentSizeInPopup = CGSize(width: 300, height: 200) 29 | landscapeContentSizeInPopup = CGSize(width: 400, height: 200) 30 | } 31 | } 32 | 33 | let popupController = MTPopupController(rootViewController: YourController()) 34 | popupController.style = .bottomSheet // Default is formSheet 35 | popupController.present(in: self) 36 | ``` 37 | 38 | * **Custom backgroundView** 39 | 40 | ```swift 41 | let popupController = MTPopupController(rootViewController: YourController()) 42 | 43 | let blurEffect = UIBlurEffect(style: .dark) 44 | popupController.backgroundView = UIVisualEffectView(effect: blurEffect) 45 | popupController.backgroundView?.alpha = 0.8 46 | popupController.present(in: self) 47 | ``` 48 | --------------------------------------------------------------------------------