Coder Social home page Coder Social logo

leonatan / lnpopupcontroller Goto Github PK

View Code? Open in Web Editor NEW
3.0K 64.0 342.0 174.93 MB

A framework for presenting view controllers as popups of other view controllers, much like the Apple Music and Podcasts apps.

License: MIT License

Objective-C 93.45% Swift 5.90% Shell 0.35% C 0.30%
popup objective-c swift xcode uiviewcontroller lnpopupcontroller ios cocoa-touch mac-catalyst

lnpopupcontroller's Introduction

Hi there! 👋 My name is Léo and I am a software engineer from Ramat Gan, Israel

LeoNatan's github stats

lnpopupcontroller's People

Contributors

aregler avatar cbpowell avatar codeeagle avatar colinmorelli avatar coolstar avatar fruitcoder avatar funkenstrahlen avatar idevelopper avatar joshluongo avatar juliensaad avatar leonatan avatar longhanks avatar louisdh avatar mosheberman avatar tomaszpieczykolan avatar wimbledon avatar zzzworm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lnpopupcontroller's Issues

'popupBar' adjusting for 'bottomDockingView' only after presenting 'contentViewController'

I'm trying to add a popupBar with a custom bottomDockingView (essentially, my player controls view).

However, I'm seeing some odd behavior: the popupBar isn't initially respecting the location of the bottomDockingView. It's only after I open contentViewController (calling presentPopupBarWithContentViewController) and then closing it, does the popupBar appear connected to the bottomDockingView correctly.


##### When presenting the `contentViewController` for the very first time

first_bar


##### After calling `presentPopupBarWithContentViewController` then closing it

second_bar


If it helps any: the initial state of the view hierarchy (i.e, simply launching the app) indicates the bottomDockingView is sitting where it should, but above all other views (including the popupBar). Thus, until I figure out what I'm doing wrong, I'm moving the z-position of the bottomDockingView to be below the popupBar, so at least I can open (then close) its contentViewController.

Any insight into what I'm doing wrong? Thanks.

Completion block is called twice when calling presentPopupBarWithContentViewController:openPopup:animated:completion:

This seems to happen when openPopup is set to YES.

In _presentBar: of FirstViewController.m of the example project , I tried changing
[targetVC openPopupAnimated:demoVC completion:nil];
to
[targetVC presentPopupBarWithContentViewController:demoVC openPopup:YES animated:YES completion:^{ NSLog(@"Completion"); }];

And get two logs of "Completion".

This happens because the completion block is called in presentPopupBarAnimated both in the animations:^ and completion^: blocks when open == YES.

Add coverart image to minified player

I would like to have a small coverart image of the current playing song in the minified version of the player.

I tried to set the coverart image instead of the play/pause button, however it messed up the whole layout. Maybe because it is a large image? I expected it to be scaled...

Any tips on how to do that?

Change player to minified state via code

I would like to press a button in the player view and then put the player into minified state. Exactly the same what the dismiss chevron button in the upper left of the example does. How can I call this from my own code?

Issues with UI adaptivity

This one was introduced very recently. One of the symptoms is that UIPopoverPresentationController's adaptivity behaviour has stopped working when presented inside the popup controller.

Steps to reproduce:
Inside DemoPopupContentViewController add

- (IBAction)presentVC:(UIButton *)sender {
    UIViewController *testVC = [UIViewController new];
    UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:testVC];

    nc.modalPresentationStyle = UIModalPresentationPopover;

    UIPopoverPresentationController *popoverController = nc.popoverPresentationController;

    if (popoverController != nil) {
        popoverController.sourceView = sender;
        popoverController.sourceRect = sender.bounds;
        popoverController.permittedArrowDirections = UIPopoverArrowDirectionAny;
    }

    [self presentViewController:nc animated:YES completion:nil];
}

On iPad Air 2 simulator present the test view controller and change the multitasking mode to 50/50 so that the horizontal size class becomes Regular.

