Code Monkey home page Code Monkey logo

gallery's Introduction

Gallery Banner

Version Carthage Compatible License Platform Swift

Description

Gallery Icon

We all love image pickers, don't we? You may already know of ImagePicker, the all in one solution for capturing pictures and selecting images. Well, it has a sibling too, called Gallery. Based on the same engine that powers ImagePicker, Gallery has a clearer flow based on albums and focuses on the use case of selecting video. If this suits your need, give it a try ๐Ÿ˜‰

Gallery has 3 tabs with easy navigation through swipe gesture

  • Images: select albums and images. Handle selection with hightlighted numbers so your users don't forget the order
  • Camera: your photographer skill goes here
  • Videos: display all videos and select. For now the use case is to select one video at a time

And, it has zero dependencies ๐Ÿ˜Ž

Usage

Presenting

GalleryController is the main entry point, just instantiate and give it the delegate

let gallery = GalleryController()
gallery.delegate = self
present(gallery, animated: true, completion: nil)

The content controller is not loaded until the users navigate to, which offers a much faster experience.

Delegate

The GalleryControllerDelegate requires you to implement some delegate methods in order to interact with the picker

func galleryController(_ controller: GalleryController, didSelectImages images: [Image])
func galleryController(_ controller: GalleryController, didSelectVideo video: Video)
func galleryController(_ controller: GalleryController, requestLightbox images: [Image])
func galleryControllerDidCancel(_ controller: GalleryController)

The lightbox delegate method is your chance to display selected images. If you're looking for a nice solution, here is the Lightbox that we use and love

Resolving

The delegate methods give you Image and Video, which are just wrappers around PHAsset. To get the actual asset informations, we offer many convenient methods. See example

Image

  • Use instance method resolve to get the actual UIImage
  • Use static method Image.resolve to resolve a list of images

Video

  • Use instance method fetchDuration, fetchPlayerItem, fetchAVAsset, fetchThumbnail to get more information about the selected video.

Permission

Gallery handles permissions for you. It checks and askes for photo and camera usage permissions at first launch. As of iOS 10, we need to explicitly declare usage descriptions in plist files

<key>NSCameraUsageDescription</key>
<string>This app requires access to camera</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to photo library</string>

Configuration

There are lots of customization points in Config structs. For example

Config.Permission.image = UIImage(named: ImageList.Gallery.cameraIcon)
Config.Font.Text.bold = UIFont(name: FontList.OpenSans.bold, size: 14)!
Config.Camera.recordLocation = true
Config.tabsToShow = [.imageTab, .cameraTab]

Video Editor

Gallery cares more about video with its editing functionalities. We have VideoEditor and AdvancedVideoEditor to trim, resize, scale and define quality of the selected video

func galleryController(_ controller: GalleryController, didSelectVideo video: Video) {
  controller.dismiss(animated: true, completion: nil)

  let editor = VideoEditor()
  editor.edit(video: video) { (editedVideo: Video?, tempPath: URL?) in
    DispatchQueue.main.async {
      if let tempPath = tempPath {
        let controller = AVPlayerViewController()
        controller.player = AVPlayer(url: tempPath)

        self.present(controller, animated: true, completion: nil)
      }
    }
  }
}

With the Video object, you can fetchPlayerItem, fetchAVAsset and fetchThumbnail as well

And, of course, you have the ability to customize it

Config.VideoEditor.maximumDuration = 30
Config.VideoEditor.savesEditedVideoToLibrary = true

Installation

Gallery is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Gallery'

Gallery is also available through Carthage. To install just write into your Cartfile:

github "hyperoslo/Gallery"

Gallery can also be installed manually. Just download and drop Sources folders in your project.

Author

Hyper Interaktiv AS, [email protected]

Contributing

We would love you to contribute to Gallery, check the CONTRIBUTING file for more info.

License

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

gallery's People

Contributors

3lvis avatar bemusementpark avatar bruno-aguiar avatar hershalle avatar hyperseed avatar iosg1sw avatar johnsundell avatar lars-fosaas avatar neilabdev avatar onmyway133 avatar petekeller2 avatar radchenkov31 avatar richardtop avatar ruberik avatar scaraux avatar telip007 avatar vadymmarkov avatar vcalfa avatar weakfl avatar zenangst 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

