Giter VIP home page Giter VIP logo

panelkit's Introduction

PanelKit for iOS

Build Status Codecov
Swift PodVersion Carthage Compatible Platform: iOS
Twitter Donate via PayPal

PanelKit for iOS
Applications using PanelKit can be seen in the showcase.

About

PanelKit is a UI framework that enables panels on iOS. A panel can be presented in the following ways:

  • Modally
  • As a popover
  • Floating (drag the panel around)
  • Pinned (either left or right)

This framework does all the heavy lifting for dragging panels, pinning them and even moving/resizing them when a keyboard is shown/dismissed.

Implementing

A lot of effort has gone into making the API simple for a basic implementation, yet very customizable if needed. Since PanelKit is protocol based, you don't need to subclass anything in order to use it. There a two basic principles PanelKit entails: panels and a PanelManager.

Panels

A panel is created using the PanelViewController initializer, which expects a UIViewController, PanelContentDelegate and PanelManager.

PanelContentDelegate

PanelContentDelegate is a protocol that defines the appearance of a panel. Typically the PanelContentDelegate protocol is implemented for each panel on its UIViewController.

Example:

class MyPanelContentViewController: UIViewController, PanelContentDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.title = "Panel title"	
    }
    
    var preferredPanelContentSize: CGSize {
        return CGSize(width: 320, height: 500)
    }	
}

A panel is explicitly (without your action) shown in a UINavigationController, but the top bar can be hidden or styled as with any UINavigationController.

PanelManager

PanelManager is a protocol that in its most basic form expects the following:

// The view in which the panels may be dragged around
var panelContentWrapperView: UIView {
    return contentWrapperView
}

// The content view, which will be moved/resized when panels pin
var panelContentView: UIView {
    return contentView
}

// An array of PanelViewController objects
var panels: [PanelViewController] {
    return []
}

Typically the PanelManager protocol is implemented on a UIViewController.

Advanced features

PanelKit has some advanced opt-in features:

Installation

To install, add the following line to your Podfile:

pod 'PanelKit', '~> 2.0'

To install, add the following line to your Cartfile:

github "louisdh/panelkit" ~> 2.0

Run carthage update to build the framework and drag the built PanelKit.framework into your Xcode project.

Requirements

  • iOS 10.0+
  • Xcode 9.0+

Todo

Long term:

  • Top/down pinning

License

This project is available under the MIT license. See the LICENSE file for more info.

panelkit's People

Contributors

basthomas avatar louisdh avatar pducks32 avatar valeriyvan 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  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

panelkit's Issues

Expose move breaks panels

When toggling expose while panels are pinned and then pulling panels the app starts to break down. While in expose apps can be pinned to a different side, then however get blurred into the background. when deactivating expose they return to their original location, but the background is laid out for the panels being pinned to the side were during expose.

Using the example provided (Map and TextView): when both panels are floating and expose is activated the both can (sometimes) be "resized", by pulling the bottom of the panels, which shrinks them down weirdly, even until they vanish. After deactivating expose they return to normal.

Close single panel?

The close method on PanelManager isn't public so I can't choose to close an individual panel (for example allowing a user to close a floating or pinned panel by pressing the UI button that displayed it, ie having that button be a toggle for displaying the panel).

Any similar library for Android?

Hi @louisdh,

First of all I would like to appreciate for creating such a nice, cool library.

Do you know any similar library for Android as well? I have searched a lot but not able to find the same.

Thanks
Pranav

Panel separator (spacing)

Is it possible to provide a spacing between the added panels and/or the main view (i.e. panelContentView)?

Support Tabs

It would be great if it were possible to have tabs, like in Goodnotes or Safari

alt\

They would be created when dragging a panel over a non-floating panel. I guess they'd be in a bar below the Navigation bar, or maybe the Navigation bar could be split if it were only two or so (?). A tab could then be grabbed and pulled back out to a floating panel. Maybe even a panel with multiple tabs could be dragged. Kind of the way that windows behave now on MacOS, when having the native tabs. (TextMate is a great example for that)

Issue with restoring pinned and floating panels

I'm not sure if this is due to how my project is set up, but I can't seem to have restoration work when there is both a pinned and a floating panel.

I'm calling my restorePanelStatesFromDisk() in viewWillAppear because if a panel is pinned I want it to be there as the view is being presented. This doesn't seem to display floating panels, though.

Calling restorePanelStatesFromDisk() in viewDidAppear seems to display floating panels fine, but causes pinned panels to suddenly appear instead of being there from the initial display animation.

I've tried calling restorePanelStatesFromDisk() in both, but this causes pinned panels to be there at the start but then disappear.

Any insights into what I might be doing wrong?

Thanks!

Is it compatible with Objective-C?

Hi @louisdh,

First of all I would like to appreciate for creating such a nice, cool library.

I wanted to use this in my Objective-C project, does this library provide wrapper for the same?

#Thanks
Pranav

Run code when panel will close