Expected: the presented popover transforms to fullscreen (the screenshot was taken from an older version of the library)
Actual: the popover style remains (the recent version)

screen shot 2015-11-11 at 9 38 51 am

screen shot 2015-11-11 at 9 38 23 am

UIPanGestureRecognizer from external view

Hi Leo!

In my app I have scrollable content inside a popup so the built in UIPanGestureRecognizer doesn't work in my situation. I want to have a UIPanGestureRecognizer on the top bar of my view controller only, not on the whole screen.
Would it be possible add API to pass a UIPanGestureRecognizer to LNPopupController or to pass a UIView to which I want the recogniser to be added?

Issue with bottomLayoutGuide

Hi Leo,

I'm having an issue with the popup bar and the bottom layout guide. You mention in the docs that your "framework will attempt to correct the bottom layout guide of the container controller and its child controllers as the popup bar is presented and dismissed." I'm wondering where exactly these calls are being made so that I can trace where it's going wrong in my app.

I attach your framework to my root view controller (a UITabBarController) whose child views are all UINavigationControllers, which in turn contain UITableViewControllers. Here's an example of the issue I'm having:

ezgif com-optimize 4
Once your bar is presented, it overlaps the table view, as you'd expect.
However, when I try to scroll to make the bottommost row visible, the app springs it back below the popup bar. I'm presuming this is because the table view controller doesn't know about the bottom layout guide.

I'm wondering how I can go about debugging this. I'd like to assume it's a potential problem with my code before blaming your framework, so I'm wondering where your framework attempts to set the bottomLayoutGuide so that I can trace the call down my view hierarchy and hopefully identify the issue.

Thanks!

Info.plist is missing CFBundleShortVersionString

I can not submit an app using LNPopupController via Carthage as it is missing the CFBundleShortVersionString in Info.plist of LNPopupController.

screen shot 2016-01-09 at 11 53 03

How can I fix that? Is this an error on my side or can this be done via the Carthage package automatically so it is fixed for everyone using this?

crash when trying to customise LNPopupBar appearance

Hi @LeoNatan ,great work on LNPopupController!
I tried to uncomment the code in your example project

+ (void)load
{
    [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UINavigationController class]]] setTitleTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Chalkduster" size:14], NSForegroundColorAttributeName: [UIColor yellowColor]}];
    [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UINavigationController class]]] setSubtitleTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Chalkduster" size:12], NSForegroundColorAttributeName: [UIColor greenColor]}];
    [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UINavigationController class]]] setBarStyle:UIBarStyleBlack];
    [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UINavigationController class]]] setTintColor:[UIColor yellowColor]];
}

to see customised appearance of LNPopupBar, it was crashed with unrecognized selector sent to class, am I missing anything?

Submitting to iTC without modifying info.plist causes an error

I downloaded the framework as a git submodule and built my app. Then I tried uploading to iTC. I received an error about missing version keys in the info.plist. It turns out that the framework target doesn't have the required version numbers in its info.plist. I've fixed this and submitted a PR #28.

Changing background color does not work

I want to customize the looks of my popup bar:

LNPopupBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()]
LNPopupBar.appearance().subtitleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()]
LNPopupBar.appearance().barStyle = UIBarStyle.Black
LNPopupBar.appearance().tintColor = UIColor.whiteColor()

All settings work except the background color aka barStyle. My popupbar is still red like the tabBar underneath it. I want it to be black.

screen shot 2016-01-29 at 14 22 36

Swipe Gesture Recognizer

Hi,

Unfortunately, I can't use anymore swipe gesture recognizer in the popup window. It seems the popup event to reduce the View Controller is overwriting all swipe events.

Thanks.

Unwanted animation of popup controller's view hierarchy

When popup view controller is being presented for the first time it's view hierarchy animates (expands from the bottom left corner) inline with the popup presentation animation. It can be reproduced in the sample app "Apple Music". Expected behaviour would be to see the view coming from the bottom.

Popup Content Controller with Navigation bar - UI issue