gallery's Issues

Can it support rechoose?

 gallery = GalleryController(isVideoShow: false)
        
 gallery.delegate = self
        
 Cart.shared.reload(self.cartImages)
 present(gallery, animated: true, completion: nil)

I host an array of Image, and make the reload method public, but it failed to work.
It performed like the pic below. I think I need help.
Uploading IMG_5200ๅ‰ฏๆœฌ.pngโ€ฆ

Value of type 'Image' has no member 'uimage'

    let lightboxImages = images.flatMap { $0.uimage(ofSize: UIScreen.main.bounds.size)}.map({ LightboxImage(image: $0 )})

This line has the following error in your demo project: Value of type 'Image' has no member 'uimage'

Please post a fix/idea for fix. Thanks.

Bundle.swift

Hi, just love the Gallery.

Have a problem tough, Bundle.swift interfere with NSBundle, which now is named Bundle.
(used for getting version number, bulidnumber and such stuff.)

/olle

Edit without reducing width and height

Hello @onmyway133,

I have yet another problem: After selecting and having edited a video so its duration is no more than 12 seconds, I would like to upload this video to my server. Uploading it works fine and I use the tempPath of the edit function to get the editedVideo's URL. However, I noticed something about the videos uploaded to my server as well as saved if savesEditedVideoToLibrary was true: Namely that its dimensions were modified, e.g. all the videos which had dimensions of 720 x 1280 would end up with a resolution of 202 x 360 on my server. Setting shouldOptimizeForNetworkUse in VideoEditor to false did unfortunately not solve the issue.

How can I solve this problem and only edit its duration (if necessary)?

Image limit

I think it would be nice to have a variable in the Config struct which holds the limit of images you can select.

set tabsToShow crash

Gallery.Config.tabsToShow = [.cameraTab]

gallery = GalleryController()
gallery.delegate = self
present(gallery, animated: true, completion: nil)
Constraint.on(
  pageIndicator.leftAnchor.constraint(equalTo: pageIndicator.superview!.leftAnchor),
  pageIndicator.rightAnchor.constraint(equalTo: pageIndicator.superview!.rightAnchor),
  pageIndicator.heightAnchor.constraint(equalToConstant: 40)
)

pageIndicator.superview!.leftAnchor
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Error when Bundle was renamed

Hi,

When you renamed the class Bundle to GalleryBundle, you made a mistake. You forgot to change Bundle.self to GalleryBundle.self

class GalleryBundle {

static func image(_ named: String) -> UIImage? {
let bundle = Foundation.Bundle**(for: GalleryBundle.self)**
return UIImage(named: "Gallery.bundle/(named)", in: bundle, compatibleWith: nil)
}
}

Now the library is crashing.

Bye!

only camera?

can I use gallery only camera, without photos and videos

Single image select

Is it possible to restrict the selection of only one picture?
Thanks

founded line: public static var imageLimit: Int = 0
sorry for issue

imageLimit callBack

Gallery.Config.Camera.imageLimit = 2
I need to show a mask when I choose more than 3 pictures, but how can I get the callback after clicking more than 3 pictures?
thanks a lot!

Gallery not reseting after controller release

I think the main idea is that gallery retain objects if you're inside the gallery parent controller, so you can check what's selected at the moment, but, when you release the parent controller, cart keep the references of the objects. deInit function of GalleryController is not triggered.

International support

I want to make the display text, such as the button "Done" to change Chinese, thank you

Demo has updated code but pods does not have update code.

Demo project contains many features like:

public struct Config
{

@available(*, deprecated, message: "Use tabsToShow instead.")
public static var showsVideoTab: Bool {
    // Maintains backwards-compatibility.
    get {
        return tabsToShow.index(of: .videoTab) != nil
    }
    set(newValue) {
        if !newValue {
            tabsToShow = tabsToShow.filter({$0 != .videoTab})
        } else {
            if tabsToShow.index(of: .videoTab) == nil {
                tabsToShow.append(.videoTab)
            }
        }
    }
}
public static var tabsToShow: [GalleryTab] = [.imageTab, .cameraTab, .videoTab]
// Defaults to cameraTab if present, or whatever tab is first if cameraTab isn't present.
public static var initialTab: GalleryTab?

public enum GalleryTab {
    case imageTab
    case cameraTab
    case videoTab
}

}

