The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .github
    ├── FUNDING.yml
    └── ISSUE_TEMPLATE
    │   ├── bug-report.yml
    │   ├── config.yml
    │   └── feature-request.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── LNPCSwiftRefinements
    └── SwiftRefinements.swift
├── LNPopupController
    ├── Info.plist
    ├── LNPopupController.h
    ├── LNPopupController.xcodeproj
    │   ├── project.pbxproj
    │   ├── project.xcworkspace
    │   │   ├── contents.xcworkspacedata
    │   │   └── xcshareddata
    │   │   │   └── IDEWorkspaceChecks.plist
    │   └── xcshareddata
    │   │   └── xcschemes
    │   │       └── LNPopupController.xcscheme
    ├── LNPopupController
    │   ├── LNPopupBar.h
    │   ├── LNPopupBarAppearance.h
    │   ├── LNPopupCloseButton.h
    │   ├── LNPopupContentView.h
    │   ├── LNPopupCustomBarViewController.h
    │   ├── LNPopupDefinitions.h
    │   ├── LNPopupImageView.h
    │   ├── LNPopupItem.h
    │   ├── Private
    │   │   ├── LNChevronView.h
    │   │   ├── LNChevronView.m
    │   │   ├── LNForwardingDelegate.h
    │   │   ├── LNForwardingDelegate.m
    │   │   ├── LNMath.h
    │   │   ├── LNMath.m
    │   │   ├── LNPopupBar+Private.h
    │   │   ├── LNPopupBar.mm
    │   │   ├── LNPopupBarAppearance+Private.h
    │   │   ├── LNPopupBarAppearance.mm
    │   │   ├── LNPopupBarAppearanceChainProxy.h
    │   │   ├── LNPopupBarAppearanceChainProxy.m
    │   │   ├── LNPopupBarExtras.mm
    │   │   ├── LNPopupCloseButton+Private.h
    │   │   ├── LNPopupCloseButton.mm
    │   │   ├── LNPopupContentView+Private.h
    │   │   ├── LNPopupContentView.m
    │   │   ├── LNPopupController.h
    │   │   ├── LNPopupController.mm
    │   │   ├── LNPopupCustomBarViewController+Private.h
    │   │   ├── LNPopupCustomBarViewController.m
    │   │   ├── LNPopupDebug.h
    │   │   ├── LNPopupDebug.m
    │   │   ├── LNPopupImageView+Private.h
    │   │   ├── LNPopupImageView.mm
    │   │   ├── LNPopupInteractionPanGestureRecognizer.h
    │   │   ├── LNPopupInteractionPanGestureRecognizer.m
    │   │   ├── LNPopupItem+Private.h
    │   │   ├── LNPopupItem.m
    │   │   ├── LNPopupLongPressGestureRecognizer.h
    │   │   ├── LNPopupLongPressGestureRecognizer.m
    │   │   ├── LNPopupOpenTapGestureRecognizer.h
    │   │   ├── LNPopupOpenTapGestureRecognizer.m
    │   │   ├── LNPopupPresentationContainerSupport.h
    │   │   ├── LNPopupPresentationContainerSupport.m
    │   │   ├── MarqueeLabel.h
    │   │   ├── MarqueeLabel.m
    │   │   ├── NSAttributedString+LNPopupSupport.h
    │   │   ├── NSAttributedString+LNPopupSupport.m
    │   │   ├── UIContextMenuInteraction+LNPopupSupportPrivate.h
    │   │   ├── UIContextMenuInteraction+LNPopupSupportPrivate.mm
    │   │   ├── UIView+LNPopupSupportPrivate.h
    │   │   ├── UIView+LNPopupSupportPrivate.mm
    │   │   ├── UIViewController+LNPopupSupport.mm
    │   │   ├── UIViewController+LNPopupSupportPrivate.h
    │   │   ├── UIViewController+LNPopupSupportPrivate.mm
    │   │   ├── _LNPopupAddressInfo.h
    │   │   ├── _LNPopupAddressInfo.mm
    │   │   ├── _LNPopupBackgroundShadowView.h
    │   │   ├── _LNPopupBackgroundShadowView.m
    │   │   ├── _LNPopupBarBackgroundMaskView.h
    │   │   ├── _LNPopupBarBackgroundMaskView.m
    │   │   ├── _LNPopupBarBackgroundView.h
    │   │   ├── _LNPopupBarBackgroundView.m
    │   │   ├── _LNPopupBase64Utils.hh
    │   │   ├── _LNPopupSwizzlingUtils.h
    │   │   ├── _LNPopupSwizzlingUtils.m
    │   │   ├── _LNPopupTransitionAnimator.h
    │   │   ├── _LNPopupTransitionAnimator.mm
    │   │   ├── _LNPopupTransitionCloseAnimator.h
    │   │   ├── _LNPopupTransitionCloseAnimator.m
    │   │   ├── _LNPopupTransitionGenericCloseAnimator.h
    │   │   ├── _LNPopupTransitionGenericCloseAnimator.m
    │   │   ├── _LNPopupTransitionGenericOpenAnimator.h
    │   │   ├── _LNPopupTransitionGenericOpenAnimator.m
    │   │   ├── _LNPopupTransitionOpenAnimator.h
    │   │   ├── _LNPopupTransitionOpenAnimator.m
    │   │   ├── _LNPopupTransitionPreferredCloseAnimator.h
    │   │   ├── _LNPopupTransitionPreferredCloseAnimator.mm
    │   │   ├── _LNPopupTransitionPreferredOpenAnimator.h
    │   │   ├── _LNPopupTransitionPreferredOpenAnimator.mm
    │   │   ├── _LNPopupTransitionView.h
    │   │   ├── _LNPopupTransitionView.mm
    │   │   ├── _LNPopupUIBarAppearanceProxy.h
    │   │   ├── _LNPopupUIBarAppearanceProxy.mm
    │   │   ├── _LNWeakRef.h
    │   │   └── _LNWeakRef.m
    │   └── UIViewController+LNPopupSupport.h
    └── include
    │   └── LNPopupController
    │       ├── LNPopupBar.h
    │       ├── LNPopupBarAppearance.h
    │       ├── LNPopupCloseButton.h
    │       ├── LNPopupContentView.h
    │       ├── LNPopupController.h
    │       ├── LNPopupCustomBarViewController.h
    │       ├── LNPopupDefinitions.h
    │       ├── LNPopupImageView.h
    │       ├── LNPopupItem.h
    │       └── UIViewController+LNPopupSupport.h
├── LNPopupControllerExample
    ├── LNPopupControllerExample.xcodeproj
    │   ├── project.pbxproj
    │   ├── project.xcworkspace
    │   │   ├── contents.xcworkspacedata
    │   │   └── xcshareddata
    │   │   │   └── IDEWorkspaceChecks.plist
    │   └── xcshareddata
    │   │   └── xcschemes
    │   │       ├── LNPopupControllerExample.xcscheme
    │   │       └── LNPopupControllerExampleNoPopup.xcscheme
    └── LNPopupControllerExample
    │   ├── CustomBarScene
    │       ├── Base.lproj
    │       │   └── MapScene.storyboard
    │       ├── CustomMapBarViewController.swift
    │       ├── LocationsController.swift
    │       └── MapViewController.swift
    │   ├── CustomBarScene_ManualLayout
    │       ├── Base.lproj
    │       │   └── ManualLayoutScene.storyboard
    │       └── ManualLayoutCustomBarViewController.swift
    │   ├── Info.plist
    │   ├── LNPopupControllerExample.entitlements
    │   ├── LNPopupControllerExampleNoPopup-Info.plist
    │   ├── MusicScene
    │       ├── Base.lproj
    │       │   └── Music.storyboard
    │       ├── DemoAlbumTableViewController.swift
    │       ├── DemoMusicPlayerController.swift
    │       ├── MusicCell.swift
    │       └── PortraitTabBarController.swift
    │   ├── Settings
    │       └── Base.lproj
    │       │   └── Settings.storyboard
    │   ├── Supporting
    │       ├── AppDelegate.h
    │       ├── AppDelegate.m
    │       ├── Assets.xcassets
    │       │   ├── AccentColor.colorset
    │       │   │   └── Contents.json
    │       │   ├── AppIcon.appiconset
    │       │   │   ├── Contents.json
    │       │   │   ├── Icon-dark.png
    │       │   │   ├── Icon-tinted.png
    │       │   │   └── icon_1024.png
    │       │   ├── AppIconPopupBar.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── Icon-dark.png
    │       │   │   └── icon_1024.png
    │       │   ├── Contents.json
    │       │   ├── demoAlbum.imageset
    │       │   │   ├── Contents.json
    │       │   │   └── smackandtoss-blue-orange-abstract-fog-ipad-wallpaper.jpg
    │       │   ├── gears.imageset
    │       │   │   ├── Contents.json
    │       │   │   └── gears.pdf
    │       │   ├── genre1.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-80s-hits.png
    │       │   │   ├── genre-image-80s-hits@2x.png
    │       │   │   └── genre-image-80s-hits@3x.png
    │       │   ├── genre10.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-country-hits.png
    │       │   │   ├── genre-image-country-hits@2x.png
    │       │   │   └── genre-image-country-hits@3x.png
    │       │   ├── genre11.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-dance.png
    │       │   │   ├── genre-image-dance@2x.png
    │       │   │   └── genre-image-dance@3x.png
    │       │   ├── genre12.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-decades.png
    │       │   │   ├── genre-image-decades@2x.png
    │       │   │   └── genre-image-decades@3x.png
    │       │   ├── genre13.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-electronic.png
    │       │   │   ├── genre-image-electronic@2x.png
    │       │   │   └── genre-image-electronic@3x.png
    │       │   ├── genre14.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-gospel.png
    │       │   │   ├── genre-image-gospel@2x.png
    │       │   │   └── genre-image-gospel@3x.png
    │       │   ├── genre15.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-hip-hop.png
    │       │   │   ├── genre-image-hip-hop@2x.png
    │       │   │   └── genre-image-hip-hop@3x.png
    │       │   ├── genre16.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-indie.png
    │       │   │   ├── genre-image-indie@2x.png
    │       │   │   └── genre-image-indie@3x.png
    │       │   ├── genre17-expanded.imageset
    │       │   │   ├── Contents.json
    │       │   │   └── genre-image-jazz-expanded.jpg
    │       │   ├── genre17.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-jazz.png
    │       │   │   ├── genre-image-jazz@2x.png
    │       │   │   └── genre-image-jazz@3x.png
    │       │   ├── genre18.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-kids-and-family.png
    │       │   │   ├── genre-image-kids-and-family@2x.png
    │       │   │   └── genre-image-kids-and-family@3x.png
    │       │   ├── genre19.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-latin-hits.png
    │       │   │   ├── genre-image-latin-hits@2x.png
    │       │   │   └── genre-image-latin-hits@3x.png
    │       │   ├── genre2.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-alternative.png
    │       │   │   ├── genre-image-alternative@2x.png
    │       │   │   └── genre-image-alternative@3x.png
    │       │   ├── genre20.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-metal.png
    │       │   │   ├── genre-image-metal@2x.png
    │       │   │   └── genre-image-metal@3x.png
    │       │   ├── genre21.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-modern-rock.png
    │       │   │   ├── genre-image-modern-rock@2x.png
    │       │   │   └── genre-image-modern-rock@3x.png
    │       │   ├── genre22.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-pop-gold.png
    │       │   │   ├── genre-image-pop-gold@2x.png
    │       │   │   └── genre-image-pop-gold@3x.png
    │       │   ├── genre23.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-pop-hits.png
    │       │   │   ├── genre-image-pop-hits@2x.png
    │       │   │   └── genre-image-pop-hits@3x.png
    │       │   ├── genre24.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-randb.png
    │       │   │   ├── genre-image-randb@2x.png
    │       │   │   └── genre-image-randb@3x.png
    │       │   ├── genre25.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-reggae.png
    │       │   │   ├── genre-image-reggae@2x.png
    │       │   │   └── genre-image-reggae@3x.png
    │       │   ├── genre26.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-regional-mexican.png
    │       │   │   ├── genre-image-regional-mexican@2x.png
    │       │   │   └── genre-image-regional-mexican@3x.png
    │       │   ├── genre27.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-singer-songwriter.png
    │       │   │   ├── genre-image-singer-songwriter@2x.png
    │       │   │   └── genre-image-singer-songwriter@3x.png
    │       │   ├── genre28.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-smooth-jazz.png
    │       │   │   ├── genre-image-smooth-jazz@2x.png
    │       │   │   └── genre-image-smooth-jazz@3x.png
    │       │   ├── genre29.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-smooth-pop.png
    │       │   │   ├── genre-image-smooth-pop@2x.png
    │       │   │   └── genre-image-smooth-pop@3x.png
    │       │   ├── genre3.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-blues.png
    │       │   │   ├── genre-image-blues@2x.png
    │       │   │   └── genre-image-blues@3x.png
    │       │   ├── genre30.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-world-hits.png
    │       │   │   ├── genre-image-world-hits@2x.png
    │       │   │   └── genre-image-world-hits@3x.png
    │       │   ├── genre4.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-christian.png
    │       │   │   ├── genre-image-christian@2x.png
    │       │   │   └── genre-image-christian@3x.png
    │       │   ├── genre5.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-classic-alt.png
    │       │   │   ├── genre-image-classic-alt@2x.png
    │       │   │   └── genre-image-classic-alt@3x.png
    │       │   ├── genre6.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-classic-country.png
    │       │   │   ├── genre-image-classic-country@2x.png
    │       │   │   └── genre-image-classic-country@3x.png
    │       │   ├── genre7.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-classic-randb.png
    │       │   │   ├── genre-image-classic-randb@2x.png
    │       │   │   └── genre-image-classic-randb@3x.png
    │       │   ├── genre8.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-classic-rock.png
    │       │   │   ├── genre-image-classic-rock@2x.png
    │       │   │   └── genre-image-classic-rock@3x.png
    │       │   ├── genre9.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre-image-classical.png
    │       │   │   ├── genre-image-classical@2x.png
    │       │   │   └── genre-image-classical@3x.png
    │       │   ├── genre_white.imageset
    │       │   │   ├── Contents.json
    │       │   │   ├── genre_black.png
    │       │   │   └── genre_white.png
    │       │   └── statusBarMask.imageset
    │       │   │   ├── Contents.json
    │       │   │   └── mask.png
    │       ├── LNPopupControllerExample-Bridging-Header.h
    │       ├── LaunchScreen.storyboard
    │       ├── SceneDelegate.h
    │       ├── SceneDelegate.m
    │       └── main.m
    │   ├── TestingScene
    │       ├── Base.lproj
    │       │   └── Main.storyboard
    │       ├── DemoGallery.h
    │       ├── DemoGallery.m
    │       ├── DemoPopupContentViewController.h
    │       ├── DemoPopupContentViewController.m
    │       ├── DemoViewController.h
    │       ├── DemoViewController.m
    │       ├── IntroWebViewController.h
    │       ├── IntroWebViewController.m
    │       ├── LNPopupControllerExampleSupport.h
    │       ├── LNPopupControllerExampleSupport.m
    │       ├── LNPopupDemoContextMenuInteraction.h
    │       ├── LNPopupDemoContextMenuInteraction.m
    │       ├── LNSplitViewController.h
    │       ├── LNSplitViewController.m
    │       ├── PageCardViewController.swift
    │       ├── ScrollingColorsPageViewController.swift
    │       ├── ScrollingColorsViewController.swift
    │       └── ScrollingMapViewController.swift
    │   └── Utils
    │       ├── RandomColors.h
    │       ├── RandomColors.m
    │       ├── SafeSystemImages.h
    │       └── SafeSystemImages.m
├── Package.swift
├── README.md
├── Supplements
    ├── Artwork.png
    ├── Icon-dark.psd
    ├── Icon.psd
    ├── close_button_chevron.png
    ├── close_button_none.png
    ├── close_button_round.png
    ├── compact_custom.png
    ├── custom_bar.png
    ├── default_bar_accessibility_label.png
    ├── floating_bar_style.gif
    ├── floating_custom.png
    ├── floating_no_scroll.gif
    ├── hidesBottomBar_TabBar.gif
    ├── hidesBottomBar_Toolbar.gif
    ├── interaction_drag.gif
    ├── interaction_snap.gif
    ├── modern_custom.png
    ├── modern_no_scroll.gif
    ├── open_floating_popup.gif
    ├── pointer_interaction.gif
    ├── popup_bar_context_menu.png
    ├── popup_transitions.gif
    ├── progress_view_bottom.png
    ├── progress_view_none.png
    ├── progress_view_top.png
    ├── rtl_english.png
    ├── rtl_hebrew.png
    ├── scroll.gif
    ├── scroll_edge_appearance.gif
    ├── statusbar_hidden.gif
    ├── statusbar_style.gif
    ├── tab_bar_sidebar_floating.gif
    ├── tab_bar_sidebar_landscape_floating.png
    └── tab_bar_sidebar_prominent.gif
├── releaseVersion.sh
└── update_copyright.sh


/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 | github: LeoNatan
3 | custom: ['paypal.me/LeoNatan25']
4 | 


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.yml:
--------------------------------------------------------------------------------
 1 | name: "Bug Report"
 2 | description: "Report an issue."
 3 | labels: [bug]
 4 | body:
 5 |   - type: textarea
 6 |     attributes:
 7 |       label: "Describe the Bug:"
 8 |       description: "A clear and concise description of what the bug is."
 9 |     validations:
10 |       required: true
11 |   - type: textarea
12 |     attributes:
13 |       label: "Reproduction:"
14 |       description: "Steps to reproduce the behavior."
15 |       placeholder: |
16 |         1. Go to '...'
17 |         2. Click on '....'
18 |         3. Scroll down to '....'
19 |         4. See error
20 |     validations:
21 |       required: true
22 |   - type: textarea
23 |     attributes:
24 |       label: "Expected Behavior:"
25 |       description: "A clear and concise description of what you expected to happen."
26 |     validations:
27 |       required: true
28 |   - type: textarea
29 |     attributes:
30 |       label: "Screenshots and/or Videos:"
31 |       description: "If applicable, add screenshots and/or videos to help explain your problem."
32 |       placeholder: "Drag and drop files here"
33 |     validations:
34 |       required: false
35 |   - type: textarea
36 |     attributes:
37 |       label: "Additional Context:"
38 |       description: "Add any other context about the problem here."
39 |     validations:
40 |       required: false


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 |   - name: Ask a Question
4 |     url:  https://github.com/LeoNatan/LNPopupController/discussions/new/choose
5 |     about: Please ask questions in Discussions


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.yml:
--------------------------------------------------------------------------------
 1 | name: "Feature Request"
 2 | description: "Suggest an idea for this project."
 3 | labels: [enhancement]
 4 | body:
 5 |   - type: textarea
 6 |     attributes:
 7 |       label: "Describe the Solution You'd Like:"
 8 |       description: "A clear and concise description of what you want to happen."
 9 |     validations:
10 |       required: true
11 |   - type: textarea
12 |     attributes:
13 |       label: "Describe Alternatives You've Considered:"
14 |       description: "A clear and concise description of any alternative solutions or features you've considered."
15 |     validations:
16 |       required: false
17 |   - type: textarea
18 |     attributes:
19 |       label: "Additional Context:"
20 |       description: "Add any other context or screenshots about the feature request here."
21 |     validations:
22 |       required: true
23 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | # Xcode
 2 | #
 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
 4 | 
 5 | ## Build generated
 6 | build/
 7 | DerivedData/
 8 | 
 9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 | 
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 | 
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 | 
31 | # CocoaPods
32 | #
33 | # We recommend against adding the Pods directory to your .gitignore. However
34 | # you should judge for yourself, the pros and cons are mentioned at:
35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
36 | #
37 | # Pods/
38 | 
39 | # Carthage
40 | #
41 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
42 | # Carthage/Checkouts
43 | 
44 | Carthage/Build
45 | 
46 | # fastlane
47 | #
48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
49 | # screenshots whenever they are needed.
50 | # For more information about the recommended setup visit:
51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
52 | 
53 | fastlane/report.xml
54 | fastlane/Preview.html
55 | fastlane/screenshots
56 | fastlane/test_output
57 | 
58 | # Code Injection
59 | #
60 | # After new code Injection tools there's a generated folder /iOSInjectionProject
61 | # https://github.com/johnno1962/injectionforxcode
62 | 
63 | iOSInjectionProject/
64 | .swiftpm
65 | swiftpm
66 | _tmp_release_notes.md


--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "LNPopupSettings"]
2 | 	path = LNPopupSettings
3 | 	url = https://LeoNatan@github.com/LeoNatan/LNPopupSettings.git
4 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2015-2024 Léo Natan
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 
23 | 


--------------------------------------------------------------------------------
/LNPopupController/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CFBundleExecutable</key>
 6 | 	<string>$(EXECUTABLE_NAME)</string>
 7 | 	<key>CFBundleIdentifier</key>
 8 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
 9 | 	<key>CFBundlePackageType</key>
10 | 	<string>FMWK</string>
11 | 	<key>CFBundleShortVersionString</key>
12 | 	<string>3.0.7</string>
13 | 	<key>CFBundleVersion</key>
14 | 	<string>1</string>
15 | 	<key>LSRequiresIPhoneOS</key>
16 | 	<true/>
17 | </dict>
18 | </plist>
19 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupController.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <LNPopupController/LNPopupDefinitions.h>
10 | #import <LNPopupController/LNPopupContentView.h>
11 | #import <LNPopupController/LNPopupCloseButton.h>
12 | #import <LNPopupController/LNPopupItem.h>
13 | #import <LNPopupController/LNPopupBar.h>
14 | #import <LNPopupController/LNPopupCustomBarViewController.h>
15 | #import <LNPopupController/UIViewController+LNPopupSupport.h>
16 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 |    version = "1.0">
4 |    <FileRef
5 |       location = "self:">
6 |    </FileRef>
7 | </Workspace>
8 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | 	<key>IDEDidComputeMac32BitWarning</key>
6 | 	<true/>
7 | </dict>
8 | </plist>
9 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController.xcodeproj/xcshareddata/xcschemes/LNPopupController.xcscheme:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <Scheme
 3 |    LastUpgradeVersion = "9999"
 4 |    version = "1.3">
 5 |    <BuildAction
 6 |       parallelizeBuildables = "YES"
 7 |       buildImplicitDependencies = "YES">
 8 |       <BuildActionEntries>
 9 |          <BuildActionEntry
10 |             buildForTesting = "YES"
11 |             buildForRunning = "YES"
12 |             buildForProfiling = "YES"
13 |             buildForArchiving = "YES"
14 |             buildForAnalyzing = "YES">
15 |             <BuildableReference
16 |                BuildableIdentifier = "primary"
17 |                BlueprintIdentifier = "39DB52E41B5823330061C589"
18 |                BuildableName = "LNPopupController.framework"
19 |                BlueprintName = "LNPopupController"
20 |                ReferencedContainer = "container:LNPopupController.xcodeproj">
21 |             </BuildableReference>
22 |          </BuildActionEntry>
23 |       </BuildActionEntries>
24 |    </BuildAction>
25 |    <TestAction
26 |       buildConfiguration = "Debug"
27 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29 |       shouldUseLaunchSchemeArgsEnv = "YES">
30 |       <Testables>
31 |       </Testables>
32 |    </TestAction>
33 |    <LaunchAction
34 |       buildConfiguration = "Debug"
35 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37 |       launchStyle = "0"
38 |       useCustomWorkingDirectory = "NO"
39 |       ignoresPersistentStateOnLaunch = "NO"
40 |       debugDocumentVersioning = "YES"
41 |       debugServiceExtension = "internal"
42 |       allowLocationSimulation = "YES">
43 |       <MacroExpansion>
44 |          <BuildableReference
45 |             BuildableIdentifier = "primary"
46 |             BlueprintIdentifier = "39DB52E41B5823330061C589"
47 |             BuildableName = "LNPopupController.framework"
48 |             BlueprintName = "LNPopupController"
49 |             ReferencedContainer = "container:LNPopupController.xcodeproj">
50 |          </BuildableReference>
51 |       </MacroExpansion>
52 |    </LaunchAction>
53 |    <ProfileAction
54 |       buildConfiguration = "Release"
55 |       shouldUseLaunchSchemeArgsEnv = "YES"
56 |       savedToolIdentifier = ""
57 |       useCustomWorkingDirectory = "NO"
58 |       debugDocumentVersioning = "YES">
59 |       <MacroExpansion>
60 |          <BuildableReference
61 |             BuildableIdentifier = "primary"
62 |             BlueprintIdentifier = "39DB52E41B5823330061C589"
63 |             BuildableName = "LNPopupController.framework"
64 |             BlueprintName = "LNPopupController"
65 |             ReferencedContainer = "container:LNPopupController.xcodeproj">
66 |          </BuildableReference>
67 |       </MacroExpansion>
68 |    </ProfileAction>
69 |    <AnalyzeAction
70 |       buildConfiguration = "Debug">
71 |    </AnalyzeAction>
72 |    <ArchiveAction
73 |       buildConfiguration = "Release"
74 |       revealArchiveInOrganizer = "YES">
75 |    </ArchiveAction>
76 | </Scheme>
77 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/LNPopupCloseButton.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupCloseButton.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import <LNPopupController/LNPopupDefinitions.h>
11 | 
12 | /// Available styles for the popup close button.
13 | typedef NS_ENUM(NSInteger, LNPopupCloseButtonStyle) {
14 | 	/// The default close button style for the current environment.
15 | 	LNPopupCloseButtonStyleDefault,
16 | 	
17 | 	/// Round close button style.
18 | 	LNPopupCloseButtonStyleRound,
19 | 	
20 | 	/// Chevron close button style.
21 | 	LNPopupCloseButtonStyleChevron,
22 | 	
23 | 	/// Grabber close button style.
24 | 	LNPopupCloseButtonStyleGrabber,
25 | 	
26 | 	/// No close button.
27 | 	LNPopupCloseButtonStyleNone = 0xFFFF,
28 | 	
29 | 	LNPopupCloseButtonStyleFlat LN_DEPRECATED_API("Use LNPopupCloseButtonStyle.grabber instead.") = LNPopupCloseButtonStyleGrabber
30 | } NS_SWIFT_NAME(LNPopupCloseButton.Style);
31 | 
32 | NS_ASSUME_NONNULL_BEGIN
33 | 
34 | /// The popup content close button.
35 | NS_SWIFT_UI_ACTOR
36 | @interface LNPopupCloseButton : UIButton <UIAppearanceContainer>
37 | 
38 | /// Gets or sets the style of the popup close button. Has the same effect as setting the `LNPopupContentView.popupCloseButtonStyle` property of the popup content view.
39 | @property (nonatomic, assign) LNPopupCloseButtonStyle style UI_APPEARANCE_SELECTOR;
40 | 
41 | /// The effective popup close button style used by the system. (read-only)
42 | ///
43 | /// Use this property's value to determine, at runtime, what the result of `LNPopupCloseButtonStyleDefault` is.
44 | @property (nonatomic, assign, readonly) LNPopupCloseButtonStyle effectiveStyle;
45 | 
46 | /// The button’s background view. (read-only)
47 | ///
48 | /// The value of this property will be `nil` if `style` is set to any value other than `LNPopupCloseButtonStyleRound`.
49 | ///
50 | /// @note Although this property is read-only, its own properties are read/write. Use these properties to configure the appearance and behavior of the button’s background view.
51 | @property (nonatomic, strong, readonly) UIVisualEffectView* backgroundView;
52 | 
53 | @end
54 | 
55 | NS_ASSUME_NONNULL_END
56 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/LNPopupContentView.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupItem.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2015-09-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import <LNPopupController/LNPopupDefinitions.h>
11 | #import <LNPopupController/LNPopupCloseButton.h>
12 | 
13 | NS_ASSUME_NONNULL_BEGIN
14 | 
15 | NS_SWIFT_UI_ACTOR
16 | /// Holds the popup content container view, as well as the popup close button and the popup interaction gesture recognizer.
17 | @interface LNPopupContentView : UIView <UIAppearanceContainer>
18 | 
19 | /// The gesture recognizer responsible for interactive opening and closing of the popup. (read-only)
20 | ///
21 | /// The system installs this gesture recognizer on either the popup bar or the popup content view and uses it to open or close the popup.
22 | /// Be careful with modifying this gesture recognizer. It is shared for interactively opening the popup by panning the popup bar (when it is closed), or interactively closing the popup interactively by panning the popup content view (when the popup is open). If you disable the gesture recognizer after opening the popup, you must monitor the state of the popup and reenable the gesture recognizer once closed by the user or through code.
23 | @property (nonatomic, strong, readonly) UIPanGestureRecognizer* popupInteractionGestureRecognizer;
24 | 
25 | /// The popup close button style.
26 | ///
27 | /// Defaults to `LNPopupCloseButtonStyleDefault`.
28 | @property (nonatomic, assign) LNPopupCloseButtonStyle popupCloseButtonStyle UI_APPEARANCE_SELECTOR;
29 | 
30 | /// The effective popup close button style used by the system. (read-only)
31 | ///
32 | /// Use this property's value to determine, at runtime, what the result of `LNPopupCloseButtonStyleDefault` is.
33 | @property (nonatomic, assign, readonly) LNPopupCloseButtonStyle effectivePopupCloseButtonStyle;
34 | 
35 | /// The popup close button. (read-only)
36 | @property (nonatomic, strong, readonly) LNPopupCloseButton* popupCloseButton;
37 | 
38 | /// The popup content view background effect, used when the popup content controller's view has transparency.
39 | ///
40 | /// Use `nil` value to inherit the popup bar's background effect if possible, or use a default effect.
41 | ///
42 | /// Defaults to `nil`.
43 | @property (nonatomic, copy, nullable) UIBlurEffect* backgroundEffect UI_APPEARANCE_SELECTOR;
44 | 
45 | /// A Boolean value that indicates whether the popup content view is translucent (`true`) or not (`false`).
46 | ///
47 | /// Defaults to `true`.
48 | @property(nonatomic, assign, getter=isTranslucent) BOOL translucent UI_APPEARANCE_SELECTOR;
49 | 
50 | @end
51 | 
52 | NS_ASSUME_NONNULL_END
53 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/LNPopupCustomBarViewController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupBarContentViewController.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2016-12-30.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import <LNPopupController/LNPopupDefinitions.h>
11 | 
12 | @class LNPopupBar;
13 | 
14 | NS_ASSUME_NONNULL_BEGIN
15 | 
16 | NS_SWIFT_UI_ACTOR
17 | /// An object that manages a custom popup bar view hierarchy.
18 | ///
19 | /// Implement the `UIPointerInteractionDelegate` methods to customize pointer interactions.
20 | @interface LNPopupCustomBarViewController : UIViewController <UIPointerInteractionDelegate>
21 | 
22 | /// The containing popup bar. (read-only)
23 | @property (nonatomic, weak, readonly, nullable) LNPopupBar* containingPopupBar;
24 | 
25 | /// Indicates whether the default tap gesture recognizer should be added to the popup bar.
26 | ///
27 | /// Defaults to `true`.
28 | @property (nonatomic, assign, readonly) BOOL wantsDefaultTapGestureRecognizer;
29 | 
30 | /// Indicates whether the default pan gesture recognizer should be added to the popup bar.
31 | ///
32 | /// Defaults to `true`.
33 | @property (nonatomic, assign, readonly) BOOL wantsDefaultPanGestureRecognizer;
34 | 
35 | /// Indicates whether the default highlight gesture recognizer should be added to the popup bar.
36 | ///
37 | /// Defaults to `true`.
38 | @property (nonatomic, assign, readonly) BOOL wantsDefaultHighlightGestureRecognizer;
39 | 
40 | /// The content size of the popup bar view.
41 | ///
42 | /// This property's value is used for height calculation of the popup bar. Update this property if you need to resize the popup bar.
43 | @property (nonatomic, assign) CGSize preferredContentSize;
44 | 
45 | /// Called after the view has been loaded. For view controllers created in code, this is after `loadView()`. For view controllers unarchived from a nib, this is after the view is set.
46 | - (void)viewDidLoad NS_REQUIRES_SUPER;
47 | 
48 | /// Called by the framework to notify the popup bar content view controller that one or more keys of the the popup item have been updated, or the entire popup item has changed.
49 | - (void)popupItemDidUpdate;
50 | 
51 | /// Called by the framework no notify the popup bar content view controller that the custom bar is about to move to a popup bar.
52 | ///
53 | /// - Parameter newPopupBar: The new popup bar
54 | - (void)willMoveToPopupBar:(nullable LNPopupBar*)newPopupBar;
55 | 
56 | /// Called by the framework no notify the popup bar content view controller that the custom bar has moved to a popup bar.
57 | - (void)didMoveToPopupBar;
58 | 
59 | /// Called by the framework to notify the popup bar content view controller that the active appearance has changed.
60 | ///
61 | /// - Parameter activeAppearance: A merged appearance from the popup item, the system appearance and popup bar appearance, as appropriate.
62 | - (void)activeAppearanceDidChange:(LNPopupBarAppearance*)activeAppearance;
63 | 
64 | @end
65 | 
66 | NS_ASSUME_NONNULL_END
67 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/LNPopupDefinitions.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupDefinitions.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-12-16.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #ifndef LNPopupDefinitions_h
10 | #define LNPopupDefinitions_h
11 | 
12 | #import <Foundation/Foundation.h>
13 | 
14 | #ifndef NS_SWIFT_UI_ACTOR
15 | #define NS_SWIFT_UI_ACTOR
16 | #endif
17 | 
18 | #ifndef NS_SWIFT_DISABLE_ASYNC
19 | #define NS_SWIFT_DISABLE_ASYNC
20 | #endif
21 | 
22 | #define LN_UNAVAILABLE_API(x) __attribute__((unavailable(x)))
23 | #define LN_DEPRECATED_API(x) __attribute__((deprecated(x)))
24 | 
25 | #endif /* LNPopupDefinitions_h */
26 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/LNPopupImageView.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupImageView.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | /// A specialized `UIImageView` subclass, allowing setting a shadow and corner radius.
14 | ///
15 | /// When used inside a popup content view, instances of this class are especially suited as image transition targets.
16 | ///
17 | /// See `UIViewController.viewForPopupTransition(from:to:)`.
18 | @interface LNPopupImageView : UIImageView
19 | 
20 | /// The corner radius of the image view.
21 | @property (nonatomic, assign) CGFloat cornerRadius;
22 | /// The shadow displayed underneath the image view.
23 | @property (nonatomic, copy) NSShadow* shadow;
24 | 
25 | @end
26 | 
27 | NS_ASSUME_NONNULL_END
28 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNChevronView.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNChevronView.h
 3 | //
 4 | //  Created by Léo Natan on 2016-12-02.
 5 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 6 | //
 7 | 
 8 | #define LNChevronView __LNChevronView
 9 | #define LNChevronViewState __LNChevronViewState
10 | #define LNChevronViewStateUp __LNChevronViewStateUp
11 | #define LNChevronViewStateFlat __LNChevronViewStateFlat
12 | #define LNChevronViewStateDown __LNChevronViewStateDown
13 | 
14 | #import <UIKit/UIKit.h>
15 | 
16 | NS_ASSUME_NONNULL_BEGIN
17 | 
18 | typedef NS_ENUM(NSInteger, LNChevronViewState) {
19 | 	LNChevronViewStateUp = -1,
20 | 	LNChevronViewStateFlat = 0,
21 | 	LNChevronViewStateDown = 1
22 | };
23 | 
24 | @interface LNChevronView : UIView
25 | 
26 | @property (nonatomic, assign) LNChevronViewState state;
27 | @property (nonatomic, assign) CGFloat width;
28 | @property (nonatomic, assign) NSTimeInterval animationDuration;
29 | 
30 | - (void)setState:(LNChevronViewState)state animated:(BOOL)animated;
31 | 
32 | @end
33 | 
34 | NS_ASSUME_NONNULL_END
35 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNForwardingDelegate.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNForwardingDelegate.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2017-07-15.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | 
11 | @interface LNForwardingDelegate : NSObject
12 | 
13 | @property (nonatomic, weak) id forwardedDelegate;
14 | 
15 | + (BOOL)isCallerUIKit:(NSArray*)callStackReturnAddresses;
16 | 
17 | @end
18 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNForwardingDelegate.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNForwardingDelegate.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2017-07-15.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "LNForwardingDelegate.h"
10 | #import "_LNPopupAddressInfo.h"
11 | 
12 | @implementation LNForwardingDelegate
13 | 
14 | - (BOOL)respondsToSelector:(SEL)aSelector
15 | {
16 | 	if([super respondsToSelector:aSelector])
17 | 	{
18 | 		return YES;
19 | 	}
20 | 	
21 | 	return [self.forwardedDelegate respondsToSelector:aSelector];
22 | }
23 | 
24 | - (void)forwardInvocation:(NSInvocation *)anInvocation
25 | {
26 | 	[anInvocation invokeWithTarget:self.forwardedDelegate];
27 | }
28 | 
29 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
30 | {
31 | 	NSMethodSignature* ms = [super methodSignatureForSelector:aSelector];
32 | 	
33 | 	if(ms)
34 | 	{
35 | 		return ms;
36 | 	}
37 | 	
38 | 	return [self.forwardedDelegate methodSignatureForSelector:aSelector];
39 | }
40 | 
41 | + (BOOL)isCallerUIKit:(NSArray *)callStackReturnAddresses
42 | {
43 | 	NSUInteger addr = [callStackReturnAddresses[1] unsignedIntegerValue];
44 | 	_LNPopupAddressInfo* addrInfo = [[_LNPopupAddressInfo alloc] initWithAddress:addr];
45 | 	
46 | 	return [addrInfo.image hasPrefix:@"UIKit"];
47 | }
48 | 
49 | @end
50 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNMath.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNMath.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-08-06.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #ifndef C__Math_h
10 | #define C__Math_h
11 | 
12 | #import <CoreFoundation/CoreFoundation.h>
13 | 
14 | CF_EXTERN_C_BEGIN
15 | 
16 | extern double _ln_clamp(double v, double lo, double hi);
17 | 
18 | CF_EXTERN_C_END
19 | 
20 | #endif /* C__Math_h */
21 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNMath.m:
--------------------------------------------------------------------------------
 1 | //
 2 | // 	LNMath.
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-08-11.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #include "LNMath.h"
10 | #import <Foundation/Foundation.h>
11 | 
12 | double _ln_clamp(double v, double lo, double hi)
13 | {
14 | 	return MIN(hi, MAX(v, lo));
15 | }
16 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupBarAppearance+Private.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupBarAppearance+Private.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-06-20.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <LNPopupController/LNPopupBarAppearance.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupDominantColorTrait : NSObject <UIObjectTraitDefinition> @end
14 | 
15 | @protocol _LNPopupBarAppearanceDelegate <NSObject>
16 | 
17 | - (void)popupBarAppearanceDidChange:(LNPopupBarAppearance*)popupBarAppearance;
18 | 
19 | @end
20 | 
21 | @interface LNPopupBarAppearance ()
22 | 
23 | @property (nonatomic, weak) id<_LNPopupBarAppearanceDelegate> delegate;
24 | 
25 | - (UIBlurEffect *)floatingBackgroundEffectForTraitCollection:(UITraitCollection*)traitCollection;
26 | 
27 | @end
28 | 
29 | NS_ASSUME_NONNULL_END
30 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupBarAppearanceChainProxy.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupBarAppearanceChainProxy.h
 3 | //  LNPopupBarAppearanceChainProxy
 4 | //
 5 | //  Created by Léo Natan on 2021-08-07.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import "LNPopupBarAppearance+Private.h"
11 | 
12 | NS_ASSUME_NONNULL_BEGIN
13 | 
14 | @interface LNPopupBarAppearanceChainProxy : NSObject
15 | 
16 | @property (nonatomic, strong) NSArray<UIBarAppearance*>* chain;
17 | 
18 | - (instancetype)initWithAppearanceChain:(NSArray<UIBarAppearance*>*)chain;
19 | - (id)objectForKey:(NSString*)key;
20 | - (BOOL)boolForKey:(NSString*)key;
21 | - (NSUInteger)unsignedIntegerForKey:(NSString*)key;
22 | - (double)doubleForKey:(NSString*)key;
23 | 
24 | - (void)setChainDelegate:(nullable id<_LNPopupBarAppearanceDelegate>)delegate;
25 | 
26 | @end
27 | 
28 | 
29 | NS_ASSUME_NONNULL_END
30 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupCloseButton+Private.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupCloseButton+Private.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2016-12-02.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <LNPopupController/LNPopupCloseButton.h>
10 | #import <LNPopupController/LNPopupContentView.h>
11 | 
12 | @interface LNPopupCloseButton ()
13 | 
14 | - (instancetype)initWithContainingContentView:(LNPopupContentView*)contentView;
15 | 
16 | @property (nonatomic, weak) LNPopupContentView* popupContentView;
17 | 
18 | - (void)_setStyle:(LNPopupCloseButtonStyle)style;
19 | - (void)_setButtonContainerStationary;
20 | - (void)_setButtonContainerTransitioning;
21 | 
22 | @end
23 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupContentView+Private.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupContentView+Private.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2020-08-04.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <LNPopupController/LNPopupContentView.h>
10 | 
11 | @interface LNPopupContentView ()
12 | 
13 | - (instancetype)initWithFrame:(CGRect)frame;
14 | 
15 | @property (nonatomic, strong, readwrite) UIPanGestureRecognizer* popupInteractionGestureRecognizer;
16 | @property (nonatomic, strong, readwrite) LNPopupCloseButton* popupCloseButton;
17 | @property (nonatomic, strong) UIVisualEffectView* effectView;
18 | @property (nonatomic, strong, readonly) UIView* contentView;
19 | 
20 | @property (nonatomic, weak) UIViewController* currentPopupContentViewController;
21 | 
22 | - (void)setControllerOverrideUserInterfaceStyle:(UIUserInterfaceStyle)overrideUserInterfaceStyle;
23 | 
24 | - (void)_applyBackgroundEffectWithContentViewController:(UIViewController*)vc barEffect:(UIBlurEffect*)barEffect;
25 | 
26 | - (void)_repositionPopupCloseButton;
27 | - (void)_repositionPopupCloseButtonAnimated:(BOOL)animated;
28 | 
29 | @end
30 | 
31 | @interface _LNPopupTransitionCoordinator : NSObject <UIViewControllerTransitionCoordinator> @end
32 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupController.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import "LNPopupBar+Private.h"
11 | #import "UIViewController+LNPopupSupportPrivate.h"
12 | #import <LNPopupController/LNPopupCloseButton.h>
13 | #import "LNPopupContentView+Private.h"
14 | #import "LNPopupBar+Private.h"
15 | 
16 | CF_EXTERN_C_BEGIN
17 | 
18 | #define _LNPopupPresentationStateTransitioning ((LNPopupPresentationState)2)
19 | 
20 | @interface LNPopupController : NSObject <_LNPopupBarDelegate>
21 | 
22 | - (instancetype)initWithContainerViewController:(__kindof UIViewController*)containerController;
23 | 
24 | @property (nonatomic, weak) UIView* bottomBar;
25 | 
26 | @property (nonatomic, strong) LNPopupBar* popupBar;
27 | @property (nonatomic, strong, readonly) LNPopupBar* popupBarStorage;
28 | @property (nonatomic, strong, readonly) LNPopupBar* popupBarNoCreate;
29 | @property (nonatomic, strong) LNPopupContentView* popupContentView;
30 | @property (nonatomic, strong) UIScrollView* popupContentContainerView;
31 | 
32 | @property (nonatomic) LNPopupPresentationState popupControllerPublicState;
33 | @property (nonatomic) LNPopupPresentationState popupControllerInternalState;
34 | @property (nonatomic) LNPopupPresentationState popupControllerTargetState;
35 | 
36 | @property (nonatomic, weak) id<LNPopupPresentationDelegate> userPopupPresentationDelegate;
37 | 
38 | @property (nonatomic, strong) __kindof UIViewController* currentContentController;
39 | @property (nonatomic, weak, readonly) __kindof UIViewController* containerController;
40 | 
41 | @property (nonatomic) CGPoint lastPopupBarLocation;
42 | @property (nonatomic) CFTimeInterval lastSeenMovement;
43 | 
44 | @property (nonatomic, weak) UIViewController* effectiveStatusBarUpdateController;
45 | 
46 | @property (assign) BOOL wantsFeedbackGeneration;
47 | 
48 | - (CGFloat)_percentFromPopupBar;
49 | 
50 | - (void)_setContentToState:(LNPopupPresentationState)state;
51 | - (void)_setContentToState:(LNPopupPresentationState)state animated:(BOOL)animated;
52 | 
53 | - (void)_movePopupBarAndContentToBottomBarSuperview;
54 | 
55 | - (void)presentPopupBarWithContentViewController:(UIViewController*)contentViewController openPopup:(BOOL)open animated:(BOOL)animated completion:(void(^)(void))completionBlock;
56 | - (void)openPopupAnimated:(BOOL)animated completion:(void(^)(void))completionBlock;
57 | - (void)closePopupAnimated:(BOOL)animated completion:(void(^)(void))completionBlock;
58 | - (void)dismissPopupBarAnimated:(BOOL)animated completion:(void(^)(void))completionBlock;
59 | 
60 | - (void)_configurePopupBarFromBottomBar;
61 | - (void)_configurePopupBarFromBottomBarModifyingGroupingIdentifier:(BOOL)modifyingGroupingIdentifier;
62 | - (void)_updateBarExtensionStyleFromPopupBar;
63 | 
64 | + (CGFloat)_statusBarHeightForView:(UIView*)view;
65 | 
66 | - (void)_fixupGestureRecognizer:(UIGestureRecognizer*)obj;
67 | 
68 | @end
69 | 
70 | CF_EXTERN_C_END
71 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupCustomBarViewController+Private.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupItem+Private.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2016-12-30.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <LNPopupController/LNPopupItem.h>
10 | #import <LNPopupController/LNPopupCustomBarViewController.h>
11 | #import "LNPopupController.h"
12 | 
13 | @interface LNPopupCustomBarViewController ()
14 | 
15 | @property (nonatomic, weak, readwrite) LNPopupBar* containingPopupBar;
16 | @property (nonatomic, weak) LNPopupController* popupController;
17 | 
18 | - (void)_activeAppearanceDidChange:(LNPopupBarAppearance*)activeAppearance;
19 | 
20 | - (void)_userFacing_viewWillAppear:(BOOL)animated;
21 | - (void)_userFacing_viewIsAppearing:(BOOL)animated;
22 | - (void)_userFacing_viewDidAppear:(BOOL)animated;
23 | - (void)_userFacing_viewWillDisappear:(BOOL)animated;
24 | - (void)_userFacing_viewDidDisappear:(BOOL)animated;
25 | 
26 | @end
27 | 
28 | @interface _LNPopupCustomBarViewController_AppearanceControl : LNPopupCustomBarViewController @end
29 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupDebug.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupDebug.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-04-04.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | #ifdef DEBUG
14 | CF_EXTERN_C_BEGIN
15 | extern NSUserDefaults* __LNDebugUserDefaults(void);
16 | CF_EXTERN_C_END
17 | #endif
18 | 
19 | NS_ASSUME_NONNULL_END
20 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupDebug.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupDebug.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-04-04.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "LNPopupDebug.h"
10 | 
11 | #ifdef DEBUG
12 | NSUserDefaults* __LNDebugUserDefaults(void)
13 | {
14 | 	static NSUserDefaults* rv = nil;
15 | 	
16 | 	static dispatch_once_t onceToken;
17 | 	dispatch_once(&onceToken, ^{
18 | 		SEL sel = NSSelectorFromString(@"settingDefaults");
19 | 		if([NSUserDefaults respondsToSelector:sel])
20 | 		{
21 | 			rv = [NSUserDefaults valueForKey:@"settingDefaults"];
22 | 		}
23 | 		else
24 | 		{
25 | 			rv = NSUserDefaults.standardUserDefaults;
26 | 		}
27 | 	});
28 | 	
29 | 	return rv;
30 | }
31 | #endif
32 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupImageView+Private.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupImageView+Private.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <LNPopupController/LNPopupImageView.h>
10 | #import "LNPopupBar+Private.h"
11 | 
12 | NS_ASSUME_NONNULL_BEGIN
13 | 
14 | @interface LNPopupImageView ()
15 | 
16 | - (instancetype)initWithContainingPopupBar:(LNPopupBar*)popupBar;
17 | 
18 | @end
19 | 
20 | NS_ASSUME_NONNULL_END
21 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupInteractionPanGestureRecognizer.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupInteractionPanGestureRecognizer.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2017-07-15.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | @class LNPopupController;
12 | 
13 | @interface LNPopupInteractionPanGestureRecognizer : UIPanGestureRecognizer
14 | 
15 | - (instancetype)initWithTarget:(id)target action:(SEL)action popupController:(LNPopupController*)popupController;
16 | 
17 | @end
18 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupItem+Private.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupItem+Private.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <LNPopupController/LNPopupItem.h>
10 | #import "LNPopupController.h"
11 | 
12 | extern NSArray* __LNPopupItemObservedKeys;
13 | 
14 | @class LNPopupItem;
15 | 
16 | @protocol _LNPopupItemDelegate <NSObject>
17 | 
18 | - (void)_popupItem:(LNPopupItem*)popupItem didChangeToValue:(id)value forKey:(NSString*)key;
19 | 
20 | @end
21 | 
22 | @interface LNPopupItem ()
23 | 
24 | @property (nonatomic, strong) UIViewController* swiftuiImageController;
25 | 
26 | @property (nonatomic, strong) UIView* swiftuiTitleContentView;
27 | 
28 | @property (nonatomic, strong) UIViewController* swiftuiHiddenLeadingController;
29 | @property (nonatomic, strong) UIViewController* swiftuiHiddenTrailingController;
30 | 
31 | @property (nonatomic, copy) NSString* accessibilityImageLabel;
32 | @property (nonatomic, copy) NSString* accessibilityProgressLabel;
33 | @property (nonatomic, copy) NSString* accessibilityProgressValue;
34 | 
35 | @property (nonatomic, weak, setter=_setItemDelegate:, getter=_itemDelegate) id<_LNPopupItemDelegate> itemDelegate;
36 | @property (nonatomic, weak, setter=_setContainerController:, getter=_containerController) __kindof UIViewController* containerController;
37 | 
38 | @end
39 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupLongPressGestureRecognizer.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupLongPressGestureRecognizer.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2017-07-15.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | @interface LNPopupLongPressGestureRecognizer : UILongPressGestureRecognizer
12 | 
13 | @end
14 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupLongPressGestureRecognizer.m:
--------------------------------------------------------------------------------
  1 | //
  2 | //  LNPopupLongPressGestureRecognizer.m
  3 | //  LNPopupController
  4 | //
  5 | //  Created by Léo Natan on 2017-07-15.
  6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
  7 | //
  8 | 
  9 | #import "LNPopupLongPressGestureRecognizer.h"
 10 | #import "LNForwardingDelegate.h"
 11 | 
 12 | @interface LNPopupControllerLongPressGestureDelegate : LNForwardingDelegate <UIGestureRecognizerDelegate>
 13 | @end
 14 | 
 15 | @implementation LNPopupControllerLongPressGestureDelegate
 16 | 
 17 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
 18 | {
 19 | #if ! TARGET_OS_MACCATALYST
 20 | 	if(@available(iOS 13.4, *))
 21 | 	{
 22 | 		if(touch.type == UITouchTypeIndirectPointer)
 23 | 		{
 24 | 			return NO;
 25 | 		}
 26 | 	}
 27 | #endif
 28 | 	
 29 | 	if([touch.view isKindOfClass:[UIControl class]])
 30 | 	{
 31 | 		return NO;
 32 | 	}
 33 | 	
 34 | 	if([self.forwardedDelegate respondsToSelector:_cmd])
 35 | 	{
 36 | 		return [self.forwardedDelegate gestureRecognizer:gestureRecognizer shouldReceiveTouch:touch];
 37 | 	}
 38 | 	
 39 | 	return YES;
 40 | }
 41 | 
 42 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
 43 | {
 44 | 	if([NSStringFromClass(otherGestureRecognizer.class) containsString:@"SwiftUI"])
 45 | 	{
 46 | 		return YES;
 47 | 	}
 48 | 	
 49 | 	if([self.forwardedDelegate respondsToSelector:_cmd])
 50 | 	{
 51 | 		return [self.forwardedDelegate gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer];
 52 | 	}
 53 | 	
 54 | 	return NO;
 55 | }
 56 | 
 57 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
 58 | {
 59 | 	if([self.forwardedDelegate respondsToSelector:_cmd])
 60 | 	{
 61 | 		return [self.forwardedDelegate gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer];
 62 | 	}
 63 | 	
 64 | 	return YES;
 65 | }
 66 | 
 67 | @end
 68 | 
 69 | 
 70 | @implementation LNPopupLongPressGestureRecognizer
 71 | {
 72 | 	LNPopupControllerLongPressGestureDelegate* _actualDelegate;
 73 | }
 74 | 
 75 | - (instancetype)initWithTarget:(id)target action:(SEL)action
 76 | {
 77 | 	self = [super initWithTarget:target action:action];
 78 | 	
 79 | 	if(self)
 80 | 	{
 81 | 		_actualDelegate = [LNPopupControllerLongPressGestureDelegate new];
 82 | 		[super setDelegate:_actualDelegate];
 83 | 	}
 84 | 	
 85 | 	return self;
 86 | }
 87 | 
 88 | - (id<UIGestureRecognizerDelegate>)delegate
 89 | {
 90 | 	return _actualDelegate.forwardedDelegate;
 91 | }
 92 | 
 93 | - (void)setDelegate:(id<UIGestureRecognizerDelegate>)delegate
 94 | {
 95 | 	_actualDelegate = [LNPopupControllerLongPressGestureDelegate new];
 96 | 	_actualDelegate.forwardedDelegate = delegate;
 97 | 	[super setDelegate:_actualDelegate];
 98 | }
 99 | 
100 | @end
101 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupOpenTapGestureRecognizer.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupOpenTapGestureRecognizer.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2017-07-15.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | @interface LNPopupOpenTapGestureRecognizer : UITapGestureRecognizer
12 | 
13 | @end
14 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupOpenTapGestureRecognizer.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupOpenTapGestureRecognizer.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2017-07-15.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "LNPopupOpenTapGestureRecognizer.h"
10 | #import "LNForwardingDelegate.h"
11 | 
12 | @interface LNPopupOpenTapGestureRecognizerForwardingDelegate : LNForwardingDelegate <UIGestureRecognizerDelegate>
13 | 
14 | @end
15 | 
16 | @implementation LNPopupOpenTapGestureRecognizerForwardingDelegate
17 | 
18 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
19 | {
20 | 	if([touch.view isKindOfClass:[UIControl class]])
21 | 	{
22 | 		return NO;
23 | 	}
24 | 	
25 | 	if([self.forwardedDelegate respondsToSelector:_cmd])
26 | 	{
27 | 		return [self.forwardedDelegate gestureRecognizer:gestureRecognizer shouldReceiveTouch:touch];
28 | 	}
29 | 	
30 | 	return YES;
31 | }
32 | 
33 | @end
34 | 
35 | @implementation LNPopupOpenTapGestureRecognizer
36 | {
37 | 	LNPopupOpenTapGestureRecognizerForwardingDelegate* _actualDelegate;
38 | }
39 | 
40 | - (instancetype)initWithTarget:(id)target action:(SEL)action
41 | {
42 | 	self = [super initWithTarget:target action:action];
43 | 	
44 | 	if(self)
45 | 	{
46 | 		_actualDelegate = [LNPopupOpenTapGestureRecognizerForwardingDelegate new];
47 | 		[super setDelegate:_actualDelegate];
48 | 	}
49 | 	
50 | 	return self;
51 | }
52 | 
53 | - (id<UIGestureRecognizerDelegate>)delegate
54 | {
55 | 	return _actualDelegate.forwardedDelegate;
56 | }
57 | 
58 | - (void)setDelegate:(id<UIGestureRecognizerDelegate>)delegate
59 | {
60 | 	_actualDelegate = [LNPopupOpenTapGestureRecognizerForwardingDelegate new];
61 | 	_actualDelegate.forwardedDelegate = delegate;
62 | 	[super setDelegate:_actualDelegate];
63 | }
64 | 
65 | @end
66 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupPresentationContainerSupport.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupPresentationContainerSupport.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-04-13.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface LNPopupPresentationContainerSupport : UIViewController
14 | 
15 | @end
16 | 
17 | NS_ASSUME_NONNULL_END
18 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/LNPopupPresentationContainerSupport.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupPresentationContainerSupport.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-04-13.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "LNPopupPresentationContainerSupport.h"
10 | #import "UIViewController+LNPopupSupportPrivate.h"
11 | #import "_LNPopupSwizzlingUtils.h"
12 | 
13 | #define LN_POPUP_SMART_CHILD_OVERRIDE(name, availability) \
14 | - (UIViewController*)name API_AVAILABLE(availability) \
15 | { \
16 | UIViewController* rv = [self _ln_childViewControllerForStatusBarLogic]; \
17 | if(rv != nil) \
18 | { \
19 | return rv;\
20 | }\
21 | \
22 | Class superclass = LNDynamicSubclassSuper(self, LNPopupPresentationContainerSupport.class);\
23 | struct objc_super super = {.receiver = self, .super_class = superclass};\
24 | UIViewController* (*super_class)(struct objc_super*, SEL) = (void*)objc_msgSendSuper;\
25 | return super_class(&super, _cmd);\
26 | }
27 | 
28 | @implementation LNPopupPresentationContainerSupport
29 | 
30 | LN_POPUP_SMART_CHILD_OVERRIDE(childViewControllerForPointerLock, ios(14))
31 | LN_POPUP_SMART_CHILD_OVERRIDE(childViewControllerForStatusBarStyle, ios(7))
32 | LN_POPUP_SMART_CHILD_OVERRIDE(childViewControllerForStatusBarHidden, ios(7))
33 | LN_POPUP_SMART_CHILD_OVERRIDE(childViewControllerForHomeIndicatorAutoHidden, ios(11))
34 | LN_POPUP_SMART_CHILD_OVERRIDE(childViewControllerForScreenEdgesDeferringSystemGestures, ios(11))
35 | 
36 | @end
37 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/NSAttributedString+LNPopupSupport.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  NSAttributedString+LNPopupSupport.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-09-19.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface NSAttributedString (LNPopupSupport)
14 | 
15 | + (instancetype)ln_attributedStringWithAttributedString:(NSAttributedString*)orig defaultAttributes:(nullable NSDictionary<NSAttributedStringKey, id>*)attribs;
16 | 
17 | @end
18 | 
19 | NS_ASSUME_NONNULL_END
20 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/NSAttributedString+LNPopupSupport.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  NSAttributedString+LNPopupSupport.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-09-19.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "NSAttributedString+LNPopupSupport.h"
10 | 
11 | @implementation NSAttributedString (LNPopupSupport)
12 | 
13 | + (instancetype)ln_attributedStringWithAttributedString:(NSAttributedString*)orig defaultAttributes:(nullable NSDictionary<NSAttributedStringKey, id>*)attribs
14 | {
15 | 	NSMutableAttributedString* rv = [[NSMutableAttributedString alloc] initWithString:orig.string attributes:attribs];
16 | 	
17 | 	[orig enumerateAttributesInRange:NSMakeRange(0, orig.length) options:0 usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
18 | 		[rv addAttributes:attrs range:range];
19 | 	}];
20 | 	
21 | 	return rv;
22 | }
23 | 
24 | @end
25 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/UIContextMenuInteraction+LNPopupSupportPrivate.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  UIContextMenuInteraction+LNPopupSupportPrivate.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-03-28.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | #ifndef LNPopupControllerEnforceStrictClean
12 | 
13 | NS_ASSUME_NONNULL_BEGIN
14 | 
15 | @interface UIContextMenuInteraction (LNPopupSupportPrivate)
16 | 
17 | @end
18 | 
19 | NS_ASSUME_NONNULL_END
20 | 
21 | #endif
22 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/UIView+LNPopupSupportPrivate.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  UIView+LNPopupSupportPrivate.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2020-08-01.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | @class LNPopupBar;
12 | @class LNPopupController;
13 | 
14 | NS_ASSUME_NONNULL_BEGIN
15 | 
16 | typedef void (^LNInWindowBlock)(dispatch_block_t);
17 | 
18 | @interface NSObject (LNPopupSupportPrivate)
19 | 
20 | @property (nonatomic, weak, nullable, getter=_ln_attachedPopupController, setter=_ln_setAttachedPopupController:) LNPopupController* attachedPopupController;
21 | 
22 | @end
23 | 
24 | UIEdgeInsets _LNEdgeInsetsFromDirectionalEdgeInsets(UIView* forView, NSDirectionalEdgeInsets edgeInsets);
25 | 
26 | @interface UIView (LNPopupSupportPrivate)
27 | 
28 | - (void)_ln_triggerBarAppearanceRefreshIfNeededTriggeringLayout:(BOOL)layout;
29 | - (BOOL)_ln_scrollEdgeAppearanceRequiresFadeForPopupBar:(LNPopupBar*)popupBar;
30 | 
31 | - (void)_ln_letMeKnowWhenViewInWindowHierarchy:(LNInWindowBlock)block;
32 | - (void)_ln_forgetAboutIt;
33 | - (nullable NSString*)_ln_effectGroupingIdentifierIfAvailable;
34 | 
35 | - (void)_ln_freezeInsets;
36 | 
37 | @end
38 | 
39 | @interface UIView ()
40 | 
41 | - (id)_lnpopup_scrollEdgeAppearance;
42 | 
43 | @end
44 | 
45 | @interface UITabBar ()
46 | 
47 | @property (nonatomic, getter=_ignoringLayoutDuringTransition, setter=_setIgnoringLayoutDuringTransition:) BOOL ignoringLayoutDuringTransition;
48 | 
49 | @end
50 | 
51 | @interface UIWindow (LNPopupSupport)
52 | 
53 | @property (nonatomic, strong, readonly) UIEvent* _ln_currentEvent;
54 | 
55 | @property (nonatomic, assign, nullable, getter=_ln_popupInteractionOnly, setter=_ln_setPopupInteractionOnly:) NSArray* popupInteractionOnly;
56 | 
57 | @end
58 | 
59 | NS_ASSUME_NONNULL_END
60 | 
61 | @interface UIScrollView (LNPopupSupportPrivate)
62 | 
63 | - (BOOL)_ln_hasHorizontalContent;
64 | - (BOOL)_ln_hasVerticalContent;
65 | - (BOOL)_ln_scrollingOnlyVertically;
66 | - (BOOL)_ln_isAtTop;
67 | 
68 | @end
69 | 
70 | @interface _LNPopupBarBackgroundGroupNameOverride: NSObject <UIObjectTraitDefinition> @end
71 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupAddressInfo.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupAddressInfo.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2024-08-09.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupAddressInfo : NSObject
14 | 
15 | - (instancetype)initWithAddress:(NSUInteger)address;
16 | 
17 | @property (nonatomic, readonly) NSUInteger address;
18 | @property (nonatomic, copy, readonly) NSString* image;
19 | @property (nonatomic, copy, readonly) NSString* symbol;
20 | @property (nonatomic, readonly) NSUInteger offset;
21 | 
22 | @end
23 | 
24 | NS_ASSUME_NONNULL_END
25 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupAddressInfo.mm:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupAddressInfo.mm
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2024-08-09.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupAddressInfo.h"
10 | #include <dlfcn.h>
11 | #include <cxxabi.h>
12 | 
13 | @implementation _LNPopupAddressInfo
14 | {
15 | 	Dl_info _info;
16 | }
17 | 
18 | @synthesize image, symbol, offset, address;
19 | 
20 | - (instancetype)initWithAddress:(NSUInteger)_address
21 | {
22 | 	self = [super init];
23 | 	
24 | 	if(self)
25 | 	{
26 | 		address = _address;
27 | 		if(dladdr((void*)address, &_info) <= 0)
28 | 		{
29 | 			return nil;
30 | 		}
31 | 	}
32 | 	
33 | 	return self;
34 | }
35 | 
36 | - (NSString *)image
37 | {
38 | 	if(_info.dli_fname != NULL)
39 | 	{
40 | 		NSString* potentialImage = [NSString stringWithUTF8String:_info.dli_fname];
41 | 		
42 | 		if([potentialImage containsString:@"/"])
43 | 		{
44 | 			return potentialImage.lastPathComponent;
45 | 		}
46 | 	}
47 | 	
48 | 	return @"???";
49 | }
50 | 
51 | - (NSString *)symbol
52 | {
53 | 	if(_info.dli_sname != NULL)
54 | 	{
55 | 		return [NSString stringWithUTF8String:_info.dli_sname];
56 | 	}
57 | 	else if(_info.dli_fname != NULL)
58 | 	{
59 | 		return self.image;
60 | 	}
61 | 	
62 | 	return [NSString stringWithFormat:@"0x%1lx", (unsigned long)_info.dli_saddr];
63 | }
64 | 
65 | - (NSUInteger)offset
66 | {
67 | 	NSString* str = nil;
68 | 	if(_info.dli_sname != NULL && (str = [NSString stringWithUTF8String:_info.dli_sname]) != nil)
69 | 	{
70 | 		return address - (NSUInteger)_info.dli_saddr;
71 | 	}
72 | 	else if(_info.dli_fname != NULL && (str = [NSString stringWithUTF8String:_info.dli_fname]) != nil)
73 | 	{
74 | 		return address - (NSUInteger)_info.dli_fbase;
75 | 	}
76 | 	
77 | 	return address - (NSUInteger)_info.dli_saddr;
78 | }
79 | 
80 | - (NSString*)description
81 | {
82 | #if __LP64__
83 | 	return [NSString stringWithFormat:@"%-35s 0x%016llx %@ + %ld", self.image.UTF8String, (uint64_t)address, self.symbol, self.offset];
84 | #else
85 | 	return [NSString stringWithFormat:@"%-35s 0x%08lx %@ + %d", self.image.UTF8String, (unsigned long)address, self.symbol, self.offset];
86 | #endif
87 | }
88 | 
89 | @end
90 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupBackgroundShadowView.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupBackgroundShadowView.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2023-09-25.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupBackgroundShadowView : UIView
14 | 
15 | @property (nonatomic, strong) NSShadow* shadow;
16 | @property (nonatomic, assign) CGFloat cornerRadius;
17 | 
18 | @end
19 | 
20 | NS_ASSUME_NONNULL_END
21 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupBackgroundShadowView.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupBackgroundShadowView.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2023-09-25.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupBackgroundShadowView.h"
10 | 
11 | @implementation _LNPopupBackgroundShadowView
12 | {
13 | 	CAShapeLayer* _maskLayer;
14 | }
15 | 
16 | - (instancetype)initWithFrame:(CGRect)frame
17 | {
18 | 	self = [super initWithFrame:frame];
19 | 	
20 | 	if(self)
21 | 	{
22 | 		_maskLayer = [CAShapeLayer layer];
23 | 		_maskLayer.fillRule = kCAFillRuleEvenOdd;
24 | 		self.layer.mask = _maskLayer;
25 | 		self.layer.shouldRasterize = YES;
26 | 	}
27 | 	
28 | 	return self;
29 | }
30 | 
31 | - (void)setShadow:(NSShadow *)shadow
32 | {
33 | 	_shadow = shadow;
34 | 	
35 | 	self.layer.shadowOffset = _shadow.shadowOffset;
36 | 	self.layer.shadowRadius = _shadow.shadowBlurRadius;
37 | 	
38 | 	[self _updateShadowColor];
39 | 	[self setNeedsLayout];
40 | }
41 | 
42 | - (void)_updateShadowColor
43 | {
44 | 	self.layer.shadowColor = [(UIColor*)_shadow.shadowColor colorWithAlphaComponent:1.0].CGColor;
45 | 	self.layer.shadowOpacity = CGColorGetAlpha([_shadow.shadowColor CGColor]);
46 | }
47 | 
48 | - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
49 | {
50 | 	[super traitCollectionDidChange:previousTraitCollection];
51 | 	
52 | 	self.layer.rasterizationScale = self.traitCollection.displayScale;
53 | 	[self _updateShadowColor];
54 | }
55 | 
56 | - (void)layoutSubviews
57 | {
58 | 	[super layoutSubviews];
59 | 	
60 | 	CGFloat dx = 2 * _shadow.shadowBlurRadius + fabs(_shadow.shadowOffset.width);
61 | 	CGFloat dy = 2 * _shadow.shadowBlurRadius + fabs(_shadow.shadowOffset.height);
62 | 	
63 | 	self.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:_cornerRadius].CGPath;
64 | 	_maskLayer.frame = CGRectInset(self.bounds, -dx, -dy);
65 | 	
66 | 	UIBezierPath* maskPath = [UIBezierPath bezierPathWithRect:_maskLayer.bounds];
67 | 	[maskPath appendPath:[UIBezierPath bezierPathWithRoundedRect:CGRectInset(_maskLayer.bounds, dx, dy) cornerRadius:_cornerRadius]];
68 | 	maskPath.usesEvenOddFillRule = YES;
69 | 	
70 | 	_maskLayer.path = maskPath.CGPath;
71 | }
72 | 
73 | @end
74 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupBarBackgroundMaskView.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupBarBackgroundMaskView.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2023-09-27.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupBarBackgroundMaskView: UIView
14 | 
15 | @property (nonatomic, readonly) BOOL wantsCutout;
16 | - (void)setWantsCutout:(BOOL)wantsCutout animated:(BOOL)animated;
17 | 
18 | @property (nonatomic) CGRect floatingFrame;
19 | @property (nonatomic) CGFloat floatingCornerRadius;
20 | 
21 | @end
22 | 
23 | 
24 | NS_ASSUME_NONNULL_END
25 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupBarBackgroundView.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupBarBackgroundView.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2021-06-20.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupBarBackgroundView : UIView
14 | 
15 | - (instancetype)initWithEffect:(nullable UIVisualEffect *)effect;
16 | 
17 | @property (nonatomic, strong, readonly) UIVisualEffectView* effectView;
18 | @property (nonatomic, copy, nullable) UIVisualEffect* effect;
19 | @property (nonatomic, strong, readonly) UIView* contentView;
20 | 
21 | @property(nonatomic, copy, nullable) UIColor* foregroundColor;
22 | @property(nonatomic, strong, nullable) UIImage* foregroundImage;
23 | @property(nonatomic) UIViewContentMode foregroundImageContentMode;
24 | - (void)hideOrShowImageViewIfNecessary;
25 | 
26 | @property (nonatomic, assign) CGFloat cornerRadius;
27 | 
28 | @property (nonatomic, strong, readonly) UIView* transitionShadingView;
29 | 
30 | @end
31 | 
32 | NS_ASSUME_NONNULL_END
33 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupBase64Utils.hh:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupBase64Utils.hh
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2024-09-01.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | #include <cstdlib>
11 | #include <array>
12 | 
13 | namespace lnpopup {
14 | 
15 | template <size_t N>
16 | struct base64_string : std::array<char, N> {
17 | 	consteval base64_string(const char (&input)[N]) : base64_string(input, std::make_index_sequence<N>{}) {}
18 | 	template <size_t... Is>
19 | 	consteval base64_string(const char (&input)[N], std::index_sequence<Is...>) : std::array<char, N>{ input[Is]... } {}
20 | };
21 | 
22 | template <size_t N>
23 | consteval const auto base64_encode(const char(&input)[N]) {
24 | 	constexpr char encoding_table[] =
25 | 	{
26 | 		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
27 | 		'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
28 | 		'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
29 | 		'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
30 | 		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
31 | 	};
32 | 	
33 | 	constexpr size_t out_len = 4 * (((N - 1) + 2) / 3) + 1;
34 | 	
35 | 	size_t in_len = N - 1;
36 | 	char output[out_len] {0};
37 | 	size_t i = 0;
38 | 	char *p = const_cast<char *>(output);
39 | 	
40 | 	for(i = 0; in_len > 2 && i < in_len - 2; i += 3)
41 | 	{
42 | 		*p++ = encoding_table[(input[i] >> 2) & 0x3F];
43 | 		*p++ = encoding_table[((input[i] & 0x3) << 4) | ((int)(input[i + 1] & 0xF0) >> 4)];
44 | 		*p++ = encoding_table[((input[i + 1] & 0xF) << 2) | ((int)(input[i + 2] & 0xC0) >> 6)];
45 | 		*p++ = encoding_table[input[i + 2] & 0x3F];
46 | 	}
47 | 	
48 | 	if(i < in_len)
49 | 	{
50 | 		*p++ = encoding_table[(input[i] >> 2) & 0x3F];
51 | 		if(i == (in_len - 1))
52 | 		{
53 | 			*p++ = encoding_table[((input[i] & 0x3) << 4)];
54 | 			*p++ = '=';
55 | 		}
56 | 		else
57 | 		{
58 | 			*p++ = encoding_table[((input[i] & 0x3) << 4) | ((int)(input[i + 1] & 0xF0) >> 4)];
59 | 			*p++ = encoding_table[((input[i + 1] & 0xF) << 2)];
60 | 		}
61 | 		*p++ = '=';
62 | 	}
63 | 	
64 | 	return base64_string<out_len>(output);
65 | }
66 | 
67 | CF_INLINE
68 | auto decode_hidden_string(auto encoded)
69 | {
70 | 	return [[NSString alloc] initWithData:[[NSData alloc] initWithBase64EncodedString:@(encoded.data()) options:0] encoding:NSUTF8StringEncoding];
71 | }
72 | 
73 | } //namespace lnpopup
74 | 
75 | #define LNPopupHiddenString(input) (lnpopup::decode_hidden_string(lnpopup::base64_encode("" input "")))
76 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupSwizzlingUtils.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupSwizzlingUtils.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2020-07-31.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | #import <objc/message.h>
11 | #import <objc/runtime.h>
12 | 
13 | CF_EXTERN_C_BEGIN
14 | 
15 | #define unavailable(...) @available(__VA_ARGS__)) { } else if(YES
16 | 
17 | #define LNSwizzleComplain(FORMAT, ...) \
18 | if(shouldTrapAndPrint) { \
19 | NSString *errStr = [NSString stringWithFormat:@"%s: " FORMAT,__func__,##__VA_ARGS__]; \
20 | NSLog(@"LNPopupController: %@", errStr); \
21 | raise(SIGTRAP); \
22 | }
23 | 
24 | #ifndef LNAlwaysInline
25 | #define LNAlwaysInline CF_INLINE
26 | #endif /* LNAlwaysInline */
27 | 
28 | extern BOOL __LNSwizzleMethod(Class cls, SEL orig, SEL alt);
29 | 
30 | #define LNSwizzleMethod __LNSwizzleMethod
31 | 
32 | LNAlwaysInline
33 | BOOL __LNSwizzleClassMethod(Class cls, SEL orig, SEL alt)
34 | {
35 | 	return LNSwizzleMethod(object_getClass((id)cls), orig, alt);
36 | }
37 | 
38 | extern BOOL __LNDynamicSubclass(id obj, Class target);
39 | #define LNDynamicSubclass __LNDynamicSubclass
40 | extern Class __LNDynamicSubclassSuper(id obj, Class dynamic);
41 | #define LNDynamicSubclassSuper __LNDynamicSubclassSuper
42 | 
43 | NSArray<NSString*>* __LNPopupGetPropertyNames(Class cls, NSArray<NSString*>* excludedProperties);
44 | #define LNPopupGetPropertyNames __LNPopupGetPropertyNames
45 | 
46 | CF_EXTERN_C_END
47 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionAnimator.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionAnimator.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import <LNPopupController/LNPopupBar.h>
11 | #import <LNPopupController/LNPopupContentView.h>
12 | #import <LNPopupController/UIViewController+LNPopupSupport.h>
13 | #import "_LNPopupTransitionView.h"
14 | 
15 | NS_ASSUME_NONNULL_BEGIN
16 | 
17 | @interface UIViewPropertyAnimator ()
18 | 
19 | - (void)addAnimations:(void (^)(void))animation delayFactor:(CGFloat)delayFactor durationFactor:(CGFloat)durationFactor;
20 | 
21 | @end
22 | 
23 | @interface _LNPopupTransitionAnimator : NSObject
24 | 
25 | - (instancetype)initWithTransitionView:(nullable _LNPopupTransitionView*)transitionView userView:(UIView*)view popupBar:(LNPopupBar*)popupBar popupContentView:(LNPopupContentView*)popupContentView;
26 | 
27 | @property (nonatomic, strong, readonly) UIView* view;
28 | @property (nonatomic, strong, readonly) LNPopupBar* popupBar;
29 | @property (nonatomic, strong, readonly) LNPopupContentView* popupContentView;
30 | 
31 | @property (nonatomic, strong, readonly, nullable) _LNPopupTransitionView* transitionView;
32 | @property (nonatomic, strong, readonly, nullable) UIView<LNPopupTransitionView>* crossfadeView;
33 | @property (nonatomic, readonly) CGRect sourceFrame;
34 | @property (nonatomic, readonly) CGRect targetFrame;
35 | @property (nonatomic, readonly) CGAffineTransform transform;
36 | 
37 | @property (nonatomic, readonly) CGFloat scaledBarImageViewCornerRadius;
38 | @property (nonatomic, strong, readonly) NSShadow* scaledBarImageViewShadow;
39 | 
40 | - (void)animateWithAnimator:(UIViewPropertyAnimator*)animator otherAnimations:(void(^)(void))otherAnimations NS_REQUIRES_SUPER;
41 | - (void)beforeAnyAnimation NS_REQUIRES_SUPER;
42 | - (void)performBeforeAdditionalAnimations NS_REQUIRES_SUPER;
43 | - (void)performAdditionalAnimations NS_REQUIRES_SUPER;
44 | - (void)performAdditionalDelayed015Animations NS_REQUIRES_SUPER;
45 | - (void)performAdditionalDelayed05Animations NS_REQUIRES_SUPER;
46 | - (void)performAdditional01Animations NS_REQUIRES_SUPER;
47 | - (void)performAdditional075Animations NS_REQUIRES_SUPER;
48 | - (void)performAdditional04Delayed015Animations NS_REQUIRES_SUPER;
49 | - (void)performAdditional075Delayed015Animations NS_REQUIRES_SUPER;
50 | - (void)performAdditionalCompletion NS_REQUIRES_SUPER;
51 | 
52 | @property (nonatomic, readonly) LNPopupPresentationState targetState;
53 | 
54 | @end
55 | 
56 | NS_ASSUME_NONNULL_END
57 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionCloseAnimator.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionCloseAnimator.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionAnimator.h"
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupTransitionCloseAnimator : _LNPopupTransitionAnimator
14 | 
15 | - (instancetype)initWithTransitionView:(nullable _LNPopupTransitionView*)transitionView userView:(UIView*)view popupBar:(LNPopupBar*)popupBar popupContentView:(LNPopupContentView*)popupContentView currentContentController:(UIViewController*)currentContentController containerController:(UIViewController*)containerController;
16 | 
17 | @property (nonatomic, strong) UIViewController* currentContentController;
18 | @property (nonatomic, strong) UIViewController* containerController;
19 | 
20 | @end
21 | 
22 | NS_ASSUME_NONNULL_END
23 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionGenericCloseAnimator.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionGenericCloseAnimator.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionCloseAnimator.h"
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupTransitionGenericCloseAnimator : _LNPopupTransitionCloseAnimator
14 | 
15 | @end
16 | 
17 | NS_ASSUME_NONNULL_END
18 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionGenericCloseAnimator.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionGenericCloseAnimator.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionGenericCloseAnimator.h"
10 | 
11 | @implementation _LNPopupTransitionGenericCloseAnimator
12 | {
13 | 	NSShadow* _targetShadow;
14 | }
15 | 
16 | - (void)animateWithAnimator:(UIViewPropertyAnimator *)animator otherAnimations:(void (^)(void))otherAnimations
17 | {
18 | 	[super animateWithAnimator:animator otherAnimations:otherAnimations];
19 | 	
20 | 	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((animator.duration * 0.38) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
21 | 		[animator addAnimations:^{
22 | 			self.transitionView.cornerRadius = self.popupBar.imageView.cornerRadius;
23 | 		}];
24 | 	});
25 | }
26 | 
27 | - (void)beforeAnyAnimation
28 | {
29 | 	[super beforeAnyAnimation];
30 | 	
31 | 	_targetShadow = self.popupBar.imageView.shadow.copy;
32 | 	
33 | 	NSShadow* hiddenShadow = [_targetShadow copy];
34 | 	hiddenShadow.shadowColor = [_targetShadow.shadowColor colorWithAlphaComponent:0.0];
35 | 	self.transitionView.shadow = hiddenShadow;
36 | }
37 | 
38 | - (void)performAdditionalAnimations
39 | {
40 | 	[super performAdditionalAnimations];
41 | 	
42 | 	self.transitionView.shadow = _targetShadow;
43 | }
44 | 
45 | @end
46 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionGenericOpenAnimator.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionGenericOpenAnimator.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionOpenAnimator.h"
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNPopupTransitionGenericOpenAnimator : _LNPopupTransitionOpenAnimator
14 | 
15 | @end
16 | 
17 | NS_ASSUME_NONNULL_END
18 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionGenericOpenAnimator.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionGenericOpenAnimator.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionGenericOpenAnimator.h"
10 | 
11 | @implementation _LNPopupTransitionGenericOpenAnimator
12 | {
13 | 	NSShadow* _targetShadow;
14 | }
15 | 
16 | - (void)beforeAnyAnimation
17 | {
18 | 	[super beforeAnyAnimation];
19 | 	
20 | 	self.transitionView.shadow = self.popupBar.imageView.shadow.copy;
21 | 	self.transitionView.cornerRadius = self.scaledBarImageViewCornerRadius;
22 | 	
23 | 	_targetShadow = [self.transitionView.shadow copy];
24 | 	_targetShadow.shadowColor = [_targetShadow.shadowColor colorWithAlphaComponent:0.0];
25 | }
26 | 
27 | - (void)performAdditionalAnimations
28 | {
29 | 	[super performAdditionalAnimations];
30 | 	
31 | 	self.transitionView.shadow = _targetShadow;
32 | 	self.transitionView.cornerRadius = 0.0;
33 | }
34 | 
35 | @end
36 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionOpenAnimator.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionOpenAnimator.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import "_LNPopupTransitionAnimator.h"
11 | #import <LNPopupController/LNPopupBar.h>
12 | #import <LNPopupController/LNPopupContentView.h>
13 | #import "_LNPopupTransitionView.h"
14 | 
15 | NS_ASSUME_NONNULL_BEGIN
16 | 
17 | @interface _LNPopupTransitionOpenAnimator : _LNPopupTransitionAnimator
18 | 
19 | @end
20 | 
21 | NS_ASSUME_NONNULL_END
22 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionOpenAnimator.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionOpenAnimator.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionOpenAnimator.h"
10 | #import <objc/runtime.h>
11 | 
12 | @implementation _LNPopupTransitionOpenAnimator
13 | 
14 | - (CGRect)sourceFrame
15 | {
16 | 	return [self.popupBar.imageView.window convertRect:self.popupBar.imageView.bounds fromView:self.popupBar.imageView];
17 | }
18 | 
19 | - (CGRect)targetFrame
20 | {
21 | 	return [self.popupContentView.window convertRect:self.transitionView.sourceView.bounds fromView:self.transitionView.sourceView];;
22 | }
23 | 
24 | - (CGAffineTransform)transform
25 | {
26 | 	CGFloat ratioX = self.sourceFrame.size.width / self.targetFrame.size.width;
27 | 	CGFloat ratioY = self.sourceFrame.size.height / self.targetFrame.size.height;
28 | 	return CGAffineTransformMakeScale(ratioX, ratioY);
29 | }
30 | 
31 | - (CGFloat)scaledBarImageViewCornerRadius
32 | {
33 | 	return self.popupBar.imageView.cornerRadius * self.targetFrame.size.width / self.popupBar.imageView.bounds.size.width;
34 | }
35 | 
36 | - (NSShadow *)scaledBarImageViewShadow
37 | {
38 | 	NSShadow* scaled = self.popupBar.imageView.shadow.copy;
39 | 	scaled.shadowBlurRadius = scaled.shadowBlurRadius * self.targetFrame.size.width / self.popupBar.imageView.bounds.size.width;
40 | 	return scaled;
41 | }
42 | 
43 | - (LNPopupPresentationState)targetState
44 | {
45 | 	return LNPopupPresentationStateOpen;
46 | }
47 | 
48 | - (void)beforeAnyAnimation
49 | {
50 | 	[super beforeAnyAnimation];
51 | 	
52 | 	self.crossfadeView.alpha = 1.0;
53 | 	self.crossfadeView.cornerRadius = self.popupBar.imageView.cornerRadius;
54 | }
55 | 
56 | - (void)performBeforeAdditionalAnimations
57 | {
58 | 	[super performBeforeAdditionalAnimations];
59 | 	
60 | 	self.transitionView.sourceViewTransform = self.transform;
61 | }
62 | 
63 | - (void)performAdditionalAnimations
64 | {
65 | 	[super performAdditionalAnimations];
66 | 	
67 | 	self.transitionView.frame = self.targetFrame;
68 | 	self.transitionView.sourceViewTransform = CGAffineTransformIdentity;
69 | 	self.crossfadeView.cornerRadius = self.transitionView.cornerRadius;
70 | }
71 | 
72 | - (void)performAdditional01Animations
73 | {
74 | 	[super performAdditional01Animations];
75 | 	
76 | 	self.crossfadeView.alpha = 0.0;
77 | }
78 | 
79 | @end
80 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionPreferredCloseAnimator.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionPreferredCloseAnimator.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionCloseAnimator.h"
10 | #import <LNPopupController/UIViewController+LNPopupSupport.h>
11 | 
12 | NS_ASSUME_NONNULL_BEGIN
13 | 
14 | @interface _LNPopupTransitionPreferredCloseAnimator : _LNPopupTransitionCloseAnimator
15 | 
16 | @property (nonatomic, strong, readonly) UIView<LNPopupTransitionView>* view;
17 | 
18 | @end
19 | 
20 | NS_ASSUME_NONNULL_END
21 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionPreferredCloseAnimator.mm:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionPreferredCloseAnimator.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionPreferredCloseAnimator.h"
10 | 
11 | @implementation _LNPopupTransitionPreferredCloseAnimator
12 | {
13 | 	CGFloat _originalCornerRadius;
14 | 	NSShadow* _originalShadow;
15 | 	BOOL _supportsShadow;
16 | }
17 | 
18 | @dynamic view;
19 | 
20 | - (void)beforeAnyAnimation
21 | {
22 | 	[super beforeAnyAnimation];
23 | 	
24 | 	if([self.view respondsToSelector:@selector(supportsShadow)])
25 | 	{
26 | 		_supportsShadow = self.view.supportsShadow;
27 | 	}
28 | 	else
29 | 	{
30 | 		_supportsShadow = YES;
31 | 	}
32 | 	
33 | 	_originalCornerRadius = self.view.cornerRadius;
34 | 	if(_supportsShadow)
35 | 	{
36 | 		_originalShadow = self.view.shadow.copy;
37 | 	}
38 | 	else
39 | 	{
40 | 		_originalShadow = nil;
41 | 	}
42 | 	
43 | 	self.crossfadeView.cornerRadius = self.view.cornerRadius;
44 | }
45 | 
46 | - (void)performAdditionalAnimations
47 | {
48 | 	[super performAdditionalAnimations];
49 | 	
50 | 	self.view.cornerRadius = self.scaledBarImageViewCornerRadius;
51 | 	self.crossfadeView.cornerRadius = self.popupBar.imageView.cornerRadius;
52 | 	if(_supportsShadow)
53 | 	{
54 | 		self.view.shadow = self.scaledBarImageViewShadow;
55 | 	}
56 | 	else
57 | 	{
58 | 		self.transitionView.shadow = self.popupBar.imageView.shadow.copy;
59 | 	}
60 | }
61 | 
62 | - (void)performAdditionalCompletion
63 | {
64 | 	self.view.cornerRadius = _originalCornerRadius;
65 | 	if(_supportsShadow)
66 | 	{
67 | 		self.view.shadow = _originalShadow;
68 | 	}
69 | 	else
70 | 	{
71 | 		self.transitionView.shadow = _originalShadow;
72 | 	}
73 | 	
74 | 	[super performAdditionalCompletion];
75 | }
76 | 
77 | @end
78 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionPreferredOpenAnimator.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionPreferredOpenAnimator.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionOpenAnimator.h"
10 | #import <LNPopupController/UIViewController+LNPopupSupport.h>
11 | 
12 | NS_ASSUME_NONNULL_BEGIN
13 | 
14 | @interface _LNPopupTransitionPreferredOpenAnimator : _LNPopupTransitionOpenAnimator
15 | 
16 | @property (nonatomic, strong, readonly) UIView<LNPopupTransitionView>* view;
17 | 
18 | @end
19 | 
20 | NS_ASSUME_NONNULL_END
21 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionPreferredOpenAnimator.mm:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionPreferredOpenAnimator.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-24.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNPopupTransitionPreferredOpenAnimator.h"
10 | 
11 | @implementation _LNPopupTransitionPreferredOpenAnimator
12 | {
13 | 	CGFloat _originalCornerRadius;
14 | 	NSShadow* _originalShadow;
15 | 	BOOL _supportsShadow;
16 | }
17 | 
18 | @dynamic view;
19 | 
20 | - (void)beforeAnyAnimation
21 | {
22 | 	[super beforeAnyAnimation];
23 | 	
24 | 	if([self.view respondsToSelector:@selector(supportsShadow)])
25 | 	{
26 | 		_supportsShadow = self.view.supportsShadow;
27 | 	}
28 | 	else
29 | 	{
30 | 		_supportsShadow = YES;
31 | 	}
32 | 	
33 | 	_originalCornerRadius = self.view.cornerRadius;
34 | 	if(_supportsShadow)
35 | 	{
36 | 		_originalShadow = self.view.shadow.copy;
37 | 	}
38 | 	else
39 | 	{
40 | 		_originalShadow = nil;
41 | 	}
42 | 	
43 | 	self.view.cornerRadius = self.scaledBarImageViewCornerRadius;
44 | 	if(_supportsShadow)
45 | 	{
46 | 		self.view.shadow = self.scaledBarImageViewShadow;
47 | 	}
48 | 	else
49 | 	{
50 | 		self.transitionView.shadow = self.popupBar.imageView.shadow.copy;
51 | 	}
52 | }
53 | 
54 | - (void)performAdditionalAnimations
55 | {
56 | 	[super performAdditionalAnimations];
57 | 	
58 | 	self.view.cornerRadius = _originalCornerRadius;
59 | 	self.view.shadow = _originalShadow;
60 | 	
61 | 	if(_supportsShadow)
62 | 	{
63 | 		self.view.shadow = _originalShadow;
64 | 	}
65 | 	else
66 | 	{
67 | 		self.transitionView.shadow = _originalShadow;
68 | 	}
69 | 	
70 | 	self.crossfadeView.cornerRadius = self.view.cornerRadius;
71 | }
72 | 
73 | @end
74 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupTransitionView.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupTransitionView.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2025-03-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import <LNPopupController/UIViewController+LNPopupSupport.h>
11 | 
12 | NS_ASSUME_NONNULL_BEGIN
13 | 
14 | @interface _LNPopupTransitionView : UIView <LNPopupTransitionView>
15 | 
16 | + (instancetype)transitionViewWithSourceView:(UIView*)sourceView;
17 | 
18 | - (instancetype)initWithSourceView:(UIView*)sourceView;
19 | 
20 | - (void)setTargetFrameUpdatingTransform:(CGRect)targetFrame;
21 | 
22 | @property (nonatomic, strong, readonly) UIView* sourceView;
23 | 
24 | @property (nonatomic, copy) NSShadow* shadow;
25 | @property (nonatomic, assign) CGFloat cornerRadius;
26 | @property (nonatomic, assign) BOOL layerAlwaysMasksToBounds;
27 | 
28 | @property (nonatomic, assign) CGAffineTransform sourceViewTransform;
29 | 
30 | @end
31 | 
32 | NS_ASSUME_NONNULL_END
33 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNPopupUIBarAppearanceProxy.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNPopupUIBarAppearanceProxy.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2023-08-30.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | 
11 | #if ! LNPopupControllerEnforceStrictClean
12 | 
13 | NS_ASSUME_NONNULL_BEGIN
14 | 
15 | @interface _LNPopupUIBarAppearanceProxy : NSObject
16 | 
17 | - (instancetype)initWithProxiedObject:(id)obj shadowColorHandler:(BOOL(^)(void))shadowColorHandler;
18 | 
19 | @end
20 | 
21 | NS_ASSUME_NONNULL_END
22 | 
23 | #endif
24 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNWeakRef.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNWeakRef.h
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <Foundation/Foundation.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface _LNWeakRef : NSObject
14 | 
15 | @property (nonatomic, weak, readonly) id object;
16 | 
17 | + (instancetype)refWithObject:(id)object;
18 | 
19 | @end
20 | 
21 | NS_ASSUME_NONNULL_END
22 | 


--------------------------------------------------------------------------------
/LNPopupController/LNPopupController/Private/_LNWeakRef.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  _LNWeakRef.m
 3 | //  LNPopupController
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "_LNWeakRef.h"
10 | 
11 | @implementation _LNWeakRef
12 | 
13 | + (instancetype)refWithObject:(id)object
14 | {
15 | 	if(object == nil)
16 | 	{
17 | 		return nil;
18 | 	}
19 | 	
20 | 	_LNWeakRef* rv = [self new];
21 | 	rv->_object = object;
22 | 	
23 | 	return rv;
24 | }
25 | 
26 | @end
27 | 


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupBar.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupBar.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupBarAppearance.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupBarAppearance.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupCloseButton.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupCloseButton.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupContentView.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupContentView.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupController.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupCustomBarViewController.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupCustomBarViewController.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupDefinitions.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupDefinitions.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupImageView.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupImageView.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/LNPopupItem.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/LNPopupItem.h


--------------------------------------------------------------------------------
/LNPopupController/include/LNPopupController/UIViewController+LNPopupSupport.h:
--------------------------------------------------------------------------------
1 | ../../LNPopupController/UIViewController+LNPopupSupport.h


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 |    version = "1.0">
4 |    <FileRef
5 |       location = "self:">
6 |    </FileRef>
7 | </Workspace>
8 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | 	<key>IDEDidComputeMac32BitWarning</key>
6 | 	<true/>
7 | </dict>
8 | </plist>
9 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample.xcodeproj/xcshareddata/xcschemes/LNPopupControllerExampleNoPopup.xcscheme:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <Scheme
 3 |    LastUpgradeVersion = "9999"
 4 |    version = "2.0">
 5 |    <BuildAction
 6 |       parallelizeBuildables = "YES"
 7 |       buildImplicitDependencies = "YES">
 8 |       <BuildActionEntries>
 9 |          <BuildActionEntry
10 |             buildForTesting = "YES"
11 |             buildForRunning = "YES"
12 |             buildForProfiling = "YES"
13 |             buildForArchiving = "YES"
14 |             buildForAnalyzing = "YES">
15 |             <BuildableReference
16 |                BuildableIdentifier = "primary"
17 |                BlueprintIdentifier = "39FAFC2E24E71A6C008BBC2D"
18 |                BuildableName = "LNPopupControllerExampleNoPopup.app"
19 |                BlueprintName = "LNPopupControllerExampleNoPopup"
20 |                ReferencedContainer = "container:LNPopupControllerExample.xcodeproj">
21 |             </BuildableReference>
22 |          </BuildActionEntry>
23 |       </BuildActionEntries>
24 |    </BuildAction>
25 |    <TestAction
26 |       buildConfiguration = "Debug"
27 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29 |       shouldUseLaunchSchemeArgsEnv = "YES">
30 |       <Testables>
31 |       </Testables>
32 |    </TestAction>
33 |    <LaunchAction
34 |       buildConfiguration = "Debug"
35 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37 |       launchStyle = "0"
38 |       useCustomWorkingDirectory = "NO"
39 |       ignoresPersistentStateOnLaunch = "NO"
40 |       debugDocumentVersioning = "NO"
41 |       debugXPCServices = "NO"
42 |       debugServiceExtension = "internal"
43 |       allowLocationSimulation = "YES"
44 |       queueDebuggingEnabled = "No">
45 |       <BuildableProductRunnable
46 |          runnableDebuggingMode = "0">
47 |          <BuildableReference
48 |             BuildableIdentifier = "primary"
49 |             BlueprintIdentifier = "39FAFC2E24E71A6C008BBC2D"
50 |             BuildableName = "LNPopupControllerExampleNoPopup.app"
51 |             BlueprintName = "LNPopupControllerExampleNoPopup"
52 |             ReferencedContainer = "container:LNPopupControllerExample.xcodeproj">
53 |          </BuildableReference>
54 |       </BuildableProductRunnable>
55 |    </LaunchAction>
56 |    <ProfileAction
57 |       buildConfiguration = "Release"
58 |       shouldUseLaunchSchemeArgsEnv = "YES"
59 |       savedToolIdentifier = ""
60 |       useCustomWorkingDirectory = "NO"
61 |       debugDocumentVersioning = "YES">
62 |       <BuildableProductRunnable
63 |          runnableDebuggingMode = "0">
64 |          <BuildableReference
65 |             BuildableIdentifier = "primary"
66 |             BlueprintIdentifier = "39FAFC2E24E71A6C008BBC2D"
67 |             BuildableName = "LNPopupControllerExampleNoPopup.app"
68 |             BlueprintName = "LNPopupControllerExampleNoPopup"
69 |             ReferencedContainer = "container:LNPopupControllerExample.xcodeproj">
70 |          </BuildableReference>
71 |       </BuildableProductRunnable>
72 |    </ProfileAction>
73 |    <AnalyzeAction
74 |       buildConfiguration = "Debug">
75 |    </AnalyzeAction>
76 |    <ArchiveAction
77 |       buildConfiguration = "Release"
78 |       revealArchiveInOrganizer = "YES">
79 |    </ArchiveAction>
80 | </Scheme>
81 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/CustomBarScene/CustomMapBarViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  CustomMapBarViewController.swift
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2016-12-30.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #if LNPOPUP
10 | import UIKit
11 | 
12 | class CustomMapBarView: UIView {
13 | 	override var frame: CGRect {
14 | 		didSet {
15 | 			print("Size: \(self.frame)")
16 | 		}
17 | 	}
18 | }
19 | 
20 | class CustomMapBarViewController: LNPopupCustomBarViewController {
21 | 	@IBOutlet weak var searchBar: UISearchBar!
22 | 	@IBOutlet var heightConstraint: NSLayoutConstraint!
23 | 
24 | 	override var wantsDefaultTapGestureRecognizer: Bool {
25 | 		return false
26 | 	}
27 | 	
28 | 	override var wantsDefaultHighlightGestureRecognizer: Bool {
29 | 		return false
30 | 	}
31 | 	
32 | 	fileprivate func updateConstraint() {
33 | 		heightConstraint.constant = 65
34 | 		self.preferredContentSize = view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
35 | 	}
36 | 	
37 | 	override func viewDidLoad() {
38 | 		super.viewDidLoad()
39 | 		
40 | 		view.translatesAutoresizingMaskIntoConstraints = false
41 | 		
42 | 		updateConstraint()
43 | 		
44 | 		guard let bg = (containingPopupBar?.value(forKey: "backgroundView") as? UIView) else {
45 | 			return
46 | 		}
47 | 		
48 | 		bg.clipsToBounds = true
49 | 		bg.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
50 | 		bg.layer.cornerRadius = 20
51 | 		bg.layer.cornerCurve = .continuous
52 | 		
53 | 	}
54 | 	
55 | 	override func viewWillAppear(_ animated: Bool) {
56 | 		super.viewWillAppear(animated)
57 | 	}
58 | 	
59 | 	override func viewIsAppearing(_ animated: Bool) {
60 | 		super.viewIsAppearing(animated)
61 | 	}
62 | 	
63 | 	override func viewDidAppear(_ animated: Bool) {
64 | 		super.viewDidAppear(animated)
65 | 	}
66 | 	
67 | 	override func viewWillDisappear(_ animated: Bool) {
68 | 		super.viewWillDisappear(animated)
69 | 	}
70 | 	
71 | 	override func viewDidDisappear(_ animated: Bool) {
72 | 		super.viewDidDisappear(animated)
73 | 	}
74 | 	
75 | 	override func popupItemDidUpdate() {
76 | 		searchBar.text = popupItem.title
77 | 	}
78 | 	
79 | 	override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
80 | 		super.viewWillTransition(to: size, with: coordinator)
81 | 		
82 | 		coordinator.animate(alongsideTransition: { [unowned self] context in
83 | 			updateConstraint()
84 | 		}, completion: nil)
85 | 	}
86 | }
87 | #endif
88 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/CustomBarScene/LocationsController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LocationsController.swift
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2016-12-30.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class LocationsController: UITableViewController, UISearchBarDelegate {
12 | 	@IBOutlet weak var searchBar: UISearchBar!
13 | 		
14 | 	override func viewDidLoad() {
15 | 		super.viewDidLoad()
16 | 		
17 | 		searchBar.delegate = self
18 | 	}
19 | 	
20 | 	override func viewWillAppear(_ animated: Bool) {
21 | 		super.viewWillAppear(animated)
22 | 		
23 | #if LNPOPUP
24 | 		searchBar.text = popupItem.title
25 | #endif
26 | 	}
27 | 	
28 | 	override func scrollViewDidScroll(_ scrollView: UIScrollView) {
29 | 		searchBar.resignFirstResponder()
30 | 	}
31 | 	
32 | 	override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
33 | 		tableView.deselectRow(at: indexPath, animated: true)
34 | 		searchBar.resignFirstResponder()
35 | #if LNPOPUP
36 | 		popupItem.title = tableView.cellForRow(at: indexPath)?.textLabel?.text
37 | 		popupPresentationContainer?.closePopup(animated: true, completion: nil)
38 | #endif
39 | 	}
40 | 	
41 | 	func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
42 | #if LNPOPUP
43 | 		popupItem.title = searchText
44 | #endif
45 | 	}
46 | }
47 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/CustomBarScene_ManualLayout/ManualLayoutCustomBarViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  ManualLayoutCustomBarViewController.swift
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2020-09-01.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #if LNPOPUP
10 | @objc public
11 | class ManualLayoutCustomBarViewController: LNPopupCustomBarViewController {
12 | 	let centeredButton = UIButton(type: .system)
13 | 	let leftButton = UIButton(type: .system)
14 | 	let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemChromeMaterial))
15 | 	
16 | 	public
17 | override func viewDidLoad() {
18 | 		super.viewDidLoad()
19 | 		
20 | 		view.autoresizingMask = []
21 | 		
22 | 		backgroundView.layer.masksToBounds = true
23 | 		backgroundView.layer.cornerCurve = .continuous
24 | 		backgroundView.layer.cornerRadius = 15
25 | 		view.addSubview(backgroundView)
26 | 		
27 | 		centeredButton.setTitle(NSLocalizedString("Centered", comment: ""), for: .normal)
28 | 		centeredButton.titleLabel?.font = UIFont.preferredFont(forTextStyle: .headline)
29 | 		centeredButton.sizeToFit()
30 | 		view.addSubview(centeredButton)
31 | 		
32 | 		leftButton.setTitle("<- \(NSLocalizedString("Leading", comment: ""))", for: .normal)
33 | 		leftButton.titleLabel?.font = UIFont.preferredFont(forTextStyle: .headline)
34 | 		leftButton.sizeToFit()
35 | 		view.addSubview(leftButton)
36 | 		
37 | 		self.preferredContentSize = CGSize(width: 0, height: 50)
38 | 		animateSize()
39 | 	}
40 | 	
41 | 	var idx = 0
42 | 	func animateSize() {
43 | 		idx = 1 - idx;
44 | 		UIView.animate(withDuration: 1.0, delay: 0.0, options: [.curveEaseInOut, .allowUserInteraction]) {
45 | 			self.preferredContentSize = CGSize(width: 0, height: 50 + self.idx * 50)
46 | 		} completion: { [weak self] _ in
47 | 			guard let self else {
48 | 				return
49 | 			}
50 | 			
51 | 			self.animateSize()
52 | 		}
53 | 	}
54 | 	
55 | 	public
56 | override func viewDidLayoutSubviews() {
57 | 		super.viewDidLayoutSubviews()
58 | 		
59 | 		let insetLeft = CGFloat.maximum(view.safeAreaInsets.left, 20)
60 | 		let insetRight = CGFloat.maximum(view.safeAreaInsets.right, 20)
61 | 		
62 | 		backgroundView.frame = CGRect(x: insetLeft, y: 2, width: view.bounds.width - insetLeft - insetRight, height: view.bounds.height - 4)
63 | 		centeredButton.center = backgroundView.center
64 | 		if UIView.userInterfaceLayoutDirection(for: view.semanticContentAttribute) == .leftToRight {
65 | 			leftButton.frame = CGRect(x: insetLeft + 20, y: backgroundView.center.y - leftButton.bounds.size.height / 2, width: leftButton.bounds.size.width, height: leftButton.bounds.size.height)
66 | 		} else {
67 | 			leftButton.frame = CGRect(x: view.bounds.width - insetRight - leftButton.bounds.width - 20, y: backgroundView.center.y - leftButton.bounds.size.height / 2, width: leftButton.bounds.size.width, height: leftButton.bounds.size.height)
68 | 		}
69 | 	}
70 | 	
71 | 	public
72 | override var wantsDefaultTapGestureRecognizer: Bool {
73 | 		return false
74 | 	}
75 | 	
76 | 	public
77 | override var wantsDefaultPanGestureRecognizer: Bool {
78 | 		return false
79 | 	}
80 | 	
81 | 	public
82 | override var wantsDefaultHighlightGestureRecognizer: Bool {
83 | 		return false
84 | 	}
85 | }
86 | #endif
87 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CADisableMinimumFrameDurationOnPhone</key>
 6 | 	<true/>
 7 | 	<key>CFBundleDevelopmentRegion</key>
 8 | 	<string>en</string>
 9 | 	<key>CFBundleDisplayName</key>
10 | 	<string>LNPopup</string>
11 | 	<key>CFBundleExecutable</key>
12 | 	<string>$(EXECUTABLE_NAME)</string>
13 | 	<key>CFBundleIdentifier</key>
14 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
15 | 	<key>CFBundleInfoDictionaryVersion</key>
16 | 	<string>6.0</string>
17 | 	<key>CFBundleName</key>
18 | 	<string>$(PRODUCT_NAME)</string>
19 | 	<key>CFBundlePackageType</key>
20 | 	<string>APPL</string>
21 | 	<key>CFBundleShortVersionString</key>
22 | 	<string>3.0.7</string>
23 | 	<key>CFBundleSignature</key>
24 | 	<string>????</string>
25 | 	<key>CFBundleVersion</key>
26 | 	<string>1</string>
27 | 	<key>LSApplicationCategoryType</key>
28 | 	<string>public.app-category.developer-tools</string>
29 | 	<key>LSRequiresIPhoneOS</key>
30 | 	<true/>
31 | 	<key>UIApplicationSceneManifest</key>
32 | 	<dict>
33 | 		<key>UIApplicationSupportsMultipleScenes</key>
34 | 		<true/>
35 | 		<key>UISceneConfigurations</key>
36 | 		<dict>
37 | 			<key>UIWindowSceneSessionRoleApplication</key>
38 | 			<array>
39 | 				<dict>
40 | 					<key>UISceneConfigurationName</key>
41 | 					<string>LNPopupExample</string>
42 | 					<key>UISceneDelegateClassName</key>
43 | 					<string>SceneDelegate</string>
44 | 					<key>UISceneStoryboardFile</key>
45 | 					<string>Main</string>
46 | 				</dict>
47 | 			</array>
48 | 		</dict>
49 | 	</dict>
50 | 	<key>UIApplicationSupportsIndirectInputEvents</key>
51 | 	<true/>
52 | 	<key>UILaunchStoryboardName</key>
53 | 	<string>LaunchScreen</string>
54 | 	<key>UIMainStoryboardFile</key>
55 | 	<string>Main</string>
56 | 	<key>UIRequiredDeviceCapabilities</key>
57 | 	<array>
58 | 		<string>armv7</string>
59 | 	</array>
60 | 	<key>UIRequiresFullScreen</key>
61 | 	<false/>
62 | 	<key>UIStatusBarTintParameters</key>
63 | 	<dict>
64 | 		<key>UINavigationBar</key>
65 | 		<dict>
66 | 			<key>Style</key>
67 | 			<string>UIBarStyleDefault</string>
68 | 			<key>Translucent</key>
69 | 			<true/>
70 | 		</dict>
71 | 	</dict>
72 | 	<key>UISupportedInterfaceOrientations</key>
73 | 	<array>
74 | 		<string>UIInterfaceOrientationLandscapeLeft</string>
75 | 		<string>UIInterfaceOrientationLandscapeRight</string>
76 | 		<string>UIInterfaceOrientationPortrait</string>
77 | 	</array>
78 | 	<key>UISupportedInterfaceOrientations~ipad</key>
79 | 	<array>
80 | 		<string>UIInterfaceOrientationLandscapeLeft</string>
81 | 		<string>UIInterfaceOrientationLandscapeRight</string>
82 | 		<string>UIInterfaceOrientationPortrait</string>
83 | 		<string>UIInterfaceOrientationPortraitUpsideDown</string>
84 | 	</array>
85 | </dict>
86 | </plist>
87 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/LNPopupControllerExample.entitlements:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>com.apple.security.application-groups</key>
 6 | 	<array>
 7 | 		<string>group.com.LeoNatan.LNPopupSettings</string>
 8 | 	</array>
 9 | </dict>
10 | </plist>
11 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/LNPopupControllerExampleNoPopup-Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CADisableMinimumFrameDurationOnPhone</key>
 6 | 	<true/>
 7 | 	<key>CFBundleDevelopmentRegion</key>
 8 | 	<string>en</string>
 9 | 	<key>CFBundleDisplayName</key>
10 | 	<string>LNPopup</string>
11 | 	<key>CFBundleExecutable</key>
12 | 	<string>$(EXECUTABLE_NAME)</string>
13 | 	<key>CFBundleIdentifier</key>
14 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
15 | 	<key>CFBundleInfoDictionaryVersion</key>
16 | 	<string>6.0</string>
17 | 	<key>CFBundleName</key>
18 | 	<string>$(PRODUCT_NAME)</string>
19 | 	<key>CFBundlePackageType</key>
20 | 	<string>APPL</string>
21 | 	<key>CFBundleShortVersionString</key>
22 | 	<string>1.0</string>
23 | 	<key>CFBundleSignature</key>
24 | 	<string>????</string>
25 | 	<key>CFBundleVersion</key>
26 | 	<string>1</string>
27 | 	<key>LSRequiresIPhoneOS</key>
28 | 	<true/>
29 | 	<key>UIApplicationSceneManifest</key>
30 | 	<dict>
31 | 		<key>UIApplicationSupportsMultipleScenes</key>
32 | 		<true/>
33 | 		<key>UISceneConfigurations</key>
34 | 		<dict>
35 | 			<key>UIWindowSceneSessionRoleApplication</key>
36 | 			<array>
37 | 				<dict>
38 | 					<key>UISceneConfigurationName</key>
39 | 					<string>LNPopupExample</string>
40 | 					<key>UISceneDelegateClassName</key>
41 | 					<string>SceneDelegate</string>
42 | 					<key>UISceneStoryboardFile</key>
43 | 					<string>Main</string>
44 | 				</dict>
45 | 			</array>
46 | 		</dict>
47 | 	</dict>
48 | 	<key>UILaunchStoryboardName</key>
49 | 	<string>LaunchScreen</string>
50 | 	<key>UIMainStoryboardFile</key>
51 | 	<string>Main</string>
52 | 	<key>UIRequiredDeviceCapabilities</key>
53 | 	<array>
54 | 		<string>armv7</string>
55 | 	</array>
56 | 	<key>UIRequiresFullScreen</key>
57 | 	<false/>
58 | 	<key>UIStatusBarTintParameters</key>
59 | 	<dict>
60 | 		<key>UINavigationBar</key>
61 | 		<dict>
62 | 			<key>Style</key>
63 | 			<string>UIBarStyleDefault</string>
64 | 			<key>Translucent</key>
65 | 			<true/>
66 | 		</dict>
67 | 	</dict>
68 | 	<key>UISupportedInterfaceOrientations</key>
69 | 	<array>
70 | 		<string>UIInterfaceOrientationPortrait</string>
71 | 		<string>UIInterfaceOrientationLandscapeLeft</string>
72 | 		<string>UIInterfaceOrientationLandscapeRight</string>
73 | 		<string>UIInterfaceOrientationPortraitUpsideDown</string>
74 | 	</array>
75 | 	<key>UISupportedInterfaceOrientations~ipad</key>
76 | 	<array>
77 | 		<string>UIInterfaceOrientationPortrait</string>
78 | 		<string>UIInterfaceOrientationPortraitUpsideDown</string>
79 | 		<string>UIInterfaceOrientationLandscapeLeft</string>
80 | 		<string>UIInterfaceOrientationLandscapeRight</string>
81 | 	</array>
82 | 	<key>LSApplicationCategoryType</key>
83 | 	<string>public.app-category.developer-tools</string>
84 | </dict>
85 | </plist>
86 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/MusicScene/MusicCell.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  MusicCell.swift
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class MusicCell: UITableViewCell {
12 | 	let selectionEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial))
13 | 	
14 | 	required init?(coder: NSCoder) {
15 | 		super.init(coder: coder)
16 | 		
17 | 		selectionEffectView.frame = bounds
18 | 		selectionEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
19 | 		selectionEffectView.isHidden = true
20 | 		addSubview(selectionEffectView)
21 | 		sendSubviewToBack(selectionEffectView)
22 | 		
23 | 		selectionStyle = .none
24 | 	}
25 | 	
26 | 	override func layoutSubviews() {
27 | 		super.layoutSubviews()
28 | 		
29 | 		imageView?.layer.cornerRadius = 5
30 | 		imageView?.layer.cornerCurve = .continuous
31 | 		
32 | 		if UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .leftToRight {
33 | 			imageView?.frame = CGRect(x: layoutMargins.left, y: bounds.height / 2 - 24, width: 48, height: 48)
34 | 			
35 | 			textLabel?.textAlignment = .left
36 | 			textLabel?.lineBreakMode = .byTruncatingTail
37 | 			textLabel?.frame = CGRect(x: imageView!.frame.maxX + 20, y: textLabel!.frame.minY, width: accessoryView!.frame.minX - imageView!.frame.maxX - 40, height: textLabel!.frame.height)
38 | 			detailTextLabel?.textAlignment = .left
39 | 			detailTextLabel?.lineBreakMode = .byTruncatingTail
40 | 			detailTextLabel?.frame = CGRect(x: imageView!.frame.maxX + 20, y: detailTextLabel!.frame.minY, width: accessoryView!.frame.minX - imageView!.frame.maxX - 40, height: detailTextLabel!.frame.height)
41 | 			
42 | 			separatorInset = UIEdgeInsets(top: 0, left: textLabel!.frame.origin.x, bottom: 0, right: 0)
43 | 		} else {
44 | 			imageView?.frame = CGRect(x: contentView.bounds.width - layoutMargins.right - 48, y: bounds.height / 2 - 24, width: 48, height: 48)
45 | 			
46 | 			textLabel?.textAlignment = .right
47 | 			textLabel?.lineBreakMode = .byTruncatingHead
48 | 			textLabel?.frame = CGRect(x: 20, y: textLabel!.frame.minY, width: contentView.bounds.width - (2 * layoutMargins.right) - imageView!.bounds.width - 20, height: textLabel!.frame.height)
49 | 			detailTextLabel?.textAlignment = .right
50 | 			detailTextLabel?.lineBreakMode = .byTruncatingHead
51 | 			detailTextLabel?.frame = CGRect(x: 20, y: detailTextLabel!.frame.minY, width: contentView.bounds.width - (2 * layoutMargins.right) - imageView!.bounds.width - 20, height: detailTextLabel!.frame.height)
52 | 			
53 | 			separatorInset = UIEdgeInsets(top: 0, left: textLabel!.frame.origin.x, bottom: 0, right: 0)
54 | 		}
55 | 	}
56 | 	
57 | 	override func setHighlighted(_ highlighted: Bool, animated: Bool) {
58 | 		guard isHighlighted != highlighted else {
59 | 			return
60 | 		}
61 | 
62 | 		super.setHighlighted(highlighted, animated: animated)
63 | 
64 | 		selectionEffectView.alpha = highlighted ? 0.0 : 1.0
65 | 		selectionEffectView.isHidden = false
66 | 		UIView.animate(withDuration: highlighted ? 0.0 : 0.35) {
67 | 			self.selectionEffectView.alpha = highlighted ? 1.0 : 0.0
68 | 		} completion: { _ in
69 | 			self.selectionEffectView.isHidden = highlighted == false
70 | 		}
71 | 	}
72 | }
73 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/MusicScene/PortraitTabBarController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  PortraitTabBarController.swift
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class PortraitTabBarController: UITabBarController {
12 | 
13 | 	override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
14 | 		return .portrait
15 | 	}
16 | 
17 | }
18 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Settings/Base.lproj/Settings.storyboard:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="KD9-4L-yPt">
 3 |     <device id="retina6_12" orientation="portrait" appearance="light"/>
 4 |     <dependencies>
 5 |         <deployment identifier="iOS"/>
 6 |         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
 7 |         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
 8 |     </dependencies>
 9 |     <scenes>
10 |         <!--Settings View Controller-->
11 |         <scene sceneID="i41-nV-z2g">
12 |             <objects>
13 |                 <hostingController storyboardIdentifier="SettingsView" id="27B-rg-hpf" customClass="SettingsViewController" customModule="LNPopupControllerExample" customModuleProvider="target" sceneMemberID="viewController">
14 |                     <navigationItem key="navigationItem" leftItemsSupplementBackButton="YES" id="KGL-NH-gfY"/>
15 |                 </hostingController>
16 |                 <placeholder placeholderIdentifier="IBFirstResponder" id="HqC-rD-hqG" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
17 |             </objects>
18 |             <point key="canvasLocation" x="1740" y="-2439"/>
19 |         </scene>
20 |         <!--Navigation Controller-->
21 |         <scene sceneID="Y6z-Jl-kP6">
22 |             <objects>
23 |                 <navigationController storyboardIdentifier="Settings" id="KD9-4L-yPt" sceneMemberID="viewController">
24 |                     <navigationBar key="navigationBar" contentMode="scaleToFill" largeTitles="YES" id="ism-MM-egy">
25 |                         <rect key="frame" x="0.0" y="59" width="393" height="96"/>
26 |                         <autoresizingMask key="autoresizingMask"/>
27 |                     </navigationBar>
28 |                     <toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Gxc-XC-Tbd">
29 |                         <autoresizingMask key="autoresizingMask"/>
30 |                     </toolbar>
31 |                     <connections>
32 |                         <segue destination="27B-rg-hpf" kind="relationship" relationship="rootViewController" id="B7W-Fa-e97"/>
33 |                     </connections>
34 |                 </navigationController>
35 |                 <placeholder placeholderIdentifier="IBFirstResponder" id="11d-Ub-Fi7" userLabel="First Responder" sceneMemberID="firstResponder"/>
36 |             </objects>
37 |             <point key="canvasLocation" x="904.18604651162786" y="-2439.2703862660946"/>
38 |         </scene>
39 |     </scenes>
40 |     <color key="tintColor" systemColor="systemPinkColor"/>
41 |     <resources>
42 |         <systemColor name="systemPinkColor">
43 |             <color red="1" green="0.17647058823529413" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
44 |         </systemColor>
45 |     </resources>
46 | </document>
47 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/AppDelegate.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  AppDelegate.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | @interface AppDelegate : UIResponder <UIApplicationDelegate>
12 | 
13 | @property (strong, nonatomic) UIWindow* window;
14 | 
15 | @end
16 | 
17 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "colors" : [
 3 |     {
 4 |       "color" : {
 5 |         "platform" : "universal",
 6 |         "reference" : "systemPinkColor"
 7 |       },
 8 |       "idiom" : "universal"
 9 |     }
10 |   ],
11 |   "info" : {
12 |     "author" : "xcode",
13 |     "version" : 1
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "filename" : "icon_1024.png",
 5 |       "idiom" : "universal",
 6 |       "platform" : "ios",
 7 |       "size" : "1024x1024"
 8 |     },
 9 |     {
10 |       "appearances" : [
11 |         {
12 |           "appearance" : "luminosity",
13 |           "value" : "dark"
14 |         }
15 |       ],
16 |       "filename" : "Icon-dark.png",
17 |       "idiom" : "universal",
18 |       "platform" : "ios",
19 |       "size" : "1024x1024"
20 |     },
21 |     {
22 |       "appearances" : [
23 |         {
24 |           "appearance" : "luminosity",
25 |           "value" : "tinted"
26 |         }
27 |       ],
28 |       "filename" : "Icon-tinted.png",
29 |       "idiom" : "universal",
30 |       "platform" : "ios",
31 |       "size" : "1024x1024"
32 |     }
33 |   ],
34 |   "info" : {
35 |     "author" : "xcode",
36 |     "version" : 1
37 |   }
38 | }
39 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIcon.appiconset/Icon-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIcon.appiconset/Icon-dark.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIcon.appiconset/Icon-tinted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIcon.appiconset/Icon-tinted.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIcon.appiconset/icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIcon.appiconset/icon_1024.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIconPopupBar.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "filename" : "icon_1024.png",
 5 |       "idiom" : "universal"
 6 |     },
 7 |     {
 8 |       "appearances" : [
 9 |         {
10 |           "appearance" : "luminosity",
11 |           "value" : "dark"
12 |         }
13 |       ],
14 |       "filename" : "Icon-dark.png",
15 |       "idiom" : "universal"
16 |     }
17 |   ],
18 |   "info" : {
19 |     "author" : "xcode",
20 |     "version" : 1
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIconPopupBar.imageset/Icon-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIconPopupBar.imageset/Icon-dark.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIconPopupBar.imageset/icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/AppIconPopupBar.imageset/icon_1024.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 |   "info" : {
3 |     "author" : "xcode",
4 |     "version" : 1
5 |   }
6 | }
7 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/demoAlbum.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "smackandtoss-blue-orange-abstract-fog-ipad-wallpaper.jpg",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "scale" : "2x"
11 |     },
12 |     {
13 |       "idiom" : "universal",
14 |       "scale" : "3x"
15 |     }
16 |   ],
17 |   "info" : {
18 |     "version" : 1,
19 |     "author" : "xcode"
20 |   }
21 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/demoAlbum.imageset/smackandtoss-blue-orange-abstract-fog-ipad-wallpaper.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/demoAlbum.imageset/smackandtoss-blue-orange-abstract-fog-ipad-wallpaper.jpg


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/gears.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "gears.pdf"
 6 |     }
 7 |   ],
 8 |   "info" : {
 9 |     "version" : 1,
10 |     "author" : "xcode"
11 |   },
12 |   "properties" : {
13 |     "template-rendering-intent" : "template"
14 |   }
15 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/gears.imageset/gears.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/gears.imageset/gears.pdf


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre1.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-80s-hits.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-80s-hits@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-80s-hits@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre1.imageset/genre-image-80s-hits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre1.imageset/genre-image-80s-hits.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre1.imageset/genre-image-80s-hits@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre1.imageset/genre-image-80s-hits@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre1.imageset/genre-image-80s-hits@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre1.imageset/genre-image-80s-hits@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre10.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-country-hits.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-country-hits@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-country-hits@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre10.imageset/genre-image-country-hits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre10.imageset/genre-image-country-hits.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre10.imageset/genre-image-country-hits@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre10.imageset/genre-image-country-hits@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre10.imageset/genre-image-country-hits@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre10.imageset/genre-image-country-hits@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre11.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-dance.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-dance@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-dance@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre11.imageset/genre-image-dance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre11.imageset/genre-image-dance.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre11.imageset/genre-image-dance@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre11.imageset/genre-image-dance@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre11.imageset/genre-image-dance@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre11.imageset/genre-image-dance@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre12.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-decades.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-decades@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-decades@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre12.imageset/genre-image-decades.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre12.imageset/genre-image-decades.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre12.imageset/genre-image-decades@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre12.imageset/genre-image-decades@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre12.imageset/genre-image-decades@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre12.imageset/genre-image-decades@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre13.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-electronic.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-electronic@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-electronic@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre13.imageset/genre-image-electronic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre13.imageset/genre-image-electronic.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre13.imageset/genre-image-electronic@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre13.imageset/genre-image-electronic@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre13.imageset/genre-image-electronic@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre13.imageset/genre-image-electronic@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre14.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-gospel.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-gospel@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-gospel@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre14.imageset/genre-image-gospel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre14.imageset/genre-image-gospel.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre14.imageset/genre-image-gospel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre14.imageset/genre-image-gospel@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre14.imageset/genre-image-gospel@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre14.imageset/genre-image-gospel@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre15.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-hip-hop.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-hip-hop@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-hip-hop@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre15.imageset/genre-image-hip-hop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre15.imageset/genre-image-hip-hop.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre15.imageset/genre-image-hip-hop@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre15.imageset/genre-image-hip-hop@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre15.imageset/genre-image-hip-hop@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre15.imageset/genre-image-hip-hop@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre16.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-indie.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-indie@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-indie@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre16.imageset/genre-image-indie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre16.imageset/genre-image-indie.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre16.imageset/genre-image-indie@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre16.imageset/genre-image-indie@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre16.imageset/genre-image-indie@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre16.imageset/genre-image-indie@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17-expanded.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "filename" : "genre-image-jazz-expanded.jpg",
 5 |       "idiom" : "universal",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "scale" : "2x"
11 |     },
12 |     {
13 |       "idiom" : "universal",
14 |       "scale" : "3x"
15 |     }
16 |   ],
17 |   "info" : {
18 |     "author" : "xcode",
19 |     "version" : 1
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17-expanded.imageset/genre-image-jazz-expanded.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17-expanded.imageset/genre-image-jazz-expanded.jpg


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-jazz.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-jazz@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-jazz@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17.imageset/genre-image-jazz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17.imageset/genre-image-jazz.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17.imageset/genre-image-jazz@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17.imageset/genre-image-jazz@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17.imageset/genre-image-jazz@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre17.imageset/genre-image-jazz@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre18.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-kids-and-family.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-kids-and-family@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-kids-and-family@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre18.imageset/genre-image-kids-and-family.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre18.imageset/genre-image-kids-and-family.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre18.imageset/genre-image-kids-and-family@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre18.imageset/genre-image-kids-and-family@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre18.imageset/genre-image-kids-and-family@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre18.imageset/genre-image-kids-and-family@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre19.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-latin-hits.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-latin-hits@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-latin-hits@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre19.imageset/genre-image-latin-hits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre19.imageset/genre-image-latin-hits.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre19.imageset/genre-image-latin-hits@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre19.imageset/genre-image-latin-hits@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre19.imageset/genre-image-latin-hits@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre19.imageset/genre-image-latin-hits@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre2.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-alternative.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-alternative@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-alternative@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre2.imageset/genre-image-alternative.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre2.imageset/genre-image-alternative.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre2.imageset/genre-image-alternative@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre2.imageset/genre-image-alternative@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre2.imageset/genre-image-alternative@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre2.imageset/genre-image-alternative@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre20.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-metal.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-metal@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-metal@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre20.imageset/genre-image-metal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre20.imageset/genre-image-metal.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre20.imageset/genre-image-metal@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre20.imageset/genre-image-metal@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre20.imageset/genre-image-metal@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre20.imageset/genre-image-metal@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre21.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-modern-rock.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-modern-rock@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-modern-rock@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre21.imageset/genre-image-modern-rock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre21.imageset/genre-image-modern-rock.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre21.imageset/genre-image-modern-rock@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre21.imageset/genre-image-modern-rock@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre21.imageset/genre-image-modern-rock@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre21.imageset/genre-image-modern-rock@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre22.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-pop-gold.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-pop-gold@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-pop-gold@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre22.imageset/genre-image-pop-gold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre22.imageset/genre-image-pop-gold.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre22.imageset/genre-image-pop-gold@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre22.imageset/genre-image-pop-gold@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre22.imageset/genre-image-pop-gold@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre22.imageset/genre-image-pop-gold@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre23.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-pop-hits.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-pop-hits@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-pop-hits@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre23.imageset/genre-image-pop-hits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre23.imageset/genre-image-pop-hits.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre23.imageset/genre-image-pop-hits@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre23.imageset/genre-image-pop-hits@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre23.imageset/genre-image-pop-hits@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre23.imageset/genre-image-pop-hits@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre24.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-randb.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-randb@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-randb@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre24.imageset/genre-image-randb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre24.imageset/genre-image-randb.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre24.imageset/genre-image-randb@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre24.imageset/genre-image-randb@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre24.imageset/genre-image-randb@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre24.imageset/genre-image-randb@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre25.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-reggae.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-reggae@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-reggae@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre25.imageset/genre-image-reggae.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre25.imageset/genre-image-reggae.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre25.imageset/genre-image-reggae@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre25.imageset/genre-image-reggae@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre25.imageset/genre-image-reggae@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre25.imageset/genre-image-reggae@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre26.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-regional-mexican.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-regional-mexican@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-regional-mexican@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre26.imageset/genre-image-regional-mexican.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre26.imageset/genre-image-regional-mexican.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre26.imageset/genre-image-regional-mexican@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre26.imageset/genre-image-regional-mexican@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre26.imageset/genre-image-regional-mexican@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre26.imageset/genre-image-regional-mexican@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre27.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-singer-songwriter.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-singer-songwriter@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-singer-songwriter@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre27.imageset/genre-image-singer-songwriter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre27.imageset/genre-image-singer-songwriter.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre27.imageset/genre-image-singer-songwriter@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre27.imageset/genre-image-singer-songwriter@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre27.imageset/genre-image-singer-songwriter@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre27.imageset/genre-image-singer-songwriter@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre28.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-smooth-jazz.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-smooth-jazz@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-smooth-jazz@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre28.imageset/genre-image-smooth-jazz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre28.imageset/genre-image-smooth-jazz.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre28.imageset/genre-image-smooth-jazz@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre28.imageset/genre-image-smooth-jazz@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre28.imageset/genre-image-smooth-jazz@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre28.imageset/genre-image-smooth-jazz@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre29.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-smooth-pop.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-smooth-pop@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-smooth-pop@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre29.imageset/genre-image-smooth-pop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre29.imageset/genre-image-smooth-pop.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre29.imageset/genre-image-smooth-pop@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre29.imageset/genre-image-smooth-pop@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre29.imageset/genre-image-smooth-pop@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre29.imageset/genre-image-smooth-pop@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre3.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-blues.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-blues@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-blues@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre3.imageset/genre-image-blues.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre3.imageset/genre-image-blues.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre3.imageset/genre-image-blues@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre3.imageset/genre-image-blues@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre3.imageset/genre-image-blues@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre3.imageset/genre-image-blues@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre30.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-world-hits.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-world-hits@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-world-hits@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre30.imageset/genre-image-world-hits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre30.imageset/genre-image-world-hits.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre30.imageset/genre-image-world-hits@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre30.imageset/genre-image-world-hits@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre30.imageset/genre-image-world-hits@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre30.imageset/genre-image-world-hits@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre4.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-christian.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-christian@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-christian@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre4.imageset/genre-image-christian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre4.imageset/genre-image-christian.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre4.imageset/genre-image-christian@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre4.imageset/genre-image-christian@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre4.imageset/genre-image-christian@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre4.imageset/genre-image-christian@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre5.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-classic-alt.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-classic-alt@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-classic-alt@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre5.imageset/genre-image-classic-alt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre5.imageset/genre-image-classic-alt.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre5.imageset/genre-image-classic-alt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre5.imageset/genre-image-classic-alt@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre5.imageset/genre-image-classic-alt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre5.imageset/genre-image-classic-alt@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre6.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-classic-country.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-classic-country@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-classic-country@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre6.imageset/genre-image-classic-country.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre6.imageset/genre-image-classic-country.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre6.imageset/genre-image-classic-country@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre6.imageset/genre-image-classic-country@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre6.imageset/genre-image-classic-country@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre6.imageset/genre-image-classic-country@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre7.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-classic-randb.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-classic-randb@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-classic-randb@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre7.imageset/genre-image-classic-randb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre7.imageset/genre-image-classic-randb.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre7.imageset/genre-image-classic-randb@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre7.imageset/genre-image-classic-randb@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre7.imageset/genre-image-classic-randb@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre7.imageset/genre-image-classic-randb@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre8.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-classic-rock.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-classic-rock@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-classic-rock@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre8.imageset/genre-image-classic-rock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre8.imageset/genre-image-classic-rock.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre8.imageset/genre-image-classic-rock@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre8.imageset/genre-image-classic-rock@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre8.imageset/genre-image-classic-rock@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre8.imageset/genre-image-classic-rock@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre9.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "genre-image-classical.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "genre-image-classical@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "genre-image-classical@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre9.imageset/genre-image-classical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre9.imageset/genre-image-classical.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre9.imageset/genre-image-classical@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre9.imageset/genre-image-classical@2x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre9.imageset/genre-image-classical@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre9.imageset/genre-image-classical@3x.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre_white.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "filename" : "genre_white.png",
 5 |       "idiom" : "universal"
 6 |     },
 7 |     {
 8 |       "appearances" : [
 9 |         {
10 |           "appearance" : "luminosity",
11 |           "value" : "dark"
12 |         }
13 |       ],
14 |       "filename" : "genre_black.png",
15 |       "idiom" : "universal"
16 |     }
17 |   ],
18 |   "info" : {
19 |     "author" : "xcode",
20 |     "version" : 1
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre_white.imageset/genre_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre_white.imageset/genre_black.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre_white.imageset/genre_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/genre_white.imageset/genre_white.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/statusBarMask.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "scale" : "1x"
 6 |     },
 7 |     {
 8 |       "idiom" : "universal",
 9 |       "scale" : "2x"
10 |     },
11 |     {
12 |       "filename" : "mask.png",
13 |       "idiom" : "universal",
14 |       "scale" : "3x"
15 |     }
16 |   ],
17 |   "info" : {
18 |     "author" : "xcode",
19 |     "version" : 1
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/statusBarMask.imageset/mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/LNPopupControllerExample/LNPopupControllerExample/Supporting/Assets.xcassets/statusBarMask.imageset/mask.png


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/LNPopupControllerExample-Bridging-Header.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Use this file to import your target's public headers that you would like to expose to Swift.
 3 | //
 4 | 
 5 | #if LNPOPUP
 6 | @import LNPopupController;
 7 | #endif
 8 | #import "LoremIpsum.h"
 9 | #import "RandomColors.h"
10 | #import "SafeSystemImages.h"
11 | #import "SettingKeys.h"
12 | #import "DemoPopupContentViewController.h"
13 | 
14 | NS_ASSUME_NONNULL_BEGIN
15 | 
16 | @interface UIBlurEffect ()
17 | 
18 | + (instancetype)_effectWithStyle:(UIBlurEffectStyle)arg1 tintColor:(UIColor*)arg2 invertAutomaticStyle:(BOOL)arg3;
19 | + (instancetype)_effectWithTintColor:(UIColor*)arg1;
20 | + (instancetype)effectWithBlurRadius:(CGFloat)arg1;
21 | + (instancetype)effectWithVariableBlurRadius:(CGFloat)arg1 imageMask:(UIImage*)arg2 API_AVAILABLE(ios(17.0));
22 | 
23 | @end
24 | 
25 | NS_ASSUME_NONNULL_END
26 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22503" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
 3 |     <device id="retina6_12" orientation="portrait" appearance="light"/>
 4 |     <dependencies>
 5 |         <deployment identifier="iOS"/>
 6 |         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22503"/>
 7 |         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
 8 |         <capability name="System colors in document resources" minToolsVersion="11.0"/>
 9 |         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10 |     </dependencies>
11 |     <scenes>
12 |         <!--View Controller-->
13 |         <scene sceneID="EHf-IW-A2E">
14 |             <objects>
15 |                 <viewController id="01J-lp-oVM" sceneMemberID="viewController">
16 |                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
17 |                         <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
18 |                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
19 |                         <viewLayoutGuide key="safeArea" id="dDD-5z-iaz"/>
20 |                         <color key="backgroundColor" systemColor="systemGroupedBackgroundColor"/>
21 |                     </view>
22 |                 </viewController>
23 |                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
24 |             </objects>
25 |             <point key="canvasLocation" x="34.715000000000003" y="532.5"/>
26 |         </scene>
27 |     </scenes>
28 |     <resources>
29 |         <systemColor name="systemGroupedBackgroundColor">
30 |             <color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
31 |         </systemColor>
32 |     </resources>
33 | </document>
34 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/SceneDelegate.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  SceneDelegate.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2019-08-21.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | @interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
12 | 
13 | @property (strong, nonatomic) UIWindow* window;
14 | @property (weak, nonatomic) UIWindowScene* windowScene;
15 | 
16 | @end
17 | 
18 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/SceneDelegate.m:
--------------------------------------------------------------------------------
 1 | #import "SceneDelegate.h"
 2 | 
 3 | @interface DemoWindow : UIWindow @end
 4 | @implementation DemoWindow
 5 | 
 6 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
 7 | {
 8 | 	id rv = [super hitTest:point withEvent:event];
 9 | 	
10 | //	NSLog(@"DemoWindow hitTest %@", rv);
11 | 	
12 | 	return rv;
13 | }
14 | 
15 | @end
16 | 
17 | @implementation SceneDelegate
18 | 
19 | -(instancetype)init
20 | {
21 | 	self = [super init];
22 | 	
23 | 	if(self)
24 | 	{
25 | 		self.window = [DemoWindow new];
26 | 	}
27 | 	
28 | 	return self;
29 | }
30 | 
31 | - (void)scene:(UIWindowScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions 
32 | {
33 | 	self.window.windowScene = scene;
34 | 	self.windowScene = scene;
35 | 	
36 | 	[self.window makeKeyAndVisible];
37 | 	
38 | #if TARGET_OS_MACCATALYST
39 | 	scene.sizeRestrictions.maximumSize = CGSizeMake(DBL_MAX, DBL_MAX);
40 | 	scene.titlebar.toolbar = nil;
41 | 	
42 | 	if([self.window.rootViewController isKindOfClass:UISplitViewController.class])
43 | 	{
44 | 		UISplitViewController* split = (id)self.window.rootViewController;
45 | 		split.primaryBackgroundStyle = UISplitViewControllerBackgroundStyleSidebar;
46 | 	}
47 | #endif
48 | }
49 | 
50 | - (void)sceneDidDisconnect:(UIScene *)scene 
51 | {
52 | 	// Called as the scene is being released by the system.
53 | 	// This occurs shortly after the scene enters the background, or when its session is discarded.
54 | 	// Release any resources associated with this scene that can be re-created the next time the scene connects.
55 | 	// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
56 | 	
57 | 	self.windowScene = nil;
58 | }
59 | 
60 | 
61 | - (void)sceneDidBecomeActive:(UIScene *)scene {
62 | 	// Called when the scene has moved from an inactive state to an active state.
63 | 	// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
64 | }
65 | 
66 | 
67 | - (void)sceneWillResignActive:(UIScene *)scene {
68 | 	// Called when the scene will move from an active state to an inactive state.
69 | 	// This may occur due to temporary interruptions (ex. an incoming phone call).
70 | }
71 | 
72 | 
73 | - (void)sceneWillEnterForeground:(UIScene *)scene {
74 | 	// Called as the scene transitions from the background to the foreground.
75 | 	// Use this method to undo the changes made on entering the background.
76 | }
77 | 
78 | 
79 | - (void)sceneDidEnterBackground:(UIScene *)scene {
80 | 	// Called as the scene transitions from the foreground to the background.
81 | 	// Use this method to save data, release shared resources, and store enough scene-specific state information
82 | 	// to restore the scene back to its current state.
83 | }
84 | 
85 | @end
86 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Supporting/main.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  main.m
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | #import "AppDelegate.h"
11 | @import ObjectiveC;
12 | 
13 | #if TARGET_OS_MACCATALYST
14 | @interface NSObject (ZZZ) @end
15 | @implementation NSObject (ZZZ)
16 | 
17 | + (void)load
18 | {
19 | 	Class cls = NSClassFromString(@"UIFocusRingManager");
20 | 	Method m1 = class_getClassMethod(cls, NSSelectorFromString(@"moveRingToFocusItem:"));
21 | 	Method m2 = class_getClassMethod(NSObject.class, @selector(__ln_moveRingToFocusItem:));
22 | 	method_exchangeImplementations(m1, m2);
23 | }
24 | 
25 | + (void)__ln_moveRingToFocusItem:(id)arg1
26 | {
27 | 	
28 | }
29 | 
30 | @end
31 | #endif
32 | 
33 | int main(int argc, char * argv[]) {
34 | 	@autoreleasepool {
35 | 	    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
36 | 	}
37 | }
38 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/DemoGallery.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  DemoGallery.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2020-11-01.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | @import UIKit;
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | 
14 | NS_ASSUME_NONNULL_END
15 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/DemoGallery.m:
--------------------------------------------------------------------------------
  1 | //
  2 | //  DemoGallery.m
  3 | //  LNPopupControllerExample
  4 | //
  5 | //  Created by Léo Natan on 2020-11-01.
  6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
  7 | //
  8 | 
  9 | #import "DemoGallery.h"
 10 | 
 11 | #if LNPOPUP
 12 | @import LNPopupController;
 13 | #import "IntroWebViewController.h"
 14 | #import "LNPopupDemoContextMenuInteraction.h"
 15 | #endif
 16 | 
 17 | @interface DemoGalleryToolbar : UIToolbar @end
 18 | @implementation DemoGalleryToolbar @end
 19 | 
 20 | @interface SizeClassGalleryCell : UITableViewCell
 21 | 
 22 | @property (nonatomic, getter=isEnabled) BOOL enabled;
 23 | 
 24 | @end
 25 | 
 26 | @implementation SizeClassGalleryCell
 27 | 
 28 | -(void)setEnabled:(BOOL)enabled
 29 | {
 30 | 	if(enabled)
 31 | 	{
 32 | 		self.textLabel.textColor = UIColor.labelColor;
 33 | 		self.selectionStyle = UITableViewCellSelectionStyleDefault;
 34 | 	}
 35 | 	else
 36 | 	{
 37 | 		self.textLabel.textColor = UIColor.secondaryLabelColor;
 38 | 		self.selectionStyle = UITableViewCellSelectionStyleNone;
 39 | 	}
 40 | }
 41 | 
 42 | - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
 43 | {
 44 | 	[super traitCollectionDidChange:previousTraitCollection];
 45 | 	
 46 | 	[self setEnabled:self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular];
 47 | }
 48 | 
 49 | @end
 50 | 
 51 | @import SafariServices;
 52 | 
 53 | @interface DemoGalleryController : UITableViewController@end
 54 | @implementation DemoGalleryController
 55 | {
 56 | #if LNPOPUP
 57 | 	IntroWebViewController* _demoVC;
 58 | #endif
 59 | }
 60 | 
 61 | - (IBAction)unwindToGallery:(UIStoryboardSegue *)unwindSegue { }
 62 | 
 63 | - (void)viewDidLoad
 64 | {
 65 | 	[super viewDidLoad];
 66 | 	
 67 | #if LNPOPUP
 68 | 	_demoVC = [IntroWebViewController new];
 69 | 	
 70 | 	self.navigationController.popupBar.barStyle = LNPopupBarStyleFloating;
 71 | 	self.navigationController.popupBar.standardAppearance.marqueeScrollDelay = 0.0;
 72 | 	self.navigationController.popupBar.standardAppearance.marqueeScrollEnabled = YES;
 73 | 
 74 | 	self.navigationController.view.tintColor = self.navigationController.navigationBar.tintColor;
 75 | 	[self.navigationController presentPopupBarWithContentViewController:_demoVC animated:NO completion:nil];
 76 | 	
 77 | 	[self.navigationController.popupBar addInteraction:[LNPopupDemoContextMenuInteraction new]];
 78 | #endif
 79 | }
 80 | 
 81 | - (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
 82 | {
 83 | 	if([identifier hasPrefix:@"split"] && self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact)
 84 | 	{
 85 | 		[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:NO];
 86 | 		
 87 | 		return NO;
 88 | 	}
 89 | 	
 90 | 	return YES;
 91 | }
 92 | 
 93 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
 94 | {
 95 | 	if(segue.destinationViewController.modalPresentationStyle != UIModalPresentationFullScreen)
 96 | 	{
 97 | 		[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
 98 | 	}
 99 | }
100 | 
101 | @end
102 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/DemoPopupContentViewController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  DemoPopupContentViewController.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2016-08-06.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | extern void LNApplyTitleWithSettings(UIViewController* vc) NS_SWIFT_NAME(LNApplyTitleWithSettings(to:));
12 | 
13 | @interface DemoPopupContentViewController : UIViewController
14 | 
15 | @end
16 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/DemoViewController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  DemoViewController.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | @interface DemoViewController : UIViewController
12 | 
13 | 
14 | @end
15 | 
16 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/IntroWebViewController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  IntroWebViewController.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2020-10-28.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface IntroWebViewController : UIViewController
14 | 
15 | @end
16 | 
17 | NS_ASSUME_NONNULL_END
18 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/LNPopupControllerExampleSupport.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupControllerExampleSupport.h
 3 | //  LNPopupControllerExampleSupport
 4 | //
 5 | //  Created by Léo Natan on 2021-08-31.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | @import UIKit;
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | NS_ASSUME_NONNULL_END
14 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/LNPopupDemoContextMenuInteraction.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupDemoContextMenuInteraction.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2021-12-17.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @interface LNPopupDemoContextMenuInteraction : UIContextMenuInteraction
14 | 
15 | - (instancetype)init;
16 | - (instancetype)initWithTitle:(BOOL)title;
17 | + (instancetype)new;
18 | 
19 | @end
20 | 
21 | NS_ASSUME_NONNULL_END
22 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/LNPopupDemoContextMenuInteraction.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNPopupDemoContextMenuInteraction.m
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2021-12-17.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "LNPopupDemoContextMenuInteraction.h"
10 | #import "IntroWebViewController.h"
11 | 
12 | @interface LNPopupDemoContextMenuInteraction () <UIContextMenuInteractionDelegate>
13 | 
14 | @end
15 | 
16 | @implementation LNPopupDemoContextMenuInteraction
17 | {
18 | 	BOOL _includeTitle;
19 | }
20 | 
21 | - (instancetype)init
22 | {
23 | 	return [self initWithTitle:NO];
24 | }
25 | 
26 | - (instancetype)initWithTitle:(BOOL)title
27 | {
28 | 	self = [super initWithDelegate:self];
29 | 	
30 | 	if(self)
31 | 	{
32 | 		_includeTitle = title;
33 | 	}
34 | 	
35 | 	return self;
36 | }
37 | 
38 | + (instancetype)new
39 | {
40 | 	return [[self alloc] init];
41 | }
42 | 
43 | #pragma mark UIContextMenuInteractionDelegate
44 | 
45 | - (nullable UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location
46 | {
47 | 	return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil actionProvider:^UIMenu * _Nullable(NSArray<UIMenuElement *> * _Nonnull suggestedActions) {
48 | 		return [UIMenu menuWithTitle: self->_includeTitle ? @"LNPopupController" : @"" children:@[
49 | 			[UIMenu menuWithTitle:@"" image:nil identifier:nil options:UIMenuOptionsDisplayInline children:@[
50 | 				[UIAction actionWithTitle:NSLocalizedString(@"Visit GitHub Page", @"") image:[UIImage systemImageNamed:@"safari"] identifier:nil handler:^(__kindof UIAction * _Nonnull action)
51 | 				 {
52 | 					[UIApplication.sharedApplication openURL:[NSURL URLWithString:@"https://github.com/LeoNatan/LNPopupController"] options:@{} completionHandler:nil];
53 | 				}],
54 | 				[UIAction actionWithTitle:NSLocalizedString(@"Report an Issue…", @"") image:[UIImage systemImageNamed:@"ant.fill"] identifier:nil handler:^(__kindof UIAction * _Nonnull action)
55 | 				 {
56 | 					[UIApplication.sharedApplication openURL:[NSURL URLWithString:@"https://github.com/LeoNatan/LNPopupController/issues/new/choose"] options:@{} completionHandler:nil];
57 | 				}]
58 | 			]],
59 | 			[UIAction actionWithTitle:NSLocalizedString(@"Share…", @"") image:[UIImage systemImageNamed:@"square.and.arrow.up"] identifier:nil handler:^(__kindof UIAction * _Nonnull action)
60 | 			 {
61 | 				UIView* popupBar = [action valueForKeyPath:@"sender.view"];
62 | 				UIViewController* presentingController = [popupBar valueForKeyPath:@"viewControllerForAncestor"];
63 | 				UIActivityViewController* avc = [[UIActivityViewController alloc] initWithActivityItems:@[[NSURL URLWithString:@"https://github.com/LeoNatan/LNPopupController"]] applicationActivities:nil];
64 | 				avc.modalPresentationStyle = UIModalPresentationFormSheet;
65 | 				avc.popoverPresentationController.sourceView = popupBar;
66 | 				[presentingController presentViewController:avc animated:YES completion:nil];
67 | 			}],
68 | 		]];
69 | 	}];
70 | }
71 | 
72 | @end
73 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/LNSplitViewController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  SplitViewController.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2023-10-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | @import UIKit;
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | @class LNSplitViewController;
14 | 
15 | @interface LNSplitViewController : UISplitViewController @end
16 | 
17 | @interface LNSplitViewControllerPrimaryPopup : LNSplitViewController @end
18 | @interface LNSplitViewControllerSecondaryPopup : LNSplitViewController @end
19 | @interface LNSplitViewControllerGlobalPopup : LNSplitViewController @end
20 | 
21 | NS_ASSUME_NONNULL_END
22 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/LNSplitViewController.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LNSplitViewController.m
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2023-10-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | #import "LNSplitViewController.h"
10 | 
11 | @implementation LNSplitViewController
12 | 
13 | - (void)viewDidLoad
14 | {
15 | 	[super viewDidLoad];
16 | 	
17 | 	if([self isKindOfClass:LNSplitViewControllerSecondaryPopup.class] == NO)
18 | 	{
19 | 		self.minimumPrimaryColumnWidth = 400;
20 | 		self.maximumPrimaryColumnWidth = 400;
21 | 		
22 | 		if(self.style == UISplitViewControllerStyleTripleColumn)
23 | 		{
24 | 			self.minimumSupplementaryColumnWidth = 400;
25 | 			self.maximumSupplementaryColumnWidth = 400;
26 | 		}
27 | 	}
28 | }
29 | 
30 | - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
31 | {
32 | 	[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
33 | 	
34 | 	if(newCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact)
35 | 	{
36 | 		[self.presentingViewController dismissViewControllerAnimated:NO completion:nil];
37 | 	}
38 | }
39 | 
40 | @end
41 | 
42 | @implementation LNSplitViewControllerPrimaryPopup @end
43 | @implementation LNSplitViewControllerSecondaryPopup @end
44 | @implementation LNSplitViewControllerGlobalPopup @end
45 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/PageCardViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  PageCardViewController.swift
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2024-09-27.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class PageCardViewController: UIViewController {
12 | 	@IBOutlet var cardView: UIView!
13 | 	@IBOutlet var indexLabel: UILabel!
14 | 	public
15 | var prefix: String? = nil {
16 | 		didSet {
17 | 			if isViewLoaded {
18 | 				indexLabel.text = "\(prefix == nil ? "" : prefix!)\(index)"
19 | 			}
20 | 		}
21 | 	}
22 | 	public
23 | var index: Int = -1 {
24 | 		didSet {
25 | 			if isViewLoaded {
26 | 				indexLabel.text = "\(prefix == nil ? "" : prefix!)\(index)"
27 | 			}
28 | 		}
29 | 	}
30 | 	
31 |     override func viewDidLoad() {
32 |         super.viewDidLoad()
33 | 
34 | 		cardView.layer.cornerCurve = .continuous
35 | 		cardView.layer.cornerRadius = 40
36 | 		
37 | 		indexLabel.text = "\(prefix == nil ? "" : prefix!)\(index)"
38 |     }
39 | 	
40 | 	override func viewSafeAreaInsetsDidChange() {
41 | 		super.viewSafeAreaInsetsDidChange()
42 | 	}
43 | }
44 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/TestingScene/ScrollingMapViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  ScrollingMapViewController.swift
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2024-09-27.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class ScrollingMapViewController: UIViewController {
12 |     override func viewDidLoad() {
13 |         super.viewDidLoad()
14 | 
15 | #if LNPOPUP
16 | 		let useCompact = UserDefaults.settings.integer(forKey: .barStyle) == LNPopupBar.Style.compact.rawValue
17 | 		
18 | 		let gridBarButtonItem = UIBarButtonItem()
19 | 		gridBarButtonItem.image = LNSystemImage("map", scale: useCompact ? .compact : .normal)
20 | 		popupItem.barButtonItems = [gridBarButtonItem]
21 | 		
22 | 		LNApplyTitleWithSettings(to: self)
23 | #endif
24 |     }
25 | }
26 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Utils/RandomColors.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  RandomColors.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2015-08-23.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | @import UIKit;
10 | 
11 | extern UIColor* LNRandomSystemColor(void);
12 | 
13 | extern UIColor* LNSeedAdaptiveColor(NSString* seed);
14 | extern UIColor* LNSeedAdaptiveInvertedColor(NSString* seed);
15 | extern UIColor* LNRandomAdaptiveColor(void);
16 | extern UIColor* LNRandomAdaptiveInvertedColor(void);
17 | 
18 | extern UIColor* LNSeedDarkColor(NSString* seed);
19 | extern UIColor* LNSeedLightColor(NSString* seed);
20 | extern UIColor* LNRandomDarkColor(void);
21 | extern UIColor* LNRandomLightColor(void);
22 | 


--------------------------------------------------------------------------------
/LNPopupControllerExample/LNPopupControllerExample/Utils/SafeSystemImages.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  SafeSystemImages.h
 3 | //  LNPopupControllerExample
 4 | //
 5 | //  Created by Léo Natan on 2023-09-02.
 6 | //  Copyright © 2015-2025 Léo Natan. All rights reserved.
 7 | //
 8 | 
 9 | @import UIKit;
10 | 
11 | NS_ASSUME_NONNULL_BEGIN
12 | 
13 | typedef NS_ENUM(NSUInteger, LNSystemImageScale) {
14 | 	LNSystemImageScaleCompact,
15 | 	LNSystemImageScaleNormal,
16 | 	LNSystemImageScaleLarge,
17 | 	LNSystemImageScaleLarger
18 | };
19 | 
20 | extern UIImage* LNSystemImage(NSString* named, LNSystemImageScale scale) NS_SWIFT_NAME(LNSystemImage(_:scale:));
21 | extern UIBarButtonItem* LNSystemBarButtonItem(NSString* named, LNSystemImageScale scale, __nullable id target, __nullable SEL action) NS_SWIFT_NAME(LNSystemBarButtonItem(_:scale:target:action:));
22 | extern UIBarButtonItem* LNSystemBarButtonItemAction(NSString* named, LNSystemImageScale scale, UIAction* primaryAction) NS_SWIFT_NAME(LNSystemBarButtonItem(_:scale:primaryAction:));
23 | 
24 | NS_ASSUME_NONNULL_END
25 | 


--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
 1 | // swift-tools-version:5.9
 2 | 
 3 | import PackageDescription
 4 | 
 5 | let package = Package(
 6 | 	name: "LNPopupController",
 7 | 	platforms: [
 8 | 		.iOS(.v13),
 9 | 		.macCatalyst(.v13)
10 | 	],
11 | 	products: [
12 | 		.library(
13 | 			name: "LNPopupController",
14 | 			type: .dynamic,
15 | 			targets: ["LNPopupController", "LNPopupController-ObjC"]),
16 | 		.library(
17 | 			name: "LNPopupController-Static",
18 | 			type: .static,
19 | 			targets: ["LNPopupController", "LNPopupController-ObjC"]),
20 | 	],
21 | 	dependencies: [],
22 | 	targets: [
23 | 		.target(
24 | 			name: "LNPopupController-ObjC",
25 | 			dependencies: [],
26 | 			path: "LNPopupController",
27 | 			exclude: ["Info.plist"],
28 | 			publicHeadersPath: "include",
29 | 			cSettings: [
30 | 				.headerSearchPath("."),
31 | 				.headerSearchPath("Private")
32 | 			]),
33 | 		.target(
34 | 			name: "LNPopupController",
35 | 			dependencies: ["LNPopupController-ObjC"],
36 | 			path: "LNPCSwiftRefinements")
37 | 	],
38 | 	cxxLanguageStandard: .gnucxx20
39 | )
40 | 


--------------------------------------------------------------------------------
/Supplements/Artwork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/Artwork.png


--------------------------------------------------------------------------------
/Supplements/Icon-dark.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/Icon-dark.psd


--------------------------------------------------------------------------------
/Supplements/Icon.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/Icon.psd


--------------------------------------------------------------------------------
/Supplements/close_button_chevron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/close_button_chevron.png


--------------------------------------------------------------------------------
/Supplements/close_button_none.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/close_button_none.png


--------------------------------------------------------------------------------
/Supplements/close_button_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/close_button_round.png


--------------------------------------------------------------------------------
/Supplements/compact_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/compact_custom.png


--------------------------------------------------------------------------------
/Supplements/custom_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/custom_bar.png


--------------------------------------------------------------------------------
/Supplements/default_bar_accessibility_label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/default_bar_accessibility_label.png


--------------------------------------------------------------------------------
/Supplements/floating_bar_style.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/floating_bar_style.gif


--------------------------------------------------------------------------------
/Supplements/floating_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/floating_custom.png


--------------------------------------------------------------------------------
/Supplements/floating_no_scroll.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/floating_no_scroll.gif


--------------------------------------------------------------------------------
/Supplements/hidesBottomBar_TabBar.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/hidesBottomBar_TabBar.gif


--------------------------------------------------------------------------------
/Supplements/hidesBottomBar_Toolbar.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/hidesBottomBar_Toolbar.gif


--------------------------------------------------------------------------------
/Supplements/interaction_drag.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/interaction_drag.gif


--------------------------------------------------------------------------------
/Supplements/interaction_snap.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/interaction_snap.gif


--------------------------------------------------------------------------------
/Supplements/modern_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/modern_custom.png


--------------------------------------------------------------------------------
/Supplements/modern_no_scroll.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/modern_no_scroll.gif


--------------------------------------------------------------------------------
/Supplements/open_floating_popup.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/open_floating_popup.gif


--------------------------------------------------------------------------------
/Supplements/pointer_interaction.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/pointer_interaction.gif


--------------------------------------------------------------------------------
/Supplements/popup_bar_context_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/popup_bar_context_menu.png


--------------------------------------------------------------------------------
/Supplements/popup_transitions.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/popup_transitions.gif


--------------------------------------------------------------------------------
/Supplements/progress_view_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/progress_view_bottom.png


--------------------------------------------------------------------------------
/Supplements/progress_view_none.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/progress_view_none.png


--------------------------------------------------------------------------------
/Supplements/progress_view_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/progress_view_top.png


--------------------------------------------------------------------------------
/Supplements/rtl_english.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/rtl_english.png


--------------------------------------------------------------------------------
/Supplements/rtl_hebrew.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/rtl_hebrew.png


--------------------------------------------------------------------------------
/Supplements/scroll.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/scroll.gif


--------------------------------------------------------------------------------
/Supplements/scroll_edge_appearance.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/scroll_edge_appearance.gif


--------------------------------------------------------------------------------
/Supplements/statusbar_hidden.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/statusbar_hidden.gif


--------------------------------------------------------------------------------
/Supplements/statusbar_style.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/statusbar_style.gif


--------------------------------------------------------------------------------
/Supplements/tab_bar_sidebar_floating.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/tab_bar_sidebar_floating.gif


--------------------------------------------------------------------------------
/Supplements/tab_bar_sidebar_landscape_floating.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/tab_bar_sidebar_landscape_floating.png


--------------------------------------------------------------------------------
/Supplements/tab_bar_sidebar_prominent.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPopupController/c7ec14fb247c0a5b57fad2c5b2099cbd6c030f91/Supplements/tab_bar_sidebar_prominent.gif


--------------------------------------------------------------------------------
/releaseVersion.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | set -e
 3 | 
 4 | if [[ -n $(git status --porcelain) ]]; then
 5 |   echo -e >&2 "\033[1;31mCannot release version because there are unstaged changes:\033[0m"
 6 |   git status --short
 7 |   exit -2
 8 | fi
 9 | 
10 | if [[ -n $(git tag --contains $(git rev-parse --verify HEAD)) ]]; then
11 |   echo -e >&2 "\033[1;31mThe latest commit is already contained in the following releases:\033[0m"
12 |   git tag --contains $(git rev-parse --verify HEAD)
13 |   exit -3
14 | fi
15 | 
16 | # if [[ -n $(git log --branches --not --remotes) ]]; then
17 | #   echo -e "\033[1;34mPushing pending commits to git\033[0m"
18 | #   git push
19 | # fi
20 | 
21 | CURRENT_VERSION=$(/usr/libexec/PlistBuddy LNPopupController/Info.plist -c "Print CFBundleShortVersionString")
22 | NEXT_VERSION=$(echo "$CURRENT_VERSION" | perl -pe 's/^((\d+\.)*)(-?\d+)(.*)$/$1.($3+1).$4/e')
23 | 
24 | echo -e "\033[1;34mUsing $NEXT_VERSION as release version\033[0m"
25 | 
26 | echo -e "\033[1;34mCreating release notes\033[0m"
27 | 
28 | RELEASE_NOTES_FILE=_tmp_release_notes.md
29 | 
30 | touch "${RELEASE_NOTES_FILE}"
31 | open -Wn "${RELEASE_NOTES_FILE}"
32 | 
33 | if ! [ -s "${RELEASE_NOTES_FILE}" ]; then
34 |   echo -e >&2 "\033[1;31mNo release notes provided, aborting.\033[0m"
35 |   rm -f "${RELEASE_NOTES_FILE}"
36 |   exit -1
37 | fi
38 | 
39 | echo -e "\033[1;34mUpdating framework version\033[0m"
40 | 
41 | /usr/libexec/PlistBuddy LNPopupController/Info.plist -c "Set CFBundleShortVersionString $NEXT_VERSION" -c "Set CFBundleVersion 1"
42 | /usr/libexec/PlistBuddy LNPopupControllerExample/LNPopupControllerExample/Info.plist -c "Set CFBundleShortVersionString $NEXT_VERSION" -c "Set CFBundleVersion 1"
43 | 
44 | echo -e "\033[1;34mCommitting all changes to Git for release $NEXT_VERSION\033[0m"
45 | 
46 | git add -A
47 | git commit -m "$NEXT_VERSION"
48 | git tag "$NEXT_VERSION"
49 | 
50 | git push
51 | git push --tags
52 | 
53 | echo -e "\033[1;34mCreating a GitHub release\033[0m"
54 | 
55 | gh release create --repo LeoNatan/LNPopupController "$NEXT_VERSION" --title "v$NEXT_VERSION" --notes-file "${RELEASE_NOTES_FILE}"
56 | 
57 | rm -f "${RELEASE_NOTES_FILE}"


--------------------------------------------------------------------------------