Is there any way of executing code when a panel closes? I tried overriding different methods I can see in the open source code, but most are in extensions and so not overridable. I tried overriding viewWillDisappear, which gets called every time a panel pins/floats/unpins. I also tried adding a custom done button, however that one got removed and replaced with the PanelKit one.

Is there a way to run code when the close button gets pressed, or could you add that functionality?

This is amazing!

I just love this repo, and wanted to share this love with you, and thank you for open sourcing it and seeing the value in open source, despite this being a serious differentiator in your own app!

My "issue" here is that this is not part of UIKit on iPad! Apple introduced the iPad Pro, and we still have silly 5x4 SpringBoard grids with such limited UI.

Crash with non-finite constraint multiplier (dividing by zero)

I triggered a crash in OpenTerm while trying to dock a panel to the side.

I believe this is caused by PanelManager+AutoLayout:updateFrame(for:to:keyboardShown) dividing by zero. Not sure the circumstances that caused this, or if this is something misconfigured in OpenTerm, but there should be a check to handle this case in PanelKit.

Crash is below:

Assertion failure in -[NSLayoutConstraint _setMultiplier:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/Foundation/Foundation-1444.12/Layout.subproj/NSLayoutConstraint.m:196
2018-02-06 16:45:07.837694-0800 OpenTerm[38697:2877706] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Multiplier is not finite!  That's illegal.  multiplier:inf'

Whenever the Panel is closed while floating or in pinned state, the contentViewController is not aware of being dismissed

First Let me say that I have really enjoyed using this! I love the ability to drag around a popover!

I just wanted to add that I am using version 0.8.2, and this is a kind of simple fix to allow the contentViewController to be aware it will be dismissed!

I can add this in for you, no problem! I am using PanelKit in one of my projects that is also using obj-c pods so I had to download the master manually include it in my project so my Cocoapods didn't clash, but overall this is great.

`extension PanelManager where Self: UIViewController {

func close(_ panel: PanelViewController) {

    if (panel.contentViewController != nil) {
        panel.contentViewController!.viewWillDisappear(true)
    }
    
	panel.view.removeFromSuperview()

	panel.contentViewController?.didUpdateFloatingState()

	if panel.isPinned {
		didDragFree(panel)
    }
}

}`

Add API to present panels in floating or pinned state (without using popover).

First off, @louisdh, thanks for making PanelKit โ€” this is really incredible. :)

I am trying to present a panel in the floating state immediately (i.e., without first presenting the panel in a popover). I've tried a number of techniques; the only thing that comes somewhat close is the following:

// MARK: - Popover

@IBAction func showMap(_ sender: UIBarButtonItem) {
	showPopover(mapPanelVC, from: sender) {
		if self.mapPanelVC.canFloat {
			self.toggleFloatStatus(for: self.mapPanelVC)
		}
	}		
}

func showPopover(_ vc: UIViewController, from barButtonItem: UIBarButtonItem, completion: (() -> Void)? = nil) {
	vc.modalPresentationStyle = .popover
	vc.popoverPresentationController?.barButtonItem = barButtonItem
	present(vc, animated: true, completion: completion)
}

(Although the panel is being presented as a popover, albeit for a very short amount of time.)

The reason that this distinction matters is because I'd like to present a "normal" (non-PanelKit) popover that will allow the user to manage panels, including opening new panels, and potentially closing existing panels. If the panels could start in the floating state immediately, that would make this a lot cleaner.

PanelContentDelegate not being called

Hello first of all thanks for this project. I am trying to integrate this into my Objective C project using swift extensions as you mentioned in some other issue. But Panel Delegate is not being called.

here is the method I am calling in my Objective C class

self.webBroserVc.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController * popoverVc = self.webBroserVc.popoverPresentationController;
popoverVc.sourceView = self.browserButton;
popoverVc.sourceRect = CGRectMake(self.browserButton.bounds.size.width/2, self.browserButton.bounds.size.height/2, 0, 0);
//popoverVc.preferredContentSize = CGSizeMake(250, 250);
[self presentViewController:self.webBroserVc animated:YES completion:nil];

Now I am using an extension to call the Panel Kit methods for PanelManager and PanelControlDelegate

extension CanvasViewController : PanelManager{

public var panels: [PanelViewController] {
    let mapPanelVC = PanelViewController(with: self.webBroserVc, in: self)
    return [mapPanelVC]
}

public var panelContentWrapperView: UIView {
    return self.view
}

public var panelContentView: UIView {
    return scrollViewContainer
}

}
extension WebBrowserViewController : PanelContentDelegate {
public var preferredPanelContentSize: CGSize {
return CGSize(width: 320, height: 500)
}

public var maximumPanelContentSize: CGSize {
    return CGSize(width: 512, height: 600)
}

public var preferredPanelPinnedWidth: CGFloat {
    return 500
}

But the PanelContentDelegate is not being called, can you please tell me what I am doing wrong @louisdh

How to make the dragging work on panels?

I've downloaded and run the example in this repo, but the panels show up as the old navigation controller, and I couldn't drag them. Am I missing something obvious for the dragging to work? I've tried to drag the NavigationBar, it does not move.

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.