But When I install pods (tried Carthage also)

public struct Config
{

public static var showsVideoTab: Bool = true
public struct PageIndicator {
    public static var backgroundColor: UIColor = UIColor(red: 0, green: 3/255, blue: 10/255, alpha: 1)
    public static var textColor: UIColor = UIColor.white
}

public struct Camera {
    
    public static var recordLocation: Bool = false
    
    public struct ShutterButton {
        public static var numberColor: UIColor = UIColor(red: 54/255, green: 56/255, blue: 62/255, alpha: 1)
    }
    
    public struct BottomContainer {
        public static var backgroundColor: UIColor = UIColor(red: 23/255, green: 25/255, blue: 28/255, alpha: 0.8)
    }
    
    public struct StackView {
        public static let imageCount: Int = 4
    }
    
    public static var imageLimit: Int = 0
    
}

}

## This code just an example for issue reference.
Is there is anything wrong? I tried pod update and Carthage update. But I can see the latest version of both but I can't find the code. I know I can add project directly (drag n drop) but I don't want to do that. This will restrict me to get an updated framework in future.

iPhone X support

Hello,

Could you please add support for iPhone X?
Some buttons are not reachable (close, flash, ...)
The home bar is also conflicting with the bottom bar.

img_7e21df0d41cb-1

Thank you very much,

Take a video

It would be nice to be able to take a video as well. If okay, I would try to implement that feature.

Tab Selection

Is it possible to hide or select which tabs to show?

Video editor not working/editedVideo equals nil

I recently started using this library and really like the layout and that it takes care of some things like maximum length and saving photos/videos (so to say edited since only the first seconds allowed are saved) to the photos automatically. However, I now encountered a problem which I cannot solve. I initially used the following code in the didSelectVideo function (very similar to what is presented in the README.md):

internal var gallery: GalleryController?
internal let editor: VideoEditing = VideoEditor()

func galleryController(_ controller: GalleryController, didSelectVideo video: Video) {    
    controller.dismiss(animated: true, completion: nil)
    
    editor.edit(video: video) { (editedVideo: Video?, tempPath: URL?) in
        DispatchQueue.main.async {
            if let tempPath = tempPath {
                let controller = AVPlayerViewController()
                controller.player = AVPlayer(url: tempPath)
                
                self.present(controller, animated: true, completion: nil) 
            }
        }
    }
}

The video in the parantheses of edit seems to have the right properties when I set a breakpoint somewhere (i.e. right amount of seconds the selected video lasts). Moreover, the values match those which can be found under self > gallery > cart > videos. But if I now enter the edit function and the breakpoint at DispatchQueue.main.async is hit, it tells me editedVideo equals nil. In addition to that, tempPath appears to be some(?) and only becomes a path when AVPlayer(url: tempPath) is hit although this doesn't seem to be a problem. The problem is no viewcontroller is presented. If I add a simple print in the completion handler of the present function, nothing is ever printed.

Since video wasn't nil I tried the following code (in `didSelectVideo) - which didn't work either:

    print(video) //prints "Gallery.Video"

    controller.dismiss(animated: true, completion: nil)
    
    video.fetchPlayerItem { (playerItem) in
        DispatchQueue.main.async {
            let avPlayer = AVPlayer(playerItem: playerItem)
            
            let avPlayerViewController = AVPlayerViewController()
            avPlayerViewController.player = avPlayer
            
            //nothing happens
            self.present(avPlayerViewController, animated: true, completion: {
                print(1)
            })
        }
    }

On top of all this, there appears to be a memory leak I couldn't find a soltuion for either. Can someone help me and explain why this is happening? I would really appreciate your help!

Lightbox Preview problem

@zenangst @fespinoza @nashby @timkurvers @sindrenm First of all this project is amazing, but I have a problem. once ive taken the images i want to preview them in this custom view controller i made with a scroll view inside of it. The lightbox solution you have for presenting your images and videos is nice but do you have something custom like a lightbox scroll view instead of a lightbox view controller that I can call in my main.storyboard so I can have additional elements in my view controller alongside the lightbox scroll view.

Skype: Jackpaster22

Loading image from iCloud

If an image is not on the device and needs to be loaded from the network, how can I enable that feature?

Cant exit from gallery after showing a preview of selected Image?

First of all,thanks for this amazing plugin.
Actually i want to select only one image and on done button action ,show a preview of that image in a new viewController.
i used this code to show it within the did selectImages delegate method,
`func galleryController(_ controller: GalleryController, didSelectImages images: [UIImage])
{

    imageSelected = images
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let cont = storyboard.instantiateViewController(withIdentifier: "FilterAndEdit")
   
   // self.navigationController?.pushViewController(controller, animated: true)
   self.present(cont, animated: true, completion: nil)
    
   let appDelegate = UIApplication.shared.delegate as! AppDelegate
    //show
   appDelegate.window?.rootViewController = cont
  
}

it show another viewController with the selected image,And on back button action on that viewController,its moving back to Gallery also.. Then comes the problem,After coming back from previewVC,the close button of gallery is not working.it pops the gallery again and again. i using this code in galleryControllerDidCancel delegate method.func galleryControllerDidCancel(_ controller: GalleryController)
{

controller.dismiss(animated: false) {
    
    self.tabBarController?.selectedIndex = 0

    }
    
}

`
Im opening this gallery on tapping a tabbar under the screen.Also i getting a warning like

Attempt to present <XXXXX.FilterAndEdit: 0x7fbd8955ee40> on <XXXXX.uploadTab: 0x7fbd89511dc0> whose view is not in the window hierarchy!

Please help me to solve this.

compile error on missed protocol method

I've implemented a subclass of UIViewController and make it conform to GalleryControllerDelegate like this:

class CaptureViewController: UIViewController, GalleryControllerDelegate {
    func galleryControllerDidCancel(_ controller: GalleryController) {
        controller.dismiss(animated: true, completion: nil)
    }
    
    func galleryController(_ controller: GalleryController, didSelectVideo video: Video) {
        controller.dismiss(animated: true, completion: nil)
    }
    
    func galleryController(_ controller: GalleryController, didSelectImages images: [UIImage]) {
        controller.dismiss(animated: true, completion: nil)
    }
    
    func galleryController(_ controller: GalleryController, requestLightbox images: [UIImage]) {
        controller.dismiss(animated: true, completion: nil)
    }
 
    // other stuff
}

but the compiler always shows:

Type 'CaptureViewController' does not conform to protocol 'GalleryControllerDelegate'

Protocol requires function 'galleryController(_:didSelectVideo:)' with type '(GalleryController, Video) -> ()'; do you want to add a stub?

Candidate has non-matching type '(GalleryController, Video) -> ()'

I don't see any mistake I've taken(in fact, my code is just follow your demo project). So what's wrong with me?

Appreciate.

Carthage build fails: Gallery.bundle: No such file or directory

Hi guys!

I want to give Gallery a try but the build with Carthage fails:
error:(my project path)/Carthage/Checkouts/Gallery/Sources/Gallery.bundle: No such file or directory

** BUILD FAILED **
The following build commands failed:
CpResource Sources/Gallery.bundle (my user path)/Library/Caches/org.carthage.CarthageKit/DerivedData/Gallery/1.0.0/Build/Products/Release-iphoneos/Gallery.framework/Gallery.bundle

(I removed my project and user path from the text above). Do you have any idea of what might be wrong? Thanks a lot :)!

Still active ?

I want to use this repo in my project but is this repo still maintained ?

launching gallery camera from landscape mode doesn't orient video in landscape

Hi,
I am having a minor issue on launching the camera on ipad from landscape, the default connection video orientation is always portrait. but rotating the device fixes the issue. looking through the code it looks like the preview layer for cameraView initialization didn't start with the current device orientation. Just thought I bring this up.

This library is a pleasure to use, thanks for the great work!

i fixed it by doing the following changes in cameraView.swift if you decided to use it.

func setupPreviewLayer(_ session: AVCaptureSession) {
guard previewLayer == nil else { return }

let layer = AVCaptureVideoPreviewLayer(session: session)
layer.autoreverses = true
layer.videoGravity = .resizeAspectFill
//-----adding the following code here seems to fix the issue --------------
if let connection = layer.connection,
connection.isVideoOrientationSupported {
connection.videoOrientation = Utils.videoOrientation()
}
//-----end fix--------------
self.layer.insertSublayer(layer, at: 0)
layer.frame = self.layer.bounds

previewLayer = layer
}

Gallery vs. ImagePicker?

Hi!

I'm a bit confused about the difference between Gallery and ImagePicker. I see Gallery has extra support for videos, but I also see ImagePicker has been optimized more? From ImagePicker's readme:
"ImagePicker has been optimized to give a great user experience, it passes around referenced images instead of the image itself which makes it less memory consuming. This is what makes it smooth as butter."
Is this something missing in Gallery or done in a different way? Thanks!

  • Julian

PageController latest changes not available in latest pod 2.0.5

Remember your last fix in PageController regarding the constraint crashes?
Well this fix is not there when we get Gallery via pod (latest 2.0.5). It has the old code.
What I did is took the code from master, unlocked the pod in Xcode and replaced PageController.swift with the latest one.

Camera permission is not asked

Latest Xcode and latest iOS11 SDK.
When I start with image and camera tab, no permission is asked for camera. Hence, only the image tab is shown.
When I start only with the camera tab, then it asks for camera permission.
Relevant plist keys are there.

What I did is force ask for permission myself in ViewDidLoad

AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in
			if response {
				//access granted
			} else {

			}
		}

Hint: I have another library that asks for photo library permission when the app starts. Maybe that's related on how internally your library handles the permissions?

The image preview

@zenangst @fespinoza @nashby @timkurvers @sindrenm First of all this project is amazing, but I have a problem. once ive taken the images i want to preview them in this custom view controller i made with a scroll view inside of it. The lightbox solution you have for presenting your images and videos is nice but do you have something custom like a lightbox scroll view instead of a lightbox view controller that I can call in my main.storyboard so I can have additional elements in my view controller alongside the lightbox scroll view.

Skype: Jackpaster22

Camera stuck when change page

If you slide page at high speed the camera will show still image instead.

I fix this by add start session in pageDidShow in CameraController.

func pageDidShow() {
once.run {
cameraMan.setup()
}
cameraMan.session.startRunning()
}

Cannot hide status bar

when i present gallery controller the status bar appear at the top, i saw in gallerycontroller, it has following code , then also the status bar is visible.
public override var prefersStatusBarHidden : Bool {
return true
}

swift 4 support?

Hi, love ur work.
But are you planning on upgrading to swift 4 anytime soon? Thx

Video Editor is crashing

My requirements are I have to open Gallery from Tab Bar Controller on pressing camera button. So it open video in full screen after selection hopefully for editing. I could not edit or play more with video. I got this crash.

2017-10-08 22:19:09.430663+0500 MOD[1368:468010] *** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<AVFullScreenPlaybackControlsViewController: 0x102805200> should have parent view controller:<AVPlayerViewController: 0x1020c7a00> but actual parent is:<AVFullScreenViewController: 0x101be8550>'
*** First throw call stack:
(0x1820bafe0 0x180b1c538 0x1820baf28 0x188267ccc 0x1881f4914 0x1881f3d88 0x1881f3bc8 0x18f959aa8 0x18f9585c0 0x182ae5050 0x182ac0d08 0x182ac0830 0x182aab790 0x18f9530e4 0x18f952df4 0x188203760 0x181fa9e34 0x181fa9d30 0x1881f2440 0x1881e649c 0x1883813e8 0x188380ec0 0x18831de64 0x18827be5c 0x18838196c 0x188222020 0x188366668 0x1882a6704 0x1881f3710 0x188261a80 0x188261a54 0x1882e66dc 0x18855c440 0x18855dcd0 0x1885607e4 0x1882dd794 0x18f95aa00 0x18f95db44 0x18f983a58 0x188221c54 0x188221bd4 0x18820c148 0x1882214b8 0x1887b60e8 0x1887b2434 0x1820689a8 0x182066630 0x182066a7c 0x181f96da4 0x183a01074 0x188251c9c 0x100047df0 0x180fa559c)
libc++abi.dylib: terminating with uncaught exception of type NSException

Select only one image

Cannot seem to find where i can restrict the user to select one pic or video at a time.Can you please help ASAP?

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.