├── .swift-version ├── Classes ├── .gitkeep └── Popover.swift ├── ScreenShots └── Screenshot.gif ├── Example ├── Podfile ├── Popover.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj ├── Popover.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── xcschemes │ │ ├── PopoverExampleTests.xcscheme │ │ └── PopoverExample.xcscheme ├── Podfile.lock ├── PopoverExampleTests │ ├── Info.plist │ └── PopoverExampleTests.swift └── Popover │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Info.plist │ ├── AppDelegate.swift │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ └── ViewController.swift ├── ExampleObjc ├── Podfile ├── PopoverExampleObjc.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj ├── Podfile.lock ├── PopoverExampleObjc.xcworkspace │ └── contents.xcworkspacedata └── PopoverExampleObjc │ ├── AppDelegate.h │ ├── main.m │ ├── ViewController.h │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Info.plist │ ├── ViewController.m │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ └── AppDelegate.m ├── Popover.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ └── Popover.xcscheme └── project.pbxproj ├── .travis.yml ├── .github └── workflows │ └── pod-deploy.yml ├── .gitignore ├── Supporting files ├── Popover.h └── Info.plist ├── Popover.podspec ├── LICENSE └── README.md /.swift-version: -------------------------------------------------------------------------------- 1 | 5.1 -------------------------------------------------------------------------------- /Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ScreenShots/Screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corin8823/Popover/HEAD/ScreenShots/Screenshot.gif -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '8.0' 3 | use_frameworks! 4 | 5 | target 'PopoverExample' do 6 | pod 'Popover', :path => "../" 7 | end 8 | -------------------------------------------------------------------------------- /ExampleObjc/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '8.0' 3 | use_frameworks! 4 | 5 | target 'PopoverExampleObjc' do 6 | pod 'Popover', :path => "../" 7 | end -------------------------------------------------------------------------------- /Popover.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Popover.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExampleObjc/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Popover (0.9.0) 3 | 4 | DEPENDENCIES: 5 | - Popover (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | Popover: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | Popover: e5a2cbfa29bb982c95cff0d7eb94f47173dbfbcc 13 | 14 | COCOAPODS: 0.39.0 15 | -------------------------------------------------------------------------------- /Example/Popover.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Popover.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Popover.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Popover (1.2.1) 3 | 4 | DEPENDENCIES: 5 | - Popover (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | Popover: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | Popover: 31a7e57c161ea6cc86dcba9ba45a2a9371398df0 13 | 14 | PODFILE CHECKSUM: 6d2f20b0ca605fb4d048b05500bed6d649d9a399 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | osx_image: xcode11.0 2 | language: objective-c 3 | install: 4 | - gem install cocoapods -v 1.8.0 --no-document 5 | 6 | before_script: 7 | - cd Example 8 | - pod install 9 | 10 | script: 11 | - xcodebuild -workspace Popover.xcworkspace -scheme "PopoverExample" -destination 'platform=iOS Simulator,OS=12.0,name=iPhone 8' build test | xcpretty 12 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PopoverExampleObjc 4 | // 5 | // Created by corin8823 on 4/6/16. 6 | // Copyright © 2016 corin8823. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/pod-deploy.yml: -------------------------------------------------------------------------------- 1 | name: pod-deploy 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | build: 10 | runs-on: macOS-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - name: Lint 14 | run: pod spec lint 15 | - name: Deploy 16 | env: 17 | COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} 18 | run: pod trunk push Popover.podspec 19 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PopoverExampleObjc 4 | // 5 | // Created by corin8823 on 4/6/16. 6 | // Copyright © 2016 corin8823. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | *.xcuserstate 22 | 23 | # Bundler 24 | .bundle 25 | 26 | # Carthage 27 | Carthage/Build/* 28 | Carthage/Checkouts/* 29 | 30 | # CocoaPods 31 | Pods/ -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PopoverExampleObjc 4 | // 5 | // Created by corin8823 on 4/6/16. 6 | // Copyright © 2016 corin8823. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @property (weak, nonatomic) IBOutlet UIButton *leftBottomButton; 14 | @property (weak, nonatomic) IBOutlet UIButton *rightButtomButton; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Supporting files/Popover.h: -------------------------------------------------------------------------------- 1 | // 2 | // Popover.h 3 | // Popover 4 | // 5 | // Created by Simon Støvring on 10/02/2016. 6 | // Copyright © 2016 SimonBS. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Popover. 12 | FOUNDATION_EXPORT double PopoverVersionNumber; 13 | 14 | //! Project version string for Popover. 15 | FOUNDATION_EXPORT const unsigned char PopoverVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Popover.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Popover" 3 | s.version = "1.3.0" 4 | s.summary = "Popover is a balloon library like facebook app. It is written in pure swift." 5 | s.homepage = "https://github.com/corin8823" 6 | s.license = { :type => "MIT", :file => "LICENSE" } 7 | s.author = { "corin8823" => "yusuke.t88@gmail.com" } 8 | s.source = { :git => "https://github.com/corin8823/Popover.git", :tag => s.version.to_s } 9 | s.social_media_url = 'https://twitter.com/corin8823' 10 | 11 | s.ios.deployment_target = "8.0" 12 | s.requires_arc = true 13 | 14 | s.source_files = 'Classes/*.swift' 15 | s.swift_version = '5.1' 16 | end 17 | -------------------------------------------------------------------------------- /Example/PopoverExampleTests/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 | -------------------------------------------------------------------------------- /Example/Popover/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Supporting files/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/PopoverExampleTests/PopoverExampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PopoverExampleTests.swift 3 | // PopoverExampleTests 4 | // 5 | // Created by corin8823 on 1/8/17. 6 | // Copyright © 2017 corin8823. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PopoverExampleTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testExample() { 24 | // This is an example of a functional test case. 25 | // Use XCTAssert and related functions to verify your tests produce the correct results. 26 | } 27 | 28 | func testPerformanceExample() { 29 | // This is an example of a performance test case. 30 | self.measure { 31 | // Put the code you want to measure the time of here. 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 corin8823 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Example/Popover/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PopoverExampleObjc 4 | // 5 | // Created by corin8823 on 4/6/16. 6 | // Copyright © 2016 corin8823. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "Popover-swift.h" 11 | 12 | @interface ViewController () 13 | 14 | @property (strong, nonatomic) Popover *popover; 15 | 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | } 23 | 24 | - (IBAction)tappedRightBarButton:(id)sender { 25 | CGPoint point = CGPointMake(self.view.frame.size.width - 60, 55); 26 | UIView *aView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, 180)]; 27 | Popover *popover = [[Popover alloc] init]; 28 | [popover show:aView point:point]; 29 | } 30 | 31 | - (IBAction)tappedLeftBottomButton:(id)sender { 32 | CGFloat width = self.view.frame.size.width / 4; 33 | UIView *aView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, width, width)]; 34 | Popover *popover = [[Popover alloc] initWithShowHandler:^{ 35 | NSLog(@"didShowHandler"); 36 | } dismissHandler:^{ 37 | NSLog(@"didDismissHandler"); 38 | 39 | }]; 40 | popover.cornerRadius = width / 2; 41 | popover.popoverType = PopoverTypeUp; 42 | [popover show: aView fromView:self.leftBottomButton]; 43 | } 44 | 45 | - (IBAction)tappedRigthButtomButton:(id)sender { 46 | CGFloat width = self.view.frame.size.width / 4; 47 | UIView *aView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, width, width)]; 48 | Popover *popover = [[Popover alloc] init]; 49 | popover.popoverType = PopoverTypeUp; 50 | [popover show: aView fromView:self.rightButtomButton]; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/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 | -------------------------------------------------------------------------------- /Example/Popover.xcworkspace/xcshareddata/xcschemes/PopoverExampleTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | 48 | 49 | 51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PopoverExampleObjc 4 | // 5 | // Created by corin8823 on 4/6/16. 6 | // Copyright © 2016 corin8823. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Example/Popover/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Popover 4 | // 5 | // Created by corin8823 on 8/16/15. 6 | // Copyright (c) 2015 corin8823. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | return true 19 | } 20 | 21 | func applicationWillResignActive(_ application: UIApplication) { 22 | // 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. 23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 24 | } 25 | 26 | func applicationDidEnterBackground(_ application: UIApplication) { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | func applicationWillEnterForeground(_ application: UIApplication) { 32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 33 | } 34 | 35 | func applicationDidBecomeActive(_ application: UIApplication) { 36 | // 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. 37 | } 38 | 39 | func applicationWillTerminate(_ application: UIApplication) { 40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Popover.xcodeproj/xcshareddata/xcschemes/Popover.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Popover 2 | 3 | [![CI Status](http://img.shields.io/travis/corin8823/Popover.svg?style=flat)](https://travis-ci.org/corin8823/Popover) 4 | [![Version](https://img.shields.io/cocoapods/v/Popover.svg?style=flat)](http://cocoapods.org/pods/Popover) 5 | [![License](https://img.shields.io/cocoapods/l/Popover.svg?style=flat)](http://cocoapods.org/pods/Popover) 6 | [![Platform](https://img.shields.io/cocoapods/p/Popover.svg?style=flat)](http://cocoapods.org/pods/Popover) 7 | 8 | ## Description and [appetize.io`s DEMO](https://appetize.io/app/q4n81yf0aakkx20x2cejh107b4) 9 | 10 | ![](https://github.com/corin8823/Popover/blob/master/ScreenShots/Screenshot.gif) 11 | 12 | ## Usage 13 | 14 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 15 | 16 | ### Simple 17 | 18 | ```swift 19 | let startPoint = CGPoint(x: self.view.frame.width - 60, y: 55) 20 | let aView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 180)) 21 | let popover = Popover() 22 | popover.show(aView, point: startPoint) 23 | ``` 24 | 25 | ### Custom 26 | 27 | ```swift 28 | @IBOutlet weak var leftBottomButton: UIButton! 29 | 30 | let width = self.view.frame.width / 4 31 | let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width)) 32 | let options = [ 33 | .type(.up), 34 | .cornerRadius(width / 2), 35 | .animationIn(0.3), 36 | .blackOverlayColor(UIColor.red), 37 | .arrowSize(CGSize.zero) 38 | ] as [PopoverOption] 39 | let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) 40 | popover.show(aView, fromView: self.leftBottomButton) 41 | ``` 42 | 43 | ## Requirements 44 | - iOS 9.0+ 45 | - Swift 5 46 | 47 | ## Installation 48 | 49 | ### CocoaPods (iOS 8+) 50 | Popover is available through [CocoaPods](http://cocoapods.org). To install 51 | it, simply add the following line to your `Podfile`: 52 | 53 | ```ruby 54 | use_frameworks! 55 | pod "Popover" 56 | ``` 57 | 58 | ### Carthage (iOS 8+) 59 | You can use [Carthage](https://github.com/Carthage/Carthage) to install `Popover` by adding it to your `Cartfile`: 60 | ```ruby 61 | github "corin8823/Popover" 62 | ``` 63 | 64 | ### Manual Installation 65 | The class file required for Popover is located in the Classes folder in the root of this repository as listed below: 66 | ``` 67 | Popover.swift 68 | ``` 69 | 70 | ## Customization 71 | 72 | ### Enum 73 | - ``case arrowSize(CGSize)`` 74 | - ``case animationIn(NSTimeInterval)`` 75 | - ``case animationOut(NSTimeInterval)`` 76 | - ``case cornerRadius(CGFloat)`` 77 | - ``case sideEdge(CGFloat)`` 78 | - ``case blackOverlayColor(UIColor)`` 79 | - ``case overlayBlur(UIBlurEffectStyle)`` 80 | - ``case type(Popover.PopoverType)`` 81 | - ``case color(UIColor)`` 82 | - ``case dismissOnBlackOverlayTap(Bool)`` 83 | - ``case showBlackOverlay(Bool)`` 84 | 85 | ### Property 86 | - ``arrowSize: CGSize = CGSize(width: 16.0, height: 10.0)`` 87 | - ``animationIn: NSTimeInterval = 0.6`` 88 | - ``animationOut: NSTimeInterval = 0.3`` 89 | - ``cornerRadius: CGFloat = 6.0`` 90 | - ``sideEdge: CGFloat = 20.0`` 91 | - ``popoverType: PopoverType = .down`` 92 | - ``blackOverlayColor: UIColor = UIColor(white: 0.0, alpha: 0.2)`` 93 | - ``overlayBlur: UIBlurEffect?`` 94 | - ``popoverColor: UIColor = UIColor.white`` 95 | 96 | ## Acknowledgments 97 | Inspired by [DXPopover](https://github.com/xiekw2010/DXPopover) in [xiekw2010](https://github.com/xiekw2010) 98 | 99 | ## License 100 | 101 | Popover is available under the MIT license. See the LICENSE file for more info. 102 | -------------------------------------------------------------------------------- /Example/Popover/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/Popover.xcworkspace/xcshareddata/xcschemes/PopoverExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Example/Popover/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Popover 4 | // 5 | // Created by corin8823 on 8/16/15. 6 | // Copyright (c) 2015 corin8823. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Popover 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet weak var rightBarButton: UIBarButtonItem! 15 | @IBOutlet weak var leftBottomButton: UIButton! 16 | @IBOutlet weak var rightButtomButton: UIButton! 17 | @IBOutlet weak var leftTopButton: UIButton! 18 | @IBOutlet weak var rightCenterButton: UIButton! 19 | 20 | fileprivate var texts = ["Edit", "Delete", "Report"] 21 | 22 | fileprivate var popover: Popover! 23 | fileprivate var popoverOptions: [PopoverOption] = [ 24 | .type(.auto), 25 | .blackOverlayColor(UIColor(white: 0.0, alpha: 0.6)) 26 | ] 27 | 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | } 31 | 32 | @IBAction func tappedRightBarButton(_ sender: UIBarButtonItem) { 33 | let startPoint = CGPoint(x: self.view.frame.width - 60, y: 55) 34 | let aView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 180)) 35 | let popover = Popover(options: nil, showHandler: nil, dismissHandler: nil) 36 | popover.show(aView, point: startPoint) 37 | } 38 | 39 | @IBAction func tappedLeftBottomButton(_ sender: UIButton) { 40 | let width = self.view.frame.width / 4 41 | let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width)) 42 | let options: [PopoverOption] = [.type(.up), .cornerRadius(width / 2), .showBlackOverlay(false)] 43 | let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) 44 | popover.show(aView, fromView: self.leftBottomButton) 45 | } 46 | 47 | @IBAction func tappedRightButtomButton(_ sender: UIButton) { 48 | let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 135)) 49 | tableView.delegate = self 50 | tableView.dataSource = self 51 | tableView.isScrollEnabled = false 52 | self.popover = Popover(options: self.popoverOptions) 53 | self.popover.willShowHandler = { 54 | print("willShowHandler") 55 | } 56 | self.popover.didShowHandler = { 57 | print("didDismissHandler") 58 | } 59 | self.popover.willDismissHandler = { 60 | print("willDismissHandler") 61 | } 62 | self.popover.didDismissHandler = { 63 | print("didDismissHandler") 64 | } 65 | self.popover.show(tableView, fromView: self.rightButtomButton) 66 | } 67 | 68 | @IBAction func tappedLeftTopButton(_ sender: UIButton) { 69 | let width = self.view.frame.width / 4 70 | let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width)) 71 | let options: [PopoverOption] = [.type(.right), .showBlackOverlay(false)] 72 | let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) 73 | popover.show(aView, fromView: self.leftTopButton) 74 | } 75 | 76 | @IBAction func tappedRightCenterButton(_ sender: UIButton) { 77 | let width = self.view.frame.width / 4 78 | let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width)) 79 | let options: [PopoverOption] = [.type(.left), .showBlackOverlay(false)] 80 | let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) 81 | popover.show(aView, fromView: self.rightCenterButton) 82 | } 83 | 84 | @IBAction func tappedAPositionButton(_ sender: UIButton) { 85 | let width = self.view.frame.width / 4 86 | let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width)) 87 | let options: [PopoverOption] = [.type(.auto), .showBlackOverlay(false)] 88 | let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) 89 | popover.show(aView, fromView: sender) 90 | } 91 | 92 | } 93 | 94 | extension ViewController: UITableViewDelegate { 95 | 96 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 97 | self.popover.dismiss() 98 | } 99 | } 100 | 101 | extension ViewController: UITableViewDataSource { 102 | 103 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ 104 | return 3 105 | } 106 | 107 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 108 | let cell = UITableViewCell(style: .default, reuseIdentifier: nil) 109 | cell.textLabel?.text = self.texts[(indexPath as NSIndexPath).row] 110 | return cell 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc/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 | 31 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Popover.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 72782A661C6BE60F003BA478 /* Popover.h in Headers */ = {isa = PBXBuildFile; fileRef = 72782A641C6BE60F003BA478 /* Popover.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 72782A681C6BE669003BA478 /* Popover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72782A671C6BE669003BA478 /* Popover.swift */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | 72782A571C6BE5C3003BA478 /* Popover.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Popover.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 16 | 72782A631C6BE60F003BA478 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 17 | 72782A641C6BE60F003BA478 /* Popover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Popover.h; sourceTree = ""; }; 18 | 72782A671C6BE669003BA478 /* Popover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Popover.swift; path = Classes/Popover.swift; sourceTree = SOURCE_ROOT; }; 19 | /* End PBXFileReference section */ 20 | 21 | /* Begin PBXFrameworksBuildPhase section */ 22 | 72782A531C6BE5C3003BA478 /* Frameworks */ = { 23 | isa = PBXFrameworksBuildPhase; 24 | buildActionMask = 2147483647; 25 | files = ( 26 | ); 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXFrameworksBuildPhase section */ 30 | 31 | /* Begin PBXGroup section */ 32 | 72782A4D1C6BE5C3003BA478 = { 33 | isa = PBXGroup; 34 | children = ( 35 | 72782A591C6BE5C3003BA478 /* Popover */, 36 | 72782A581C6BE5C3003BA478 /* Products */, 37 | ); 38 | sourceTree = ""; 39 | }; 40 | 72782A581C6BE5C3003BA478 /* Products */ = { 41 | isa = PBXGroup; 42 | children = ( 43 | 72782A571C6BE5C3003BA478 /* Popover.framework */, 44 | ); 45 | name = Products; 46 | sourceTree = ""; 47 | }; 48 | 72782A591C6BE5C3003BA478 /* Popover */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 72782A671C6BE669003BA478 /* Popover.swift */, 52 | 72782A621C6BE60F003BA478 /* Supporting files */, 53 | ); 54 | path = Popover; 55 | sourceTree = ""; 56 | }; 57 | 72782A621C6BE60F003BA478 /* Supporting files */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | 72782A631C6BE60F003BA478 /* Info.plist */, 61 | 72782A641C6BE60F003BA478 /* Popover.h */, 62 | ); 63 | path = "Supporting files"; 64 | sourceTree = SOURCE_ROOT; 65 | }; 66 | /* End PBXGroup section */ 67 | 68 | /* Begin PBXHeadersBuildPhase section */ 69 | 72782A541C6BE5C3003BA478 /* Headers */ = { 70 | isa = PBXHeadersBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | 72782A661C6BE60F003BA478 /* Popover.h in Headers */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXHeadersBuildPhase section */ 78 | 79 | /* Begin PBXNativeTarget section */ 80 | 72782A561C6BE5C3003BA478 /* Popover */ = { 81 | isa = PBXNativeTarget; 82 | buildConfigurationList = 72782A5F1C6BE5C3003BA478 /* Build configuration list for PBXNativeTarget "Popover" */; 83 | buildPhases = ( 84 | 72782A521C6BE5C3003BA478 /* Sources */, 85 | 72782A531C6BE5C3003BA478 /* Frameworks */, 86 | 72782A541C6BE5C3003BA478 /* Headers */, 87 | 72782A551C6BE5C3003BA478 /* Resources */, 88 | ); 89 | buildRules = ( 90 | ); 91 | dependencies = ( 92 | ); 93 | name = Popover; 94 | productName = Popover; 95 | productReference = 72782A571C6BE5C3003BA478 /* Popover.framework */; 96 | productType = "com.apple.product-type.framework"; 97 | }; 98 | /* End PBXNativeTarget section */ 99 | 100 | /* Begin PBXProject section */ 101 | 72782A4E1C6BE5C3003BA478 /* Project object */ = { 102 | isa = PBXProject; 103 | attributes = { 104 | LastUpgradeCheck = 1020; 105 | ORGANIZATIONNAME = SimonBS; 106 | TargetAttributes = { 107 | 72782A561C6BE5C3003BA478 = { 108 | CreatedOnToolsVersion = 7.2.1; 109 | LastSwiftMigration = 1020; 110 | }; 111 | }; 112 | }; 113 | buildConfigurationList = 72782A511C6BE5C3003BA478 /* Build configuration list for PBXProject "Popover" */; 114 | compatibilityVersion = "Xcode 3.2"; 115 | developmentRegion = en; 116 | hasScannedForEncodings = 0; 117 | knownRegions = ( 118 | en, 119 | Base, 120 | ); 121 | mainGroup = 72782A4D1C6BE5C3003BA478; 122 | productRefGroup = 72782A581C6BE5C3003BA478 /* Products */; 123 | projectDirPath = ""; 124 | projectRoot = ""; 125 | targets = ( 126 | 72782A561C6BE5C3003BA478 /* Popover */, 127 | ); 128 | }; 129 | /* End PBXProject section */ 130 | 131 | /* Begin PBXResourcesBuildPhase section */ 132 | 72782A551C6BE5C3003BA478 /* Resources */ = { 133 | isa = PBXResourcesBuildPhase; 134 | buildActionMask = 2147483647; 135 | files = ( 136 | ); 137 | runOnlyForDeploymentPostprocessing = 0; 138 | }; 139 | /* End PBXResourcesBuildPhase section */ 140 | 141 | /* Begin PBXSourcesBuildPhase section */ 142 | 72782A521C6BE5C3003BA478 /* Sources */ = { 143 | isa = PBXSourcesBuildPhase; 144 | buildActionMask = 2147483647; 145 | files = ( 146 | 72782A681C6BE669003BA478 /* Popover.swift in Sources */, 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | }; 150 | /* End PBXSourcesBuildPhase section */ 151 | 152 | /* Begin XCBuildConfiguration section */ 153 | 72782A5D1C6BE5C3003BA478 /* Debug */ = { 154 | isa = XCBuildConfiguration; 155 | buildSettings = { 156 | ALWAYS_SEARCH_USER_PATHS = NO; 157 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 158 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 159 | CLANG_CXX_LIBRARY = "libc++"; 160 | CLANG_ENABLE_MODULES = YES; 161 | CLANG_ENABLE_OBJC_ARC = YES; 162 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 163 | CLANG_WARN_BOOL_CONVERSION = YES; 164 | CLANG_WARN_COMMA = YES; 165 | CLANG_WARN_CONSTANT_CONVERSION = YES; 166 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 167 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 168 | CLANG_WARN_EMPTY_BODY = YES; 169 | CLANG_WARN_ENUM_CONVERSION = YES; 170 | CLANG_WARN_INFINITE_RECURSION = YES; 171 | CLANG_WARN_INT_CONVERSION = YES; 172 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 173 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 174 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 175 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 176 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 177 | CLANG_WARN_STRICT_PROTOTYPES = YES; 178 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 179 | CLANG_WARN_UNREACHABLE_CODE = YES; 180 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 181 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 182 | COPY_PHASE_STRIP = NO; 183 | CURRENT_PROJECT_VERSION = 1; 184 | DEBUG_INFORMATION_FORMAT = dwarf; 185 | ENABLE_STRICT_OBJC_MSGSEND = YES; 186 | ENABLE_TESTABILITY = YES; 187 | GCC_C_LANGUAGE_STANDARD = gnu99; 188 | GCC_DYNAMIC_NO_PIC = NO; 189 | GCC_NO_COMMON_BLOCKS = YES; 190 | GCC_OPTIMIZATION_LEVEL = 0; 191 | GCC_PREPROCESSOR_DEFINITIONS = ( 192 | "DEBUG=1", 193 | "$(inherited)", 194 | ); 195 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 196 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 197 | GCC_WARN_UNDECLARED_SELECTOR = YES; 198 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 199 | GCC_WARN_UNUSED_FUNCTION = YES; 200 | GCC_WARN_UNUSED_VARIABLE = YES; 201 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 202 | MTL_ENABLE_DEBUG_INFO = YES; 203 | ONLY_ACTIVE_ARCH = YES; 204 | SDKROOT = iphoneos; 205 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 206 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 207 | SWIFT_VERSION = 5.0; 208 | TARGETED_DEVICE_FAMILY = "1,2"; 209 | VERSIONING_SYSTEM = "apple-generic"; 210 | VERSION_INFO_PREFIX = ""; 211 | }; 212 | name = Debug; 213 | }; 214 | 72782A5E1C6BE5C3003BA478 /* Release */ = { 215 | isa = XCBuildConfiguration; 216 | buildSettings = { 217 | ALWAYS_SEARCH_USER_PATHS = NO; 218 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 219 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 220 | CLANG_CXX_LIBRARY = "libc++"; 221 | CLANG_ENABLE_MODULES = YES; 222 | CLANG_ENABLE_OBJC_ARC = YES; 223 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 224 | CLANG_WARN_BOOL_CONVERSION = YES; 225 | CLANG_WARN_COMMA = YES; 226 | CLANG_WARN_CONSTANT_CONVERSION = YES; 227 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 228 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 229 | CLANG_WARN_EMPTY_BODY = YES; 230 | CLANG_WARN_ENUM_CONVERSION = YES; 231 | CLANG_WARN_INFINITE_RECURSION = YES; 232 | CLANG_WARN_INT_CONVERSION = YES; 233 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 234 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 235 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 236 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 237 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 238 | CLANG_WARN_STRICT_PROTOTYPES = YES; 239 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 240 | CLANG_WARN_UNREACHABLE_CODE = YES; 241 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 242 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 243 | COPY_PHASE_STRIP = NO; 244 | CURRENT_PROJECT_VERSION = 1; 245 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 246 | ENABLE_NS_ASSERTIONS = NO; 247 | ENABLE_STRICT_OBJC_MSGSEND = YES; 248 | GCC_C_LANGUAGE_STANDARD = gnu99; 249 | GCC_NO_COMMON_BLOCKS = YES; 250 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 251 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 252 | GCC_WARN_UNDECLARED_SELECTOR = YES; 253 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 254 | GCC_WARN_UNUSED_FUNCTION = YES; 255 | GCC_WARN_UNUSED_VARIABLE = YES; 256 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 257 | MTL_ENABLE_DEBUG_INFO = NO; 258 | SDKROOT = iphoneos; 259 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 260 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 261 | SWIFT_VERSION = 5.0; 262 | TARGETED_DEVICE_FAMILY = "1,2"; 263 | VALIDATE_PRODUCT = YES; 264 | VERSIONING_SYSTEM = "apple-generic"; 265 | VERSION_INFO_PREFIX = ""; 266 | }; 267 | name = Release; 268 | }; 269 | 72782A601C6BE5C3003BA478 /* Debug */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | CLANG_ENABLE_MODULES = YES; 273 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 274 | DEFINES_MODULE = YES; 275 | DYLIB_COMPATIBILITY_VERSION = 1; 276 | DYLIB_CURRENT_VERSION = 1; 277 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 278 | INFOPLIST_FILE = "Supporting files/Info.plist"; 279 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 280 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 281 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 282 | PRODUCT_BUNDLE_IDENTIFIER = dk.simonbs.Popover; 283 | PRODUCT_NAME = "$(TARGET_NAME)"; 284 | SKIP_INSTALL = YES; 285 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 286 | SWIFT_VERSION = 5.0; 287 | }; 288 | name = Debug; 289 | }; 290 | 72782A611C6BE5C3003BA478 /* Release */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | CLANG_ENABLE_MODULES = YES; 294 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 295 | DEFINES_MODULE = YES; 296 | DYLIB_COMPATIBILITY_VERSION = 1; 297 | DYLIB_CURRENT_VERSION = 1; 298 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 299 | INFOPLIST_FILE = "Supporting files/Info.plist"; 300 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 301 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 302 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 303 | PRODUCT_BUNDLE_IDENTIFIER = dk.simonbs.Popover; 304 | PRODUCT_NAME = "$(TARGET_NAME)"; 305 | SKIP_INSTALL = YES; 306 | SWIFT_VERSION = 5.0; 307 | }; 308 | name = Release; 309 | }; 310 | /* End XCBuildConfiguration section */ 311 | 312 | /* Begin XCConfigurationList section */ 313 | 72782A511C6BE5C3003BA478 /* Build configuration list for PBXProject "Popover" */ = { 314 | isa = XCConfigurationList; 315 | buildConfigurations = ( 316 | 72782A5D1C6BE5C3003BA478 /* Debug */, 317 | 72782A5E1C6BE5C3003BA478 /* Release */, 318 | ); 319 | defaultConfigurationIsVisible = 0; 320 | defaultConfigurationName = Release; 321 | }; 322 | 72782A5F1C6BE5C3003BA478 /* Build configuration list for PBXNativeTarget "Popover" */ = { 323 | isa = XCConfigurationList; 324 | buildConfigurations = ( 325 | 72782A601C6BE5C3003BA478 /* Debug */, 326 | 72782A611C6BE5C3003BA478 /* Release */, 327 | ); 328 | defaultConfigurationIsVisible = 0; 329 | defaultConfigurationName = Release; 330 | }; 331 | /* End XCConfigurationList section */ 332 | }; 333 | rootObject = 72782A4E1C6BE5C3003BA478 /* Project object */; 334 | } 335 | -------------------------------------------------------------------------------- /Example/Popover.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 01A491CD1E222AFB007E15FA /* PopoverExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01A491CC1E222AFB007E15FA /* PopoverExampleTests.swift */; }; 11 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 12 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 13 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 16 | 76FCE001333FB3A5CE7D6A24 /* Pods_PopoverExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7272DC337697A6C52A135F0 /* Pods_PopoverExample.framework */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 01A491CF1E222AFB007E15FA /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 25 | remoteInfo = PopoverExample; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 01A491CA1E222AFB007E15FA /* PopoverExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PopoverExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 01A491CC1E222AFB007E15FA /* PopoverExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopoverExampleTests.swift; sourceTree = ""; }; 32 | 01A491CE1E222AFB007E15FA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 0C7CA225928466CCAA26D51E /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 34 | 607FACD01AFB9204008FA782 /* PopoverExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PopoverExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 38 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 39 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 40 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 41 | 65A80BF69ABA0864389E626F /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 42 | 932FBC229015BD6FEF162C71 /* Popover.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Popover.podspec; path = ../Popover.podspec; sourceTree = ""; }; 43 | A7272DC337697A6C52A135F0 /* Pods_PopoverExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PopoverExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | E051C51B0BA3C9F2F55FE1BC /* Pods-PopoverExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PopoverExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PopoverExample/Pods-PopoverExample.debug.xcconfig"; sourceTree = ""; }; 45 | E43483252C0750C0950138B5 /* Pods-PopoverExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PopoverExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-PopoverExample/Pods-PopoverExample.release.xcconfig"; sourceTree = ""; }; 46 | /* End PBXFileReference section */ 47 | 48 | /* Begin PBXFrameworksBuildPhase section */ 49 | 01A491C71E222AFB007E15FA /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | 76FCE001333FB3A5CE7D6A24 /* Pods_PopoverExample.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 01A491CB1E222AFB007E15FA /* PopoverExampleTests */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 01A491CE1E222AFB007E15FA /* Info.plist */, 71 | 01A491CC1E222AFB007E15FA /* PopoverExampleTests.swift */, 72 | ); 73 | path = PopoverExampleTests; 74 | sourceTree = ""; 75 | }; 76 | 2550AFBDF3B7957B49C10F85 /* Frameworks */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | A7272DC337697A6C52A135F0 /* Pods_PopoverExample.framework */, 80 | ); 81 | name = Frameworks; 82 | sourceTree = ""; 83 | }; 84 | 607FACC71AFB9204008FA782 = { 85 | isa = PBXGroup; 86 | children = ( 87 | 2550AFBDF3B7957B49C10F85 /* Frameworks */, 88 | E00CC2F1C8FD47D6208C4691 /* Pods */, 89 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 90 | 607FACD21AFB9204008FA782 /* Popover */, 91 | 01A491CB1E222AFB007E15FA /* PopoverExampleTests */, 92 | 607FACD11AFB9204008FA782 /* Products */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | 607FACD11AFB9204008FA782 /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 607FACD01AFB9204008FA782 /* PopoverExample.app */, 100 | 01A491CA1E222AFB007E15FA /* PopoverExampleTests.xctest */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | 607FACD21AFB9204008FA782 /* Popover */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 607FACD31AFB9204008FA782 /* Supporting Files */, 109 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 110 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 111 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 112 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 113 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 114 | ); 115 | path = Popover; 116 | sourceTree = ""; 117 | }; 118 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 607FACD41AFB9204008FA782 /* Info.plist */, 122 | ); 123 | name = "Supporting Files"; 124 | sourceTree = ""; 125 | }; 126 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 0C7CA225928466CCAA26D51E /* LICENSE */, 130 | 932FBC229015BD6FEF162C71 /* Popover.podspec */, 131 | 65A80BF69ABA0864389E626F /* README.md */, 132 | ); 133 | name = "Podspec Metadata"; 134 | sourceTree = ""; 135 | }; 136 | E00CC2F1C8FD47D6208C4691 /* Pods */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | E051C51B0BA3C9F2F55FE1BC /* Pods-PopoverExample.debug.xcconfig */, 140 | E43483252C0750C0950138B5 /* Pods-PopoverExample.release.xcconfig */, 141 | ); 142 | name = Pods; 143 | sourceTree = ""; 144 | }; 145 | /* End PBXGroup section */ 146 | 147 | /* Begin PBXNativeTarget section */ 148 | 01A491C91E222AFB007E15FA /* PopoverExampleTests */ = { 149 | isa = PBXNativeTarget; 150 | buildConfigurationList = 01A491D31E222AFB007E15FA /* Build configuration list for PBXNativeTarget "PopoverExampleTests" */; 151 | buildPhases = ( 152 | 01A491C61E222AFB007E15FA /* Sources */, 153 | 01A491C71E222AFB007E15FA /* Frameworks */, 154 | 01A491C81E222AFB007E15FA /* Resources */, 155 | ); 156 | buildRules = ( 157 | ); 158 | dependencies = ( 159 | 01A491D01E222AFB007E15FA /* PBXTargetDependency */, 160 | ); 161 | name = PopoverExampleTests; 162 | productName = PopoverExampleTests; 163 | productReference = 01A491CA1E222AFB007E15FA /* PopoverExampleTests.xctest */; 164 | productType = "com.apple.product-type.bundle.unit-test"; 165 | }; 166 | 607FACCF1AFB9204008FA782 /* PopoverExample */ = { 167 | isa = PBXNativeTarget; 168 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "PopoverExample" */; 169 | buildPhases = ( 170 | AA2E1EE836D2B226FCD44825 /* [CP] Check Pods Manifest.lock */, 171 | 607FACCC1AFB9204008FA782 /* Sources */, 172 | 607FACCD1AFB9204008FA782 /* Frameworks */, 173 | 607FACCE1AFB9204008FA782 /* Resources */, 174 | 6F95EC676DC3E57801C40B90 /* [CP] Embed Pods Frameworks */, 175 | ); 176 | buildRules = ( 177 | ); 178 | dependencies = ( 179 | ); 180 | name = PopoverExample; 181 | productName = Popover; 182 | productReference = 607FACD01AFB9204008FA782 /* PopoverExample.app */; 183 | productType = "com.apple.product-type.application"; 184 | }; 185 | /* End PBXNativeTarget section */ 186 | 187 | /* Begin PBXProject section */ 188 | 607FACC81AFB9204008FA782 /* Project object */ = { 189 | isa = PBXProject; 190 | attributes = { 191 | LastSwiftMigration = 0700; 192 | LastSwiftUpdateCheck = 0820; 193 | LastUpgradeCheck = 1020; 194 | ORGANIZATIONNAME = CocoaPods; 195 | TargetAttributes = { 196 | 01A491C91E222AFB007E15FA = { 197 | CreatedOnToolsVersion = 8.2.1; 198 | LastSwiftMigration = 1020; 199 | ProvisioningStyle = Automatic; 200 | TestTargetID = 607FACCF1AFB9204008FA782; 201 | }; 202 | 607FACCF1AFB9204008FA782 = { 203 | CreatedOnToolsVersion = 6.3.1; 204 | LastSwiftMigration = 1020; 205 | }; 206 | }; 207 | }; 208 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Popover" */; 209 | compatibilityVersion = "Xcode 3.2"; 210 | developmentRegion = en; 211 | hasScannedForEncodings = 0; 212 | knownRegions = ( 213 | en, 214 | Base, 215 | ); 216 | mainGroup = 607FACC71AFB9204008FA782; 217 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 218 | projectDirPath = ""; 219 | projectRoot = ""; 220 | targets = ( 221 | 607FACCF1AFB9204008FA782 /* PopoverExample */, 222 | 01A491C91E222AFB007E15FA /* PopoverExampleTests */, 223 | ); 224 | }; 225 | /* End PBXProject section */ 226 | 227 | /* Begin PBXResourcesBuildPhase section */ 228 | 01A491C81E222AFB007E15FA /* Resources */ = { 229 | isa = PBXResourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | }; 235 | 607FACCE1AFB9204008FA782 /* Resources */ = { 236 | isa = PBXResourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 240 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 241 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | /* End PBXResourcesBuildPhase section */ 246 | 247 | /* Begin PBXShellScriptBuildPhase section */ 248 | 6F95EC676DC3E57801C40B90 /* [CP] Embed Pods Frameworks */ = { 249 | isa = PBXShellScriptBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | ); 253 | inputPaths = ( 254 | "${SRCROOT}/Pods/Target Support Files/Pods-PopoverExample/Pods-PopoverExample-frameworks.sh", 255 | "${BUILT_PRODUCTS_DIR}/Popover/Popover.framework", 256 | ); 257 | name = "[CP] Embed Pods Frameworks"; 258 | outputPaths = ( 259 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Popover.framework", 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | shellPath = /bin/sh; 263 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PopoverExample/Pods-PopoverExample-frameworks.sh\"\n"; 264 | showEnvVarsInLog = 0; 265 | }; 266 | AA2E1EE836D2B226FCD44825 /* [CP] Check Pods Manifest.lock */ = { 267 | isa = PBXShellScriptBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | ); 271 | inputPaths = ( 272 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 273 | "${PODS_ROOT}/Manifest.lock", 274 | ); 275 | name = "[CP] Check Pods Manifest.lock"; 276 | outputPaths = ( 277 | "$(DERIVED_FILE_DIR)/Pods-PopoverExample-checkManifestLockResult.txt", 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | shellPath = /bin/sh; 281 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 282 | showEnvVarsInLog = 0; 283 | }; 284 | /* End PBXShellScriptBuildPhase section */ 285 | 286 | /* Begin PBXSourcesBuildPhase section */ 287 | 01A491C61E222AFB007E15FA /* Sources */ = { 288 | isa = PBXSourcesBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | 01A491CD1E222AFB007E15FA /* PopoverExampleTests.swift in Sources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | 607FACCC1AFB9204008FA782 /* Sources */ = { 296 | isa = PBXSourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 300 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | }; 304 | /* End PBXSourcesBuildPhase section */ 305 | 306 | /* Begin PBXTargetDependency section */ 307 | 01A491D01E222AFB007E15FA /* PBXTargetDependency */ = { 308 | isa = PBXTargetDependency; 309 | target = 607FACCF1AFB9204008FA782 /* PopoverExample */; 310 | targetProxy = 01A491CF1E222AFB007E15FA /* PBXContainerItemProxy */; 311 | }; 312 | /* End PBXTargetDependency section */ 313 | 314 | /* Begin PBXVariantGroup section */ 315 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 316 | isa = PBXVariantGroup; 317 | children = ( 318 | 607FACDA1AFB9204008FA782 /* Base */, 319 | ); 320 | name = Main.storyboard; 321 | sourceTree = ""; 322 | }; 323 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 324 | isa = PBXVariantGroup; 325 | children = ( 326 | 607FACDF1AFB9204008FA782 /* Base */, 327 | ); 328 | name = LaunchScreen.xib; 329 | sourceTree = ""; 330 | }; 331 | /* End PBXVariantGroup section */ 332 | 333 | /* Begin XCBuildConfiguration section */ 334 | 01A491D11E222AFB007E15FA /* Debug */ = { 335 | isa = XCBuildConfiguration; 336 | buildSettings = { 337 | BUNDLE_LOADER = "$(TEST_HOST)"; 338 | CLANG_ANALYZER_NONNULL = YES; 339 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 340 | DEBUG_INFORMATION_FORMAT = dwarf; 341 | INFOPLIST_FILE = PopoverExampleTests/Info.plist; 342 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 343 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 344 | PRODUCT_BUNDLE_IDENTIFIER = corin8823.PopoverExampleTests; 345 | PRODUCT_NAME = "$(TARGET_NAME)"; 346 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 347 | SWIFT_VERSION = 5.0; 348 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PopoverExample.app/PopoverExample"; 349 | }; 350 | name = Debug; 351 | }; 352 | 01A491D21E222AFB007E15FA /* Release */ = { 353 | isa = XCBuildConfiguration; 354 | buildSettings = { 355 | BUNDLE_LOADER = "$(TEST_HOST)"; 356 | CLANG_ANALYZER_NONNULL = YES; 357 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 358 | INFOPLIST_FILE = PopoverExampleTests/Info.plist; 359 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 360 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 361 | PRODUCT_BUNDLE_IDENTIFIER = corin8823.PopoverExampleTests; 362 | PRODUCT_NAME = "$(TARGET_NAME)"; 363 | SWIFT_VERSION = 5.0; 364 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PopoverExample.app/PopoverExample"; 365 | }; 366 | name = Release; 367 | }; 368 | 607FACED1AFB9204008FA782 /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | ALWAYS_SEARCH_USER_PATHS = NO; 372 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 373 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 374 | CLANG_CXX_LIBRARY = "libc++"; 375 | CLANG_ENABLE_MODULES = YES; 376 | CLANG_ENABLE_OBJC_ARC = YES; 377 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 378 | CLANG_WARN_BOOL_CONVERSION = YES; 379 | CLANG_WARN_COMMA = YES; 380 | CLANG_WARN_CONSTANT_CONVERSION = YES; 381 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 382 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 383 | CLANG_WARN_EMPTY_BODY = YES; 384 | CLANG_WARN_ENUM_CONVERSION = YES; 385 | CLANG_WARN_INFINITE_RECURSION = YES; 386 | CLANG_WARN_INT_CONVERSION = YES; 387 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 388 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 389 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 390 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 391 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 392 | CLANG_WARN_STRICT_PROTOTYPES = YES; 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_STRICT_OBJC_MSGSEND = YES; 400 | ENABLE_TESTABILITY = YES; 401 | GCC_C_LANGUAGE_STANDARD = gnu99; 402 | GCC_DYNAMIC_NO_PIC = NO; 403 | GCC_NO_COMMON_BLOCKS = YES; 404 | GCC_OPTIMIZATION_LEVEL = 0; 405 | GCC_PREPROCESSOR_DEFINITIONS = ( 406 | "DEBUG=1", 407 | "$(inherited)", 408 | ); 409 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 410 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 411 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 412 | GCC_WARN_UNDECLARED_SELECTOR = YES; 413 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 414 | GCC_WARN_UNUSED_FUNCTION = YES; 415 | GCC_WARN_UNUSED_VARIABLE = YES; 416 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 417 | MTL_ENABLE_DEBUG_INFO = YES; 418 | ONLY_ACTIVE_ARCH = YES; 419 | SDKROOT = iphoneos; 420 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 421 | }; 422 | name = Debug; 423 | }; 424 | 607FACEE1AFB9204008FA782 /* Release */ = { 425 | isa = XCBuildConfiguration; 426 | buildSettings = { 427 | ALWAYS_SEARCH_USER_PATHS = NO; 428 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 429 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 430 | CLANG_CXX_LIBRARY = "libc++"; 431 | CLANG_ENABLE_MODULES = YES; 432 | CLANG_ENABLE_OBJC_ARC = YES; 433 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 434 | CLANG_WARN_BOOL_CONVERSION = YES; 435 | CLANG_WARN_COMMA = YES; 436 | CLANG_WARN_CONSTANT_CONVERSION = YES; 437 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 438 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 439 | CLANG_WARN_EMPTY_BODY = YES; 440 | CLANG_WARN_ENUM_CONVERSION = YES; 441 | CLANG_WARN_INFINITE_RECURSION = YES; 442 | CLANG_WARN_INT_CONVERSION = YES; 443 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 444 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 445 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 446 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 447 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 448 | CLANG_WARN_STRICT_PROTOTYPES = YES; 449 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 450 | CLANG_WARN_UNREACHABLE_CODE = YES; 451 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 452 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 453 | COPY_PHASE_STRIP = NO; 454 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 455 | ENABLE_NS_ASSERTIONS = NO; 456 | ENABLE_STRICT_OBJC_MSGSEND = YES; 457 | GCC_C_LANGUAGE_STANDARD = gnu99; 458 | GCC_NO_COMMON_BLOCKS = YES; 459 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 460 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 461 | GCC_WARN_UNDECLARED_SELECTOR = YES; 462 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 463 | GCC_WARN_UNUSED_FUNCTION = YES; 464 | GCC_WARN_UNUSED_VARIABLE = YES; 465 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 466 | MTL_ENABLE_DEBUG_INFO = NO; 467 | SDKROOT = iphoneos; 468 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 469 | VALIDATE_PRODUCT = YES; 470 | }; 471 | name = Release; 472 | }; 473 | 607FACF01AFB9204008FA782 /* Debug */ = { 474 | isa = XCBuildConfiguration; 475 | baseConfigurationReference = E051C51B0BA3C9F2F55FE1BC /* Pods-PopoverExample.debug.xcconfig */; 476 | buildSettings = { 477 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 478 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 479 | FRAMEWORK_SEARCH_PATHS = ( 480 | "$(inherited)", 481 | "$(PROJECT_DIR)/build/Debug-iphoneos", 482 | ); 483 | INFOPLIST_FILE = Popover/Info.plist; 484 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 485 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 486 | MODULE_NAME = ExampleApp; 487 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 488 | PRODUCT_NAME = "$(TARGET_NAME)"; 489 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 490 | SWIFT_VERSION = 5.0; 491 | }; 492 | name = Debug; 493 | }; 494 | 607FACF11AFB9204008FA782 /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | baseConfigurationReference = E43483252C0750C0950138B5 /* Pods-PopoverExample.release.xcconfig */; 497 | buildSettings = { 498 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 499 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 500 | FRAMEWORK_SEARCH_PATHS = ( 501 | "$(inherited)", 502 | "$(PROJECT_DIR)/build/Debug-iphoneos", 503 | ); 504 | INFOPLIST_FILE = Popover/Info.plist; 505 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 506 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 507 | MODULE_NAME = ExampleApp; 508 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 509 | PRODUCT_NAME = "$(TARGET_NAME)"; 510 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 511 | SWIFT_VERSION = 5.0; 512 | }; 513 | name = Release; 514 | }; 515 | /* End XCBuildConfiguration section */ 516 | 517 | /* Begin XCConfigurationList section */ 518 | 01A491D31E222AFB007E15FA /* Build configuration list for PBXNativeTarget "PopoverExampleTests" */ = { 519 | isa = XCConfigurationList; 520 | buildConfigurations = ( 521 | 01A491D11E222AFB007E15FA /* Debug */, 522 | 01A491D21E222AFB007E15FA /* Release */, 523 | ); 524 | defaultConfigurationIsVisible = 0; 525 | defaultConfigurationName = Release; 526 | }; 527 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Popover" */ = { 528 | isa = XCConfigurationList; 529 | buildConfigurations = ( 530 | 607FACED1AFB9204008FA782 /* Debug */, 531 | 607FACEE1AFB9204008FA782 /* Release */, 532 | ); 533 | defaultConfigurationIsVisible = 0; 534 | defaultConfigurationName = Release; 535 | }; 536 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "PopoverExample" */ = { 537 | isa = XCConfigurationList; 538 | buildConfigurations = ( 539 | 607FACF01AFB9204008FA782 /* Debug */, 540 | 607FACF11AFB9204008FA782 /* Release */, 541 | ); 542 | defaultConfigurationIsVisible = 0; 543 | defaultConfigurationName = Release; 544 | }; 545 | /* End XCConfigurationList section */ 546 | }; 547 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 548 | } 549 | -------------------------------------------------------------------------------- /ExampleObjc/PopoverExampleObjc.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | archiveVersion 6 | 1 7 | classes 8 | 9 | objectVersion 10 | 46 11 | objects 12 | 13 | 0112010D1CB54AD3007E8F9A 14 | 15 | children 16 | 17 | 011201181CB54AD3007E8F9A 18 | 011201171CB54AD3007E8F9A 19 | BE6E6066048B6A04661F49F1 20 | D8E052B333F738D9DB5F71CA 21 | 22 | isa 23 | PBXGroup 24 | sourceTree 25 | <group> 26 | 27 | 0112010E1CB54AD3007E8F9A 28 | 29 | attributes 30 | 31 | LastUpgradeCheck 32 | 0730 33 | ORGANIZATIONNAME 34 | corin8823 35 | TargetAttributes 36 | 37 | 011201151CB54AD3007E8F9A 38 | 39 | CreatedOnToolsVersion 40 | 7.3 41 | 42 | 43 | 44 | buildConfigurationList 45 | 011201111CB54AD3007E8F9A 46 | compatibilityVersion 47 | Xcode 3.2 48 | developmentRegion 49 | English 50 | hasScannedForEncodings 51 | 0 52 | isa 53 | PBXProject 54 | knownRegions 55 | 56 | en 57 | Base 58 | 59 | mainGroup 60 | 0112010D1CB54AD3007E8F9A 61 | productRefGroup 62 | 011201171CB54AD3007E8F9A 63 | projectDirPath 64 | 65 | projectReferences 66 | 67 | projectRoot 68 | 69 | targets 70 | 71 | 011201151CB54AD3007E8F9A 72 | 73 | 74 | 011201111CB54AD3007E8F9A 75 | 76 | buildConfigurations 77 | 78 | 0112012B1CB54AD3007E8F9A 79 | 0112012C1CB54AD3007E8F9A 80 | 81 | defaultConfigurationIsVisible 82 | 0 83 | defaultConfigurationName 84 | Release 85 | isa 86 | XCConfigurationList 87 | 88 | 011201121CB54AD3007E8F9A 89 | 90 | buildActionMask 91 | 2147483647 92 | files 93 | 94 | 011201211CB54AD3007E8F9A 95 | 0112011E1CB54AD3007E8F9A 96 | 0112011B1CB54AD3007E8F9A 97 | 98 | isa 99 | PBXSourcesBuildPhase 100 | runOnlyForDeploymentPostprocessing 101 | 0 102 | 103 | 011201131CB54AD3007E8F9A 104 | 105 | buildActionMask 106 | 2147483647 107 | files 108 | 109 | 4EA91790460316EC172E1238 110 | 111 | isa 112 | PBXFrameworksBuildPhase 113 | runOnlyForDeploymentPostprocessing 114 | 0 115 | 116 | 011201141CB54AD3007E8F9A 117 | 118 | buildActionMask 119 | 2147483647 120 | files 121 | 122 | 011201291CB54AD3007E8F9A 123 | 011201261CB54AD3007E8F9A 124 | 011201241CB54AD3007E8F9A 125 | 126 | isa 127 | PBXResourcesBuildPhase 128 | runOnlyForDeploymentPostprocessing 129 | 0 130 | 131 | 011201151CB54AD3007E8F9A 132 | 133 | buildConfigurationList 134 | 0112012D1CB54AD3007E8F9A 135 | buildPhases 136 | 137 | EE20AB4564DCF82EA75025F3 138 | 011201121CB54AD3007E8F9A 139 | 011201131CB54AD3007E8F9A 140 | 011201141CB54AD3007E8F9A 141 | E7AAA46C00E084BBD47D685F 142 | 152E7D34FD1DFF38F1667F26 143 | 144 | buildRules 145 | 146 | dependencies 147 | 148 | isa 149 | PBXNativeTarget 150 | name 151 | PopoverExampleObjc 152 | productName 153 | PopoverExampleObjc 154 | productReference 155 | 011201161CB54AD3007E8F9A 156 | productType 157 | com.apple.product-type.application 158 | 159 | 011201161CB54AD3007E8F9A 160 | 161 | explicitFileType 162 | wrapper.application 163 | includeInIndex 164 | 0 165 | isa 166 | PBXFileReference 167 | path 168 | PopoverExampleObjc.app 169 | sourceTree 170 | BUILT_PRODUCTS_DIR 171 | 172 | 011201171CB54AD3007E8F9A 173 | 174 | children 175 | 176 | 011201161CB54AD3007E8F9A 177 | 178 | isa 179 | PBXGroup 180 | name 181 | Products 182 | sourceTree 183 | <group> 184 | 185 | 011201181CB54AD3007E8F9A 186 | 187 | children 188 | 189 | 0112011C1CB54AD3007E8F9A 190 | 0112011D1CB54AD3007E8F9A 191 | 0112011F1CB54AD3007E8F9A 192 | 011201201CB54AD3007E8F9A 193 | 011201221CB54AD3007E8F9A 194 | 011201251CB54AD3007E8F9A 195 | 011201271CB54AD3007E8F9A 196 | 0112012A1CB54AD3007E8F9A 197 | 011201191CB54AD3007E8F9A 198 | 199 | isa 200 | PBXGroup 201 | path 202 | PopoverExampleObjc 203 | sourceTree 204 | <group> 205 | 206 | 011201191CB54AD3007E8F9A 207 | 208 | children 209 | 210 | 0112011A1CB54AD3007E8F9A 211 | 212 | isa 213 | PBXGroup 214 | name 215 | Supporting Files 216 | sourceTree 217 | <group> 218 | 219 | 0112011A1CB54AD3007E8F9A 220 | 221 | isa 222 | PBXFileReference 223 | lastKnownFileType 224 | sourcecode.c.objc 225 | path 226 | main.m 227 | sourceTree 228 | <group> 229 | 230 | 0112011B1CB54AD3007E8F9A 231 | 232 | fileRef 233 | 0112011A1CB54AD3007E8F9A 234 | isa 235 | PBXBuildFile 236 | 237 | 0112011C1CB54AD3007E8F9A 238 | 239 | isa 240 | PBXFileReference 241 | lastKnownFileType 242 | sourcecode.c.h 243 | path 244 | AppDelegate.h 245 | sourceTree 246 | <group> 247 | 248 | 0112011D1CB54AD3007E8F9A 249 | 250 | isa 251 | PBXFileReference 252 | lastKnownFileType 253 | sourcecode.c.objc 254 | path 255 | AppDelegate.m 256 | sourceTree 257 | <group> 258 | 259 | 0112011E1CB54AD3007E8F9A 260 | 261 | fileRef 262 | 0112011D1CB54AD3007E8F9A 263 | isa 264 | PBXBuildFile 265 | 266 | 0112011F1CB54AD3007E8F9A 267 | 268 | isa 269 | PBXFileReference 270 | lastKnownFileType 271 | sourcecode.c.h 272 | path 273 | ViewController.h 274 | sourceTree 275 | <group> 276 | 277 | 011201201CB54AD3007E8F9A 278 | 279 | isa 280 | PBXFileReference 281 | lastKnownFileType 282 | sourcecode.c.objc 283 | path 284 | ViewController.m 285 | sourceTree 286 | <group> 287 | 288 | 011201211CB54AD3007E8F9A 289 | 290 | fileRef 291 | 011201201CB54AD3007E8F9A 292 | isa 293 | PBXBuildFile 294 | 295 | 011201221CB54AD3007E8F9A 296 | 297 | children 298 | 299 | 011201231CB54AD3007E8F9A 300 | 301 | isa 302 | PBXVariantGroup 303 | name 304 | Main.storyboard 305 | sourceTree 306 | <group> 307 | 308 | 011201231CB54AD3007E8F9A 309 | 310 | isa 311 | PBXFileReference 312 | lastKnownFileType 313 | file.storyboard 314 | name 315 | Base 316 | path 317 | Base.lproj/Main.storyboard 318 | sourceTree 319 | <group> 320 | 321 | 011201241CB54AD3007E8F9A 322 | 323 | fileRef 324 | 011201221CB54AD3007E8F9A 325 | isa 326 | PBXBuildFile 327 | 328 | 011201251CB54AD3007E8F9A 329 | 330 | isa 331 | PBXFileReference 332 | lastKnownFileType 333 | folder.assetcatalog 334 | path 335 | Assets.xcassets 336 | sourceTree 337 | <group> 338 | 339 | 011201261CB54AD3007E8F9A 340 | 341 | fileRef 342 | 011201251CB54AD3007E8F9A 343 | isa 344 | PBXBuildFile 345 | 346 | 011201271CB54AD3007E8F9A 347 | 348 | children 349 | 350 | 011201281CB54AD3007E8F9A 351 | 352 | isa 353 | PBXVariantGroup 354 | name 355 | LaunchScreen.storyboard 356 | sourceTree 357 | <group> 358 | 359 | 011201281CB54AD3007E8F9A 360 | 361 | isa 362 | PBXFileReference 363 | lastKnownFileType 364 | file.storyboard 365 | name 366 | Base 367 | path 368 | Base.lproj/LaunchScreen.storyboard 369 | sourceTree 370 | <group> 371 | 372 | 011201291CB54AD3007E8F9A 373 | 374 | fileRef 375 | 011201271CB54AD3007E8F9A 376 | isa 377 | PBXBuildFile 378 | 379 | 0112012A1CB54AD3007E8F9A 380 | 381 | isa 382 | PBXFileReference 383 | lastKnownFileType 384 | text.plist.xml 385 | path 386 | Info.plist 387 | sourceTree 388 | <group> 389 | 390 | 0112012B1CB54AD3007E8F9A 391 | 392 | buildSettings 393 | 394 | ALWAYS_SEARCH_USER_PATHS 395 | NO 396 | CLANG_ANALYZER_NONNULL 397 | YES 398 | CLANG_CXX_LANGUAGE_STANDARD 399 | gnu++0x 400 | CLANG_CXX_LIBRARY 401 | libc++ 402 | CLANG_ENABLE_MODULES 403 | YES 404 | CLANG_ENABLE_OBJC_ARC 405 | YES 406 | CLANG_WARN_BOOL_CONVERSION 407 | YES 408 | CLANG_WARN_CONSTANT_CONVERSION 409 | YES 410 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE 411 | YES_ERROR 412 | CLANG_WARN_EMPTY_BODY 413 | YES 414 | CLANG_WARN_ENUM_CONVERSION 415 | YES 416 | CLANG_WARN_INT_CONVERSION 417 | YES 418 | CLANG_WARN_OBJC_ROOT_CLASS 419 | YES_ERROR 420 | CLANG_WARN_UNREACHABLE_CODE 421 | YES 422 | CLANG_WARN__DUPLICATE_METHOD_MATCH 423 | YES 424 | CODE_SIGN_IDENTITY[sdk=iphoneos*] 425 | iPhone Developer 426 | COPY_PHASE_STRIP 427 | NO 428 | DEBUG_INFORMATION_FORMAT 429 | dwarf 430 | ENABLE_STRICT_OBJC_MSGSEND 431 | YES 432 | ENABLE_TESTABILITY 433 | YES 434 | GCC_C_LANGUAGE_STANDARD 435 | gnu99 436 | GCC_DYNAMIC_NO_PIC 437 | NO 438 | GCC_NO_COMMON_BLOCKS 439 | YES 440 | GCC_OPTIMIZATION_LEVEL 441 | 0 442 | GCC_PREPROCESSOR_DEFINITIONS 443 | 444 | DEBUG=1 445 | $(inherited) 446 | 447 | GCC_WARN_64_TO_32_BIT_CONVERSION 448 | YES 449 | GCC_WARN_ABOUT_RETURN_TYPE 450 | YES_ERROR 451 | GCC_WARN_UNDECLARED_SELECTOR 452 | YES 453 | GCC_WARN_UNINITIALIZED_AUTOS 454 | YES_AGGRESSIVE 455 | GCC_WARN_UNUSED_FUNCTION 456 | YES 457 | GCC_WARN_UNUSED_VARIABLE 458 | YES 459 | IPHONEOS_DEPLOYMENT_TARGET 460 | 9.3 461 | MTL_ENABLE_DEBUG_INFO 462 | YES 463 | ONLY_ACTIVE_ARCH 464 | YES 465 | SDKROOT 466 | iphoneos 467 | TARGETED_DEVICE_FAMILY 468 | 1,2 469 | 470 | isa 471 | XCBuildConfiguration 472 | name 473 | Debug 474 | 475 | 0112012C1CB54AD3007E8F9A 476 | 477 | buildSettings 478 | 479 | ALWAYS_SEARCH_USER_PATHS 480 | NO 481 | CLANG_ANALYZER_NONNULL 482 | YES 483 | CLANG_CXX_LANGUAGE_STANDARD 484 | gnu++0x 485 | CLANG_CXX_LIBRARY 486 | libc++ 487 | CLANG_ENABLE_MODULES 488 | YES 489 | CLANG_ENABLE_OBJC_ARC 490 | YES 491 | CLANG_WARN_BOOL_CONVERSION 492 | YES 493 | CLANG_WARN_CONSTANT_CONVERSION 494 | YES 495 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE 496 | YES_ERROR 497 | CLANG_WARN_EMPTY_BODY 498 | YES 499 | CLANG_WARN_ENUM_CONVERSION 500 | YES 501 | CLANG_WARN_INT_CONVERSION 502 | YES 503 | CLANG_WARN_OBJC_ROOT_CLASS 504 | YES_ERROR 505 | CLANG_WARN_UNREACHABLE_CODE 506 | YES 507 | CLANG_WARN__DUPLICATE_METHOD_MATCH 508 | YES 509 | CODE_SIGN_IDENTITY[sdk=iphoneos*] 510 | iPhone Developer 511 | COPY_PHASE_STRIP 512 | NO 513 | DEBUG_INFORMATION_FORMAT 514 | dwarf-with-dsym 515 | ENABLE_NS_ASSERTIONS 516 | NO 517 | ENABLE_STRICT_OBJC_MSGSEND 518 | YES 519 | GCC_C_LANGUAGE_STANDARD 520 | gnu99 521 | GCC_NO_COMMON_BLOCKS 522 | YES 523 | GCC_WARN_64_TO_32_BIT_CONVERSION 524 | YES 525 | GCC_WARN_ABOUT_RETURN_TYPE 526 | YES_ERROR 527 | GCC_WARN_UNDECLARED_SELECTOR 528 | YES 529 | GCC_WARN_UNINITIALIZED_AUTOS 530 | YES_AGGRESSIVE 531 | GCC_WARN_UNUSED_FUNCTION 532 | YES 533 | GCC_WARN_UNUSED_VARIABLE 534 | YES 535 | IPHONEOS_DEPLOYMENT_TARGET 536 | 9.3 537 | MTL_ENABLE_DEBUG_INFO 538 | NO 539 | SDKROOT 540 | iphoneos 541 | TARGETED_DEVICE_FAMILY 542 | 1,2 543 | VALIDATE_PRODUCT 544 | YES 545 | 546 | isa 547 | XCBuildConfiguration 548 | name 549 | Release 550 | 551 | 0112012D1CB54AD3007E8F9A 552 | 553 | buildConfigurations 554 | 555 | 0112012E1CB54AD3007E8F9A 556 | 0112012F1CB54AD3007E8F9A 557 | 558 | defaultConfigurationIsVisible 559 | 0 560 | isa 561 | XCConfigurationList 562 | 563 | 0112012E1CB54AD3007E8F9A 564 | 565 | baseConfigurationReference 566 | 2C2A2C24E81D6988535D4E5A 567 | buildSettings 568 | 569 | ASSETCATALOG_COMPILER_APPICON_NAME 570 | AppIcon 571 | INFOPLIST_FILE 572 | PopoverExampleObjc/Info.plist 573 | LD_RUNPATH_SEARCH_PATHS 574 | $(inherited) @executable_path/Frameworks 575 | PRODUCT_BUNDLE_IDENTIFIER 576 | org.cocoapods.demo.PopoverExampleObjc 577 | PRODUCT_NAME 578 | $(TARGET_NAME) 579 | 580 | isa 581 | XCBuildConfiguration 582 | name 583 | Debug 584 | 585 | 0112012F1CB54AD3007E8F9A 586 | 587 | baseConfigurationReference 588 | F38FA851A4ADCE92047CADEC 589 | buildSettings 590 | 591 | ASSETCATALOG_COMPILER_APPICON_NAME 592 | AppIcon 593 | INFOPLIST_FILE 594 | PopoverExampleObjc/Info.plist 595 | LD_RUNPATH_SEARCH_PATHS 596 | $(inherited) @executable_path/Frameworks 597 | PRODUCT_BUNDLE_IDENTIFIER 598 | org.cocoapods.demo.PopoverExampleObjc 599 | PRODUCT_NAME 600 | $(TARGET_NAME) 601 | 602 | isa 603 | XCBuildConfiguration 604 | name 605 | Release 606 | 607 | 152E7D34FD1DFF38F1667F26 608 | 609 | buildActionMask 610 | 2147483647 611 | files 612 | 613 | inputPaths 614 | 615 | isa 616 | PBXShellScriptBuildPhase 617 | name 618 | Copy Pods Resources 619 | outputPaths 620 | 621 | runOnlyForDeploymentPostprocessing 622 | 0 623 | shellPath 624 | /bin/sh 625 | shellScript 626 | "${SRCROOT}/Pods/Target Support Files/Pods-PopoverExampleObjc/Pods-PopoverExampleObjc-resources.sh" 627 | 628 | showEnvVarsInLog 629 | 0 630 | 631 | 2C2A2C24E81D6988535D4E5A 632 | 633 | includeInIndex 634 | 1 635 | isa 636 | PBXFileReference 637 | lastKnownFileType 638 | text.xcconfig 639 | name 640 | Pods-PopoverExampleObjc.debug.xcconfig 641 | path 642 | Pods/Target Support Files/Pods-PopoverExampleObjc/Pods-PopoverExampleObjc.debug.xcconfig 643 | sourceTree 644 | <group> 645 | 646 | 4EA91790460316EC172E1238 647 | 648 | fileRef 649 | D1B62356738482C1E9F0404D 650 | isa 651 | PBXBuildFile 652 | 653 | BE6E6066048B6A04661F49F1 654 | 655 | children 656 | 657 | 2C2A2C24E81D6988535D4E5A 658 | F38FA851A4ADCE92047CADEC 659 | 660 | isa 661 | PBXGroup 662 | name 663 | Pods 664 | sourceTree 665 | <group> 666 | 667 | D1B62356738482C1E9F0404D 668 | 669 | explicitFileType 670 | wrapper.framework 671 | includeInIndex 672 | 0 673 | isa 674 | PBXFileReference 675 | path 676 | Pods_PopoverExampleObjc.framework 677 | sourceTree 678 | BUILT_PRODUCTS_DIR 679 | 680 | D8E052B333F738D9DB5F71CA 681 | 682 | children 683 | 684 | D1B62356738482C1E9F0404D 685 | 686 | isa 687 | PBXGroup 688 | name 689 | Frameworks 690 | sourceTree 691 | <group> 692 | 693 | E7AAA46C00E084BBD47D685F 694 | 695 | buildActionMask 696 | 2147483647 697 | files 698 | 699 | inputPaths 700 | 701 | isa 702 | PBXShellScriptBuildPhase 703 | name 704 | Embed Pods Frameworks 705 | outputPaths 706 | 707 | runOnlyForDeploymentPostprocessing 708 | 0 709 | shellPath 710 | /bin/sh 711 | shellScript 712 | "${SRCROOT}/Pods/Target Support Files/Pods-PopoverExampleObjc/Pods-PopoverExampleObjc-frameworks.sh" 713 | 714 | showEnvVarsInLog 715 | 0 716 | 717 | EE20AB4564DCF82EA75025F3 718 | 719 | buildActionMask 720 | 2147483647 721 | files 722 | 723 | inputPaths 724 | 725 | isa 726 | PBXShellScriptBuildPhase 727 | name 728 | Check Pods Manifest.lock 729 | outputPaths 730 | 731 | runOnlyForDeploymentPostprocessing 732 | 0 733 | shellPath 734 | /bin/sh 735 | shellScript 736 | diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null 737 | if [[ $? != 0 ]] ; then 738 | cat << EOM 739 | error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. 740 | EOM 741 | exit 1 742 | fi 743 | 744 | showEnvVarsInLog 745 | 0 746 | 747 | F38FA851A4ADCE92047CADEC 748 | 749 | includeInIndex 750 | 1 751 | isa 752 | PBXFileReference 753 | lastKnownFileType 754 | text.xcconfig 755 | name 756 | Pods-PopoverExampleObjc.release.xcconfig 757 | path 758 | Pods/Target Support Files/Pods-PopoverExampleObjc/Pods-PopoverExampleObjc.release.xcconfig 759 | sourceTree 760 | <group> 761 | 762 | 763 | rootObject 764 | 0112010E1CB54AD3007E8F9A 765 | 766 | 767 | -------------------------------------------------------------------------------- /Classes/Popover.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Popover.swift 3 | // Popover 4 | // 5 | // Created by corin8823 on 8/16/15. 6 | // Copyright (c) 2015 corin8823. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | public enum PopoverOption { 13 | case arrowSize(CGSize) 14 | case animationIn(TimeInterval) 15 | case animationOut(TimeInterval) 16 | case cornerRadius(CGFloat) 17 | case sideEdge(CGFloat) 18 | case blackOverlayColor(UIColor) 19 | case overlayBlur(UIBlurEffect.Style) 20 | case type(PopoverType) 21 | case color(UIColor) 22 | case dismissOnBlackOverlayTap(Bool) 23 | case showBlackOverlay(Bool) 24 | case springDamping(CGFloat) 25 | case initialSpringVelocity(CGFloat) 26 | case sideOffset(CGFloat) 27 | case borderColor(UIColor) 28 | } 29 | 30 | @objc public enum PopoverType: Int { 31 | case up 32 | case down 33 | case left 34 | case right 35 | case auto 36 | } 37 | 38 | @objcMembers 39 | open class Popover: UIView { 40 | 41 | // custom property 42 | open var arrowSize: CGSize = CGSize(width: 16.0, height: 10.0) 43 | open var animationIn: TimeInterval = 0.6 44 | open var animationOut: TimeInterval = 0.3 45 | open var cornerRadius: CGFloat = 6.0 46 | open var sideEdge: CGFloat = 20.0 47 | open var popoverType: PopoverType = .down 48 | open var blackOverlayColor: UIColor = UIColor(white: 0.0, alpha: 0.2) 49 | open var overlayBlur: UIBlurEffect? 50 | open var popoverColor: UIColor = UIColor.white 51 | open var dismissOnBlackOverlayTap: Bool = true 52 | open var showBlackOverlay: Bool = true 53 | open var highlightFromView: Bool = false 54 | open var highlightCornerRadius: CGFloat = 0 55 | open var springDamping: CGFloat = 0.7 56 | open var initialSpringVelocity: CGFloat = 3 57 | open var sideOffset: CGFloat = 6.0 58 | open var borderColor: UIColor? 59 | 60 | // custom closure 61 | open var willShowHandler: (() -> ())? 62 | open var willDismissHandler: (() -> ())? 63 | open var didShowHandler: (() -> ())? 64 | open var didDismissHandler: (() -> ())? 65 | 66 | public fileprivate(set) var blackOverlay: UIControl = UIControl() 67 | 68 | fileprivate var containerView: UIView! 69 | fileprivate var contentView: UIView! 70 | fileprivate var contentViewFrame: CGRect! 71 | fileprivate var arrowShowPoint: CGPoint! 72 | 73 | public init() { 74 | super.init(frame: .zero) 75 | self.backgroundColor = .clear 76 | self.accessibilityViewIsModal = true 77 | } 78 | 79 | public init(showHandler: (() -> ())?, dismissHandler: (() -> ())?) { 80 | super.init(frame: .zero) 81 | self.backgroundColor = .clear 82 | self.didShowHandler = showHandler 83 | self.didDismissHandler = dismissHandler 84 | self.accessibilityViewIsModal = true 85 | } 86 | 87 | public init(options: [PopoverOption]?, showHandler: (() -> ())? = nil, dismissHandler: (() -> ())? = nil) { 88 | super.init(frame: .zero) 89 | self.backgroundColor = .clear 90 | self.setOptions(options) 91 | self.didShowHandler = showHandler 92 | self.didDismissHandler = dismissHandler 93 | self.accessibilityViewIsModal = true 94 | } 95 | 96 | required public init?(coder aDecoder: NSCoder) { 97 | fatalError("init(coder:) has not been implemented") 98 | } 99 | 100 | override open func layoutSubviews() { 101 | super.layoutSubviews() 102 | self.contentView.frame = self.bounds 103 | } 104 | 105 | open func showAsDialog(_ contentView: UIView) { 106 | guard let rootView = UIApplication.shared.keyWindow else { 107 | return 108 | } 109 | self.showAsDialog(contentView, inView: rootView) 110 | } 111 | 112 | open func showAsDialog(_ contentView: UIView, inView: UIView) { 113 | self.arrowSize = .zero 114 | let point = CGPoint(x: inView.center.x, 115 | y: inView.center.y - contentView.frame.height / 2) 116 | self.show(contentView, point: point, inView: inView) 117 | } 118 | 119 | open func show(_ contentView: UIView, fromView: UIView) { 120 | guard let rootView = UIApplication.shared.keyWindow else { 121 | return 122 | } 123 | self.show(contentView, fromView: fromView, inView: rootView) 124 | } 125 | 126 | open func show(_ contentView: UIView, fromView: UIView, inView: UIView) { 127 | let point: CGPoint 128 | 129 | //TODO: add left/right auto 130 | if self.popoverType == .auto { 131 | if let point = fromView.superview?.convert(fromView.frame.origin, to: nil), 132 | point.y + fromView.frame.height + self.arrowSize.height + contentView.frame.height > inView.frame.height { 133 | self.popoverType = .up 134 | } else { 135 | self.popoverType = .down 136 | } 137 | } 138 | 139 | switch self.popoverType { 140 | case .up: 141 | point = inView.convert( 142 | CGPoint( 143 | x: fromView.frame.origin.x + (fromView.frame.size.width / 2), 144 | y: fromView.frame.origin.y 145 | ), from: fromView.superview) 146 | case .down, .auto: 147 | point = inView.convert( 148 | CGPoint( 149 | x: fromView.frame.origin.x + (fromView.frame.size.width / 2), 150 | y: fromView.frame.origin.y + fromView.frame.size.height 151 | ), from: fromView.superview) 152 | case .left: 153 | point = inView.convert( 154 | CGPoint(x: fromView.frame.origin.x - sideOffset, 155 | y: fromView.frame.origin.y + 0.5 * fromView.frame.height 156 | ), from: fromView.superview) 157 | case .right: 158 | point = inView.convert( 159 | CGPoint(x: fromView.frame.origin.x + fromView.frame.size.width + sideOffset, 160 | y: fromView.frame.origin.y + 0.5 * fromView.frame.height 161 | ), from: fromView.superview) 162 | } 163 | 164 | if self.highlightFromView { 165 | self.createHighlightLayer(fromView: fromView, inView: inView) 166 | } 167 | 168 | self.show(contentView, point: point, inView: inView) 169 | } 170 | 171 | open func show(_ contentView: UIView, point: CGPoint) { 172 | guard let rootView = UIApplication.shared.keyWindow else { 173 | return 174 | } 175 | self.show(contentView, point: point, inView: rootView) 176 | } 177 | 178 | open func show(_ contentView: UIView, point: CGPoint, inView: UIView) { 179 | if self.dismissOnBlackOverlayTap || self.showBlackOverlay { 180 | self.blackOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight] 181 | self.blackOverlay.frame = inView.bounds 182 | inView.addSubview(self.blackOverlay) 183 | 184 | if showBlackOverlay { 185 | if let overlayBlur = self.overlayBlur { 186 | let effectView = UIVisualEffectView(effect: overlayBlur) 187 | effectView.frame = self.blackOverlay.bounds 188 | effectView.isUserInteractionEnabled = false 189 | self.blackOverlay.addSubview(effectView) 190 | } else { 191 | if !self.highlightFromView { 192 | self.blackOverlay.backgroundColor = self.blackOverlayColor 193 | } 194 | self.blackOverlay.alpha = 0 195 | } 196 | } 197 | 198 | if self.dismissOnBlackOverlayTap { 199 | self.blackOverlay.addTarget(self, action: #selector(Popover.dismiss), for: .touchUpInside) 200 | } 201 | } 202 | 203 | self.containerView = inView 204 | self.contentView = contentView 205 | self.contentView.backgroundColor = UIColor.clear 206 | self.contentView.layer.cornerRadius = self.cornerRadius 207 | self.contentView.layer.masksToBounds = true 208 | self.arrowShowPoint = point 209 | self.show() 210 | } 211 | 212 | open override func accessibilityPerformEscape() -> Bool { 213 | self.dismiss() 214 | return true 215 | } 216 | 217 | @objc open func dismiss() { 218 | if self.superview != nil { 219 | self.willDismissHandler?() 220 | UIView.animate(withDuration: self.animationOut, delay: 0, 221 | options: UIView.AnimationOptions(), 222 | animations: { 223 | self.transform = CGAffineTransform(scaleX: 0.0001, y: 0.0001) 224 | self.blackOverlay.alpha = 0 225 | }){ _ in 226 | self.contentView.removeFromSuperview() 227 | self.blackOverlay.removeFromSuperview() 228 | self.removeFromSuperview() 229 | self.transform = CGAffineTransform.identity 230 | self.didDismissHandler?() 231 | } 232 | } 233 | } 234 | 235 | override open func draw(_ rect: CGRect) { 236 | super.draw(rect) 237 | let arrow = UIBezierPath() 238 | let color = self.popoverColor 239 | let arrowPoint = self.containerView.convert(self.arrowShowPoint, to: self) 240 | switch self.popoverType { 241 | case .up: 242 | arrow.move(to: CGPoint(x: arrowPoint.x, y: self.bounds.height)) 243 | arrow.addLine( 244 | to: CGPoint( 245 | x: arrowPoint.x - self.arrowSize.width * 0.5, 246 | y: self.isCornerLeftArrow ? self.arrowSize.height : self.bounds.height - self.arrowSize.height 247 | ) 248 | ) 249 | 250 | arrow.addLine(to: CGPoint(x: self.cornerRadius, y: self.bounds.height - self.arrowSize.height)) 251 | arrow.addArc( 252 | withCenter: CGPoint( 253 | x: self.cornerRadius, 254 | y: self.bounds.height - self.arrowSize.height - self.cornerRadius 255 | ), 256 | radius: self.cornerRadius, 257 | startAngle: self.radians(90), 258 | endAngle: self.radians(180), 259 | clockwise: true) 260 | 261 | arrow.addLine(to: CGPoint(x: 0, y: self.cornerRadius)) 262 | arrow.addArc( 263 | withCenter: CGPoint( 264 | x: self.cornerRadius, 265 | y: self.cornerRadius 266 | ), 267 | radius: self.cornerRadius, 268 | startAngle: self.radians(180), 269 | endAngle: self.radians(270), 270 | clockwise: true) 271 | 272 | arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: 0)) 273 | arrow.addArc( 274 | withCenter: CGPoint( 275 | x: self.bounds.width - self.cornerRadius, 276 | y: self.cornerRadius 277 | ), 278 | radius: self.cornerRadius, 279 | startAngle: self.radians(270), 280 | endAngle: self.radians(0), 281 | clockwise: true) 282 | 283 | arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height - self.arrowSize.height - self.cornerRadius)) 284 | arrow.addArc( 285 | withCenter: CGPoint( 286 | x: self.bounds.width - self.cornerRadius, 287 | y: self.bounds.height - self.arrowSize.height - self.cornerRadius 288 | ), 289 | radius: self.cornerRadius, 290 | startAngle: self.radians(0), 291 | endAngle: self.radians(90), 292 | clockwise: true) 293 | 294 | arrow.addLine( 295 | to: CGPoint( 296 | x: arrowPoint.x + self.arrowSize.width * 0.5, 297 | y: self.isCornerRightArrow ? self.arrowSize.height : self.bounds.height - self.arrowSize.height 298 | ) 299 | ) 300 | 301 | case .down, .auto: 302 | arrow.move(to: CGPoint(x: arrowPoint.x, y: 0)) 303 | 304 | if self.isCloseToCornerRightArrow && !self.isCornerRightArrow { 305 | if !isBehindCornerRightArrow { 306 | arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height)) 307 | arrow.addArc( 308 | withCenter: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height + self.cornerRadius), 309 | radius: self.cornerRadius, 310 | startAngle: self.radians(270.0), 311 | endAngle: self.radians(0), 312 | clockwise: true) 313 | } else { 314 | arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.arrowSize.height + self.cornerRadius)) 315 | arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.arrowSize.height)) 316 | } 317 | } else { 318 | arrow.addLine( 319 | to: CGPoint( 320 | x: self.isBehindCornerLeftArrow ? self.frame.minX - self.arrowSize.width * 0.5 : arrowPoint.x + self.arrowSize.width * 0.5, 321 | y: self.isCornerRightArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height 322 | ) 323 | ) 324 | arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height)) 325 | arrow.addArc( 326 | withCenter: CGPoint( 327 | x: self.bounds.width - self.cornerRadius, 328 | y: self.arrowSize.height + self.cornerRadius 329 | ), 330 | radius: self.cornerRadius, 331 | startAngle: self.radians(270.0), 332 | endAngle: self.radians(0), 333 | clockwise: true) 334 | } 335 | 336 | arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height - self.cornerRadius)) 337 | arrow.addArc( 338 | withCenter: CGPoint( 339 | x: self.bounds.width - self.cornerRadius, 340 | y: self.bounds.height - self.cornerRadius 341 | ), 342 | radius: self.cornerRadius, 343 | startAngle: self.radians(0), 344 | endAngle: self.radians(90), 345 | clockwise: true) 346 | 347 | arrow.addLine(to: CGPoint(x: 0, y: self.bounds.height)) 348 | arrow.addArc( 349 | withCenter: CGPoint( 350 | x: self.cornerRadius, 351 | y: self.bounds.height - self.cornerRadius 352 | ), 353 | radius: self.cornerRadius, 354 | startAngle: self.radians(90), 355 | endAngle: self.radians(180), 356 | clockwise: true) 357 | 358 | arrow.addLine(to: CGPoint(x: 0, y: self.arrowSize.height + self.cornerRadius)) 359 | 360 | if !isBehindCornerLeftArrow { 361 | arrow.addArc( 362 | withCenter: CGPoint( 363 | x: self.cornerRadius, 364 | y: self.arrowSize.height + self.cornerRadius 365 | ), 366 | radius: self.cornerRadius, 367 | startAngle: self.radians(180), 368 | endAngle: self.radians(270), 369 | clockwise: true) 370 | } 371 | 372 | if isBehindCornerRightArrow { 373 | arrow.addLine(to: CGPoint( 374 | x: self.bounds.width - self.arrowSize.width * 0.5, 375 | y: self.isCornerLeftArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height)) 376 | } else if isCloseToCornerLeftArrow && !isCornerLeftArrow { 377 | () // skipping this line in that case 378 | } else { 379 | arrow.addLine(to: CGPoint(x: arrowPoint.x - self.arrowSize.width * 0.5, 380 | y: self.isCornerLeftArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height)) 381 | } 382 | 383 | case .left: 384 | arrow.move(to: CGPoint(x: self.bounds.width, y: self.bounds.height * 0.5)) 385 | arrow.addLine( 386 | to: CGPoint( 387 | x: self.bounds.width - self.arrowSize.height, 388 | y: self.bounds.height * 0.5 + self.arrowSize.width * 0.5 389 | )) 390 | 391 | arrow.addLine(to: CGPoint(x:self.bounds.width - self.arrowSize.height, y: self.bounds.height - self.cornerRadius)) 392 | arrow.addArc( 393 | withCenter: CGPoint( 394 | x: self.bounds.width - self.arrowSize.height - self.cornerRadius, 395 | y: self.bounds.height - self.cornerRadius 396 | ), 397 | radius: self.cornerRadius, 398 | startAngle: self.radians(0.0), 399 | endAngle: self.radians(90), 400 | clockwise: true) 401 | 402 | arrow.addLine(to: CGPoint(x: self.cornerRadius, y: self.bounds.height)) 403 | arrow.addArc( 404 | withCenter: CGPoint( 405 | x: self.cornerRadius, 406 | y: self.bounds.height - self.cornerRadius 407 | ), 408 | radius: self.cornerRadius, 409 | startAngle: self.radians(90), 410 | endAngle: self.radians(180), 411 | clockwise: true) 412 | 413 | arrow.addLine(to: CGPoint(x: 0, y: self.cornerRadius)) 414 | arrow.addArc( 415 | withCenter: CGPoint( 416 | x: self.cornerRadius, 417 | y: self.cornerRadius 418 | ), 419 | radius: self.cornerRadius, 420 | startAngle: self.radians(180), 421 | endAngle: self.radians(270), 422 | clockwise: true) 423 | 424 | arrow.addLine(to: CGPoint(x: self.bounds.width - self.arrowSize.height - self.cornerRadius, y: 0)) 425 | arrow.addArc( 426 | withCenter: CGPoint(x: self.bounds.width - self.arrowSize.height - self.cornerRadius, 427 | y: self.cornerRadius 428 | ), 429 | radius: self.cornerRadius, 430 | startAngle: self.radians(270), 431 | endAngle: self.radians(0), 432 | clockwise: true) 433 | 434 | arrow.addLine(to: CGPoint(x: self.bounds.width - self.arrowSize.height, 435 | y: self.bounds.height * 0.5 - self.arrowSize.width * 0.5 436 | )) 437 | case .right: 438 | arrow.move(to: CGPoint(x: arrowPoint.x, y: self.bounds.height * 0.5)) 439 | arrow.addLine( 440 | to: CGPoint( 441 | x: arrowPoint.x + self.arrowSize.height, 442 | y: self.bounds.height * 0.5 + 0.5 * self.arrowSize.width 443 | )) 444 | 445 | arrow.addLine( 446 | to: CGPoint( 447 | x: arrowPoint.x + self.arrowSize.height, 448 | y: self.bounds.height - self.cornerRadius 449 | )) 450 | arrow.addArc( 451 | withCenter: CGPoint( 452 | x: arrowPoint.x + self.arrowSize.height + self.cornerRadius, 453 | y: self.bounds.height - self.cornerRadius 454 | ), 455 | radius: self.cornerRadius, 456 | startAngle: self.radians(180.0), 457 | endAngle: self.radians(90), 458 | clockwise: false) 459 | 460 | arrow.addLine(to: CGPoint(x: self.bounds.width + arrowPoint.x - self.cornerRadius, y: self.bounds.height)) 461 | arrow.addArc( 462 | withCenter: CGPoint( 463 | x: self.bounds.width + arrowPoint.x - self.cornerRadius, 464 | y: self.bounds.height - self.cornerRadius 465 | ), 466 | radius: self.cornerRadius, 467 | startAngle: self.radians(90), 468 | endAngle: self.radians(0), 469 | clockwise: false) 470 | 471 | arrow.addLine(to: CGPoint(x: self.bounds.width + arrowPoint.x, y: self.cornerRadius)) 472 | arrow.addArc( 473 | withCenter: CGPoint( 474 | x: self.bounds.width + arrowPoint.x - self.cornerRadius, 475 | y: self.cornerRadius 476 | ), 477 | radius: self.cornerRadius, 478 | startAngle: self.radians(0), 479 | endAngle: self.radians(-90), 480 | clockwise: false) 481 | 482 | arrow.addLine(to: CGPoint(x: arrowPoint.x + self.arrowSize.height - self.cornerRadius, y: 0)) 483 | arrow.addArc( 484 | withCenter: CGPoint(x: arrowPoint.x + self.arrowSize.height + self.cornerRadius, 485 | y: self.cornerRadius 486 | ), 487 | radius: self.cornerRadius, 488 | startAngle: self.radians(-90), 489 | endAngle: self.radians(-180), 490 | clockwise: false) 491 | 492 | arrow.addLine(to: CGPoint(x: arrowPoint.x + self.arrowSize.height, 493 | y: self.bounds.height * 0.5 - self.arrowSize.width * 0.5)) 494 | } 495 | 496 | color.setFill() 497 | arrow.fill() 498 | if let borderColor = borderColor { 499 | borderColor.setStroke() 500 | arrow.stroke() 501 | } 502 | } 503 | } 504 | 505 | private extension Popover { 506 | 507 | func setOptions(_ options: [PopoverOption]?){ 508 | if let options = options { 509 | for option in options { 510 | switch option { 511 | case let .arrowSize(value): 512 | self.arrowSize = value 513 | case let .animationIn(value): 514 | self.animationIn = value 515 | case let .animationOut(value): 516 | self.animationOut = value 517 | case let .cornerRadius(value): 518 | self.cornerRadius = value 519 | case let .sideEdge(value): 520 | self.sideEdge = value 521 | case let .blackOverlayColor(value): 522 | self.blackOverlayColor = value 523 | case let .overlayBlur(style): 524 | self.overlayBlur = UIBlurEffect(style: style) 525 | case let .type(value): 526 | self.popoverType = value 527 | case let .color(value): 528 | self.popoverColor = value 529 | case let .dismissOnBlackOverlayTap(value): 530 | self.dismissOnBlackOverlayTap = value 531 | case let .showBlackOverlay(value): 532 | self.showBlackOverlay = value 533 | case let .springDamping(value): 534 | self.springDamping = value 535 | case let .initialSpringVelocity(value): 536 | self.initialSpringVelocity = value 537 | case let .sideOffset(value): 538 | self.sideOffset = value 539 | case let .borderColor(value): 540 | self.borderColor = value 541 | } 542 | } 543 | } 544 | } 545 | 546 | func create() { 547 | var frame = self.contentView.frame 548 | 549 | switch self.popoverType { 550 | case .up, .down, .auto: 551 | frame.origin.x = self.arrowShowPoint.x - frame.size.width * 0.5 552 | case .left, .right: 553 | frame.origin.y = self.arrowShowPoint.y - frame.size.height * 0.5 554 | } 555 | 556 | var sideEdge: CGFloat = 0.0 557 | if frame.size.width < self.containerView.frame.size.width { 558 | sideEdge = self.sideEdge 559 | } 560 | 561 | let outerSideEdge = frame.maxX - self.containerView.bounds.size.width 562 | if outerSideEdge > 0 { 563 | frame.origin.x -= (outerSideEdge + sideEdge) 564 | } else { 565 | if frame.minX < 0 { 566 | frame.origin.x += abs(frame.minX) + sideEdge 567 | } 568 | } 569 | self.frame = frame 570 | 571 | let arrowPoint = self.containerView.convert(self.arrowShowPoint, to: self) 572 | var anchorPoint: CGPoint 573 | switch self.popoverType { 574 | case .up: 575 | frame.origin.y = self.arrowShowPoint.y - frame.height - self.arrowSize.height 576 | anchorPoint = CGPoint(x: arrowPoint.x / frame.size.width, y: 1) 577 | case .down, .auto: 578 | frame.origin.y = self.arrowShowPoint.y 579 | anchorPoint = CGPoint(x: arrowPoint.x / frame.size.width, y: 0) 580 | case .left: 581 | frame.origin.x = self.arrowShowPoint.x - frame.size.width - self.arrowSize.height 582 | anchorPoint = CGPoint(x: 1, y: 0.5) 583 | case .right: 584 | frame.origin.x = self.arrowShowPoint.x 585 | anchorPoint = CGPoint(x: 0, y: 0.5) 586 | } 587 | 588 | if self.arrowSize == .zero { 589 | anchorPoint = CGPoint(x: 0.5, y: 0.5) 590 | } 591 | 592 | let lastAnchor = self.layer.anchorPoint 593 | self.layer.anchorPoint = anchorPoint 594 | let x = self.layer.position.x + (anchorPoint.x - lastAnchor.x) * self.layer.bounds.size.width 595 | let y = self.layer.position.y + (anchorPoint.y - lastAnchor.y) * self.layer.bounds.size.height 596 | self.layer.position = CGPoint(x: x, y: y) 597 | 598 | switch self.popoverType { 599 | case .up, .down, .auto: 600 | frame.size.height += self.arrowSize.height 601 | case .left, .right: 602 | frame.size.width += self.arrowSize.height 603 | } 604 | 605 | self.frame = frame 606 | } 607 | 608 | func createHighlightLayer(fromView: UIView, inView: UIView) { 609 | let path = UIBezierPath(rect: inView.bounds) 610 | let highlightRect = inView.convert(fromView.frame, from: fromView.superview) 611 | let highlightPath = UIBezierPath(roundedRect: highlightRect, cornerRadius: self.highlightCornerRadius) 612 | path.append(highlightPath) 613 | path.usesEvenOddFillRule = true 614 | 615 | let fillLayer = CAShapeLayer() 616 | fillLayer.path = path.cgPath 617 | fillLayer.fillRule = CAShapeLayerFillRule.evenOdd 618 | fillLayer.fillColor = self.blackOverlayColor.cgColor 619 | self.blackOverlay.layer.addSublayer(fillLayer) 620 | } 621 | 622 | func show() { 623 | self.setNeedsDisplay() 624 | switch self.popoverType { 625 | case .up: 626 | self.contentView.frame.origin.y = 0.0 627 | case .down, .auto: 628 | self.contentView.frame.origin.y = self.arrowSize.height 629 | case .left, .right: 630 | self.contentView.frame.origin.x = 0 631 | } 632 | self.addSubview(self.contentView) 633 | self.containerView.addSubview(self) 634 | 635 | self.create() 636 | self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0) 637 | self.willShowHandler?() 638 | UIView.animate( 639 | withDuration: self.animationIn, 640 | delay: 0, 641 | usingSpringWithDamping: self.springDamping, 642 | initialSpringVelocity: self.initialSpringVelocity, 643 | options: UIView.AnimationOptions(), 644 | animations: { 645 | self.transform = CGAffineTransform.identity 646 | }){ _ in 647 | self.didShowHandler?() 648 | } 649 | UIView.animate( 650 | withDuration: self.animationIn / 3, 651 | delay: 0, 652 | options: .curveLinear, 653 | animations: { 654 | self.blackOverlay.alpha = 1 655 | }, completion: nil) 656 | } 657 | 658 | var isCloseToCornerLeftArrow: Bool { 659 | return self.arrowShowPoint.x < self.frame.origin.x + arrowSize.width/2 + cornerRadius 660 | } 661 | 662 | var isCloseToCornerRightArrow: Bool { 663 | return self.arrowShowPoint.x > (self.frame.origin.x + self.bounds.width) - arrowSize.width/2 - cornerRadius 664 | } 665 | 666 | var isCornerLeftArrow: Bool { 667 | return self.arrowShowPoint.x == self.frame.origin.x 668 | } 669 | 670 | var isCornerRightArrow: Bool { 671 | return self.arrowShowPoint.x == self.frame.origin.x + self.bounds.width 672 | } 673 | 674 | var isBehindCornerLeftArrow: Bool { 675 | return self.arrowShowPoint.x < self.frame.origin.x 676 | } 677 | 678 | var isBehindCornerRightArrow: Bool { 679 | return self.arrowShowPoint.x > self.frame.origin.x + self.bounds.width 680 | } 681 | 682 | func radians(_ degrees: CGFloat) -> CGFloat { 683 | return CGFloat.pi * degrees / 180 684 | } 685 | } 686 | -------------------------------------------------------------------------------- /Example/Popover/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 | 32 | 42 | 52 | 62 | 73 | 84 | 95 | 106 | 117 | 128 | 141 | 152 | 163 | 174 | 185 | 196 | 209 | 220 | 231 | 242 | 248 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | --------------------------------------------------------------------------------