Hi All,
I would like to use LNPopupController with content controller which is embeded in UINavigationController (or have own UINavigationBar at least).

I am trying to do something similar as Instagram do with their Tabbar middle Button, but in my case I want to create Popup Bar with Dashboard View Controller as it's content view. So I used the Tabbarcontroller delegate method to basically ignore that middle tab bar button tap and instead of that I instantiate Dashboard VC from storyboard like this:

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {

    if ([viewController isKindOfClass:[GRAVDashBoardPlaceholderController class]]) {
        UIStoryboard *dashboardStoryboard = [UIStoryboard storyboardWithName:@"Dashboard" bundle:nil];
        UIViewController *dashboardVC = (GRAVDashboardViewController *)[dashboardStoryboard instantiateInitialViewController];

        dashboardVC.popupItem.title = @"Recording test";
        dashboardVC.popupItem.subtitle = @"00:00:00";
        dashboardVC.popupItem.progress = 0;

        self.tabBarController.popupContentView.popupCloseButton.hidden = YES;
        [self.tabBarController presentPopupBarWithContentViewController:dashboardVC openPopup:YES animated:YES completion:nil];

        return NO;
    }

    return YES;
}

And this is what I want to achieve:
1

I tried to:
1) embed Dashboard view in Navigation Controller (translucent set to NO) directly in Storyboard
2) add Navigation Bar with autolayout constraints
But Navigation bar looks always like this when I use presentPopupBarWithContentViewController:openPopup:animated:completion:

snappyapp snappyapp today at 3 59 35 pm

This is well known behaviour since iOS7 [http://blog.jaredsinclair.com/post/61507315630/wrestling-with-status-bars-and-navigation-bars-on]

I checked tons of stackoverflow discussions about this topic. The only way I was able to solve that navigation bar layout (as seen on gif above) after initial openPopup: was that I add NavigationBar with 20pts constraint to Top Layout Guide of DashboardVC and use positionForBar: delegate method to return UIBarPositionTopAttached :

- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar {
    return UIBarPositionTopAttached;
}

But here is the issue. On both solutions stated above (correct and incorrect initial navbar height) with another UI update on the Dashboard i.e. when "start recording" button is pressed NavigationBar height change as well:
2 3

I am not sure it this behaviour has something to do with the Dashboard autolayout constraints setup or anything else... Any idea how to solve this? Or advice, what should I be focused on during troubleshooting? Thanks in advance ✌️

API to open popup view controller

Currently there is presentPopupBarWithContentViewController and upon completion we can call openPopupAnimated. It works OK but it'd be nice to have API to present popup view controller in one step.

Memory leak because of timer?

I just discovered a problem: If you use a timer in the PopupViewController to call a method on it regularly the PlayerViewController will be kept in memory and active even if the tabBarController instantiated a new PopupViewController.

I discovered this because right at the moment I added a timer, my AVPlayer of each PopupViewController(containing the player) kept playing in the background even when I started playing another song and a new PopupViewController was created.

I fixed this by invalidating the timer each time a new PopupViewController object was created.

        // invalidate the timer of the old controller, because this keeps the old controller in the memory
        if let oldController = popupContentController {
            oldController.timer?.invalidate()
            oldController.player?.pause()
        }
        popupContentController = storyboard?.instantiateViewControllerWithIdentifier("DemoMusicPlayerController") as? PlayerViewController

        tabBarController?.presentPopupBarWithContentViewController(popupContentController!, animated: true, completion: nil)

Is this issue covered in the demo projects?

Content controller is displaying under the navigation bar

I have a UINavigationController with a UIVC as its content controller. I call:
[self presentPopupBarWithContentViewController:self.mapNavigationController animated:YES completion:nil];
and it all works great. I get my viewDidLayoutSubviews - I alter the table content insets and all is good!

However when I open the content controller either by tapping on the button or swiping up, the content is under the navigation controller's navbar.

Now in your sample, you present the popupbar on the self.navigationController if there is no tab bar - and true, if I set it to navigationBar…it overlays the navigation Bar correctly…but then I don't get any changes to my bottom layout guide to offset the tableview content offsets.

There has to be a way to make both work…

Error not Loaded

Hello, I've dragged and dropped LNPopupController.xcoderoj into my project then I added the Framework to binary. Finally, in .m file I've added @import LNPopupController;.
Now when I run my project I get this error :

dyld: Library not loaded: @rpath/LNPopupController.framework/LNPopupController
  Referenced from: /private/var/mobile/Containers/Bundle/Application/811B7095-DA53-4F0E-B48D-D22765AAFD7E/flimee.app/flimee
  Reason: image not found

Did I missed something here ?

setNeedsStatusBarAppearanceUpdate() has no effect

I present a UIViewController as a popup. I want to change the status bar color dynamically.

I have implemented preferredStatusBarStyle() and an updateStatusBarStyle(style: UIStatusBarStyle) method to set a new style.

    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return statusBarStyle
    }

    func updateStatusBarStyle(style: UIStatusBarStyle) {
        statusBarStyle = style
        self.setNeedsStatusBarAppearanceUpdate()
    }

self.setNeedsStatusBarAppearanceUpdate() is called as I can see by debugging. However the status bar color does not change.

The status bar only updates its style correctly, if I minify the popup and max again.

o4wiaxrekp

LNPopupController goes behind UINavigationBar

I'm implementing this framework in my app, but somehow, when I slide it open, the view is placed behind the UINavigationBar. What am I doing wrong?

I present it like this: [self presentPopupBarWithContentViewController:self.demoVC animated:YES completion:nil];

Framework not found

Hey, I followed the Github instructions for importing the framework. It's in embedded libraries and linked frameworks but I'm getting "error: /Users/me/Documents/testApp/TestApp/LNPopupController/build/Debug-iphoneos/LNPopupController.framework: No such file or directory"

Not sure what I'm doing wrong. When I downloaded and dragged in just the .xcodeproj it linked from my downloads directory so undid all that and copied the folder into my directory and then dragged it in again. Hitting the + on the Embedded Libraries didn't bring it in so I went to Link Binary With Libraries and added it there first. Now it appears in all the correct places but it isn't being found.

ParagraphStyle support

In 0c98357 you have removed the default centered text alignment. Now I tried to set the alignment with paragraphStyle, but it does not work.

NSMutableParagraphStyle *paragraph= [[NSMutableParagraphStyle alloc] init];
[paragraph setAlignment:NSTextAlignmentCenter];
[[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UINavigationController class]]] setTitleTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Chalkduster" size:14], NSForegroundColorAttributeName: [UIColor yellowColor],NSParagraphStyleAttributeName : paragraph}];

I need an hasBeenMinified() delegate method

When my lnpopup view is fullscreen, I set the status bar color according to the coverart image (so the status bar is visible).

However if the player is minified I need to update the status bar color again, so it matches the color of my navigation bar of the rest of the app.

This kinda works if I use this method to set my status bar color:

- (UIStatusBarStyle)preferredStatusBarStyle
{ 
    return UIStatusBarStyleLightContent; 
}

However this does not play nice with controllers inside UINavigationControllers. So I use this method now:

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

However this does not change the status bar color when the popup is minified. Therefore I need a delegate to be called whenever the popup is minified, so I can force an update of the status bar color.

Opening LNPopupController programmatically gives me a "see through" window

When I initialise and open the LNPopupController instance in my app, I get a a window that's complete see-through on top of the presenting UIViewController.

self.restVC = [RestaurantsViewController new];
self.restVC.restaurants = [Restaurants fetchAll];

UIBarButtonItem *title = [[UIBarButtonItem alloc] initWithCustomView:self.restLabel];
self.restVC.popupItem.rightBarButtonItems = @[title];

[self.navigationController presentPopupBarWithContentViewController:self.restVC openPopup:YES animated:NO completion:nil];

When I look in the logs I can see that RestaurantsViewController is indeed loaded. If I then collaps the view and reopen it, it's fine. Any ideas as to what's causing this?

Having big problems when using with UITabBarController that has more than 4 tabs

It's a major one - when used with UITabBarController that has more than 4 tabs the LNPopupController gets embedded into the UITabBarController as an additional tab. This happens not on the initial presentation but when the screen size changes (iOS9 multitasking on iPad Air2 and newer).

Steps:

  1. In the example app open Main.storyboard and add one more tab to the tab bar controller to make 5 tabs in total
  2. Compile and launch on iPad Air2 iOS9 simulator
  3. When the LNPopupController is docked change the screen size to 50/50

Result:
The LNPopupController ends up being an additional tab of the tab bar controller

Bottom docking view should respect tabBar.isHidden property

Hi,

UITabBar can be hidden with .hidden property, but in this case bottomBarFrame still will be calculated with default UITabBar height (including frame.origin). You can see it here:

- (CGRect)defaultFrameForBottomDockingView
{
    CGRect bottomBarFrame = self.tabBar.frame;  
    bottomBarFrame.origin = CGPointMake(0, self.view.bounds.size.height - bottomBarFrame.size.height);
    return bottomBarFrame;
}

I think .origin should be calculated with additional check for visibility, something like this:

- (CGRect)defaultFrameForBottomDockingView
{
    CGRect bottomBarFrame = self.tabBar.frame;  
    bottomBarFrame.origin = CGPointMake(0, self.view.bounds.size.height - (self.tabBar.isHidden ? 0 : bottomBarFrame.size.height));
    return bottomBarFrame;
}

Regards,
Artem

Technique for dismissing TableView `contentViewController` onDrag

My content view controller's primary view is a UIScrollView subclass, specifically: UITableVIew. Any advice on what the correct solution is for getting the popupInteractionGestureRecognizer to work simultaneously with its installed panGestureRecognizer so that if the scroll view's contentOffset is zero, dragging down will dismiss the content view controller?

I have a crude initial attempt, which looks in the tableView's gesture recognizer array for popupInteractionGestureRecognizer. When the contentOffset is just right (TM), it will stop the panGestureRecognizer from beginning.

It works...but not great.

Current attempt

    private override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        // Capture '_popupGesture', if necessary...
        if (gestureRecognizers?.contains(gestureRecognizer) ?? false) == false
            && gestureRecognizer is UIPanGestureRecognizer
            && _popupGesture == nil {
                _popupGesture = gestureRecognizer as? UIPanGestureRecognizer
        } else if gestureRecognizer == panGestureRecognizer {
            if let _ = _popupGesture {
                switch (contentOffset.y + 44.0, panGestureRecognizer.velocityInView(self).y) {
                case (-CGFloat.max...0, 1...CGFloat.max):
                    return false
                default:
                    return true
                }
            }
        }

        return true
    }

Title and subtitle doesn't appear in bar.

If I open a navigation controller instead a single view controller, then the bar doesn't show any button or information.

let nav = UINavigationController(rootViewController: popupContentController) tabBarController?.presentPopupBarWithContentViewController(nav, animated: true, completion: nil)

You can reproduce in the example project.
simulator screen shot 2 feb 2016 15 34 49

Status Bar + UINavigationController doesn't play nicely.

The Apple Music app doesn't use a UINavigationController here, so perhaps this wasn't an anticipated edge case, but whenever I pass a UINavigationController as the popup view controller, the navigation bar doesn't adjust for the status bar.

Crash when title or subtitle nil

I've got a crash when the title or subtitle property is nil on presentation.
The crash is in the LNPopupBar : _layputTitles method, at line 281:
_titleLabel.attributedText = [[NSAttributedString alloc] initWithString:_title attributes:defaultTitleAttribures];

of course the error is the following:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSConcreteAttributedString initWithString:: nil value'

For the subtitle, I did not check, but based on the code, it is the same :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.