Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift

Overview

SKPhotoBrowser

Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift

Swift5 Build Status Platform Contributors

features

  • Display one or more images by providing either UIImage objects, or string of URL array.

  • Photos can be zoomed and panned, and optional captions can be displayed - Minimalistic Facebook-like interface, swipe up/down to dismiss

  • Ability to custom control. (hide/ show toolbar for controls, / swipe control) - Handling and caching photos from web - Landscape handling - Delete photo support(by offbye). By set displayDelete=true show a delete icon in statusbar, deleted indexes can be obtain from delegate func didDeleted

      | Table/CollectionView sample | Button tap sample |
      | ------------- | --------------- |
      | ![sample](Screenshots/example01.gif) | ![sample](Screenshots/example02.gif) |
    

Requirements

    - iOS 9.0+
    - Swift 2.0+
    - ARC

Version vs Swift version.

    Below is a table that shows which version of SKPhotoBrowser you should use for your Swift version.

    | Swift version | SKPhotoBrowser version    |
    | ------------- | --------------- |
    | 5.0           | >= 6.1.0 |
    | 4.2           | >= 6.0.0 |
    | 4.1           | >= 5.0.0 |
    | 3.2           | >= 4.0.0 |
    | 2.3           | 2.0.4 - 3.1.4  |
    | 2.2           | <= 2.0.3        |

Installation

CocoaPods

    available on CocoaPods. Just add the following to your project Podfile:
    ```
    pod 'SKPhotoBrowser'
    use_frameworks!
    ```

Carthage

    To integrate into your Xcode project using Carthage, specify it in your Cartfile:

    ```ogdl
    github "suzuki-0000/SKPhotoBrowser"
    ```

Info.plist

    If you want to use share image feature, it includes save image into galery, so you should specify a permission into your Info.plist (if you haven't done it yet).

    ```
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>Used to save images into your galery</string>
    ```

=======

Swift Package Manager

Available in Swift Package Manager. Use the repository URL in Xcode

Usage

See the code snippet below for an example of how to implement, or see the example project.

from UIImages:

// 1. create SKPhoto Array from UIImage
var images = [SKPhoto]()
let photo = SKPhoto.photoWithImage(UIImage())// add some UIImage
images.append(photo) 

// 2. create PhotoBrowser Instance, and present from your viewController. 
let browser = SKPhotoBrowser(photos: images)
browser.initializePageIndex(0)
present(browser, animated: true, completion: {})

from URLs:

// 1. create URL Array 
var images = [SKPhoto]()
let photo = SKPhoto.photoWithImageURL("https://placehold.jp/150x150.png")
photo.shouldCachePhotoURLImage = false // you can use image cache by true(NSCache)
images.append(photo)

// 2. create PhotoBrowser Instance, and present. 
let browser = SKPhotoBrowser(photos: images)
browser.initializePageIndex(0)
present(browser, animated: true, completion: {})

from local files:

// 1. create images from local files
var images = [SKLocalPhoto]()
let photo = SKLocalPhoto.photoWithImageURL("..some_local_path/150x150.png")
images.append(photo)

// 2. create PhotoBrowser Instance, and present. 
let browser = SKPhotoBrowser(photos: images)
browser.initializePageIndex(0)
present(browser, animated: true, completion: {})

If you want to use zooming effect from an existing view, use another initializer:

// e.g.: some tableView or collectionView.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
   let cell = collectionView.cellForItemAtIndexPath(indexPath) 
   let originImage = cell.exampleImageView.image // some image for baseImage 

   let browser = SKPhotoBrowser(originImage: originImage ?? UIImage(), photos: images, animatedFromView: cell) 
   browser.initializePageIndex(indexPath.row)
   present(browser, animated: true, completion: {})
}

Custom

Toolbar

You can customize Toolbar via SKPhotoBrowserOptions.

SKPhotoBrowserOptions.displayToolbar = false                              // all tool bar will be hidden
SKPhotoBrowserOptions.displayCounterLabel = false                         // counter label will be hidden
SKPhotoBrowserOptions.displayBackAndForwardButton = false                 // back / forward button will be hidden
SKPhotoBrowserOptions.displayAction = false                               // action button will be hidden
SKPhotoBrowserOptions.displayHorizontalScrollIndicator = false            // horizontal scroll bar will be hidden
SKPhotoBrowserOptions.displayVerticalScrollIndicator = false              // vertical scroll bar will be hidden
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)

Colors

You can customize text, icon and background colors via SKPhotoBrowserOptions or SKToolbarOptions

SKPhotoBrowserOptions.backgroundColor = UIColor.whiteColor()               // browser view will be white
SKPhotoBrowserOptions.textAndIconColor = UIColor.blackColor()              // text and icons will be black
SKToolbarOptions.textShadowColor = UIColor.clearColor()                    // shadow of toolbar text will be removed
SKToolbarOptions.font = UIFont(name: "Futura", size: 16.0)                 // font of toolbar will be 'Futura'

Images

You can customize the padding of displayed images via SKPhotoBrowserOptions

SKPhotoBrowserOptions.imagePaddingX = 50                                   // image padding left and right will be 25
SKPhotoBrowserOptions.imagePaddingY = 50                                   // image padding top and bottom will be 25

Statusbar

You can customize the visibility of the Statusbar in browser view via SKPhotoBrowserOptions

SKPhotoBrowserOptions.displayStatusbar = false                             // status bar will be hidden

Close And Delete Buttons

That how you can customize close and delete buttons

SKPhotoBrowserOptions.displayDeleteButton = true                           // delete button will be shown
SKPhotoBrowserOptions.swapCloseAndDeleteButtons = true                     // now close button located on right side of screen and delete button is on left side
SKPhotoBrowserOptions.closeAndDeleteButtonPadding = 20                     // set offset from top and from nearest screen edge of close button and delete button

Custom Cache From Web URL

You can use SKCacheable protocol if others are adaptable. (SKImageCacheable or SKRequestResponseCacheable)

e.g. SDWebImage

// 1. create custom cache, implement in accordance with the protocol 
class CustomImageCache: SKImageCacheable { var cache: SDImageCache }

// 2. replace SKCache instance with custom cache
SKCache.sharedCache.imageCache = CustomImageCache()

CustomButton Image

Close, Delete buttons are able to change image and frame.

browser.updateCloseButton(UIImage())
browser.updateUpdateButton(UIImage())

Delete Photo

You can delete your photo for your own handling. detect button tap from removePhoto delegate function.

Photo Captions

Photo captions can be displayed simply bottom of PhotoBrowser. by setting the caption property on specific photos:

let photo = SKPhoto.photoWithImage(UIImage())
photo.caption = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."

SwipeGesture

vertical swipe can enable/disable:

SKPhotoBrowserOptions.disableVerticalSwipe = true 

Delegate

There's some trigger point you can handle using delegate. those are optional. See SKPhotoBrowserDelegate for more details.

  • didShowPhotoAtIndex(_ index:Int)
  • willDismissAtPageIndex(_ index:Int)
  • willShowActionSheet(_ photoIndex: Int)
  • didDismissAtPageIndex(_ index:Int)
  • didDismissActionSheetWithButtonIndex(_ buttonIndex: Int, photoIndex: Int)
  • didScrollToIndex(_ index: Int)
  • removePhoto(_ browser: SKPhotoBrowser, index: Int, reload: (() -> Void))
  • viewForPhoto(_ browser: SKPhotoBrowser, index: Int) -> UIView?
  • controlsVisibilityToggled(_ browser: SKPhotoBrowser, hidden: Bool)
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
browser.delegate = self

// MARK: - SKPhotoBrowserDelegate
func didShowPhotoAtIndex(_ index: Int) {
// when photo will be shown
}

func willDismissAtPageIndex(_ index: Int) {
// when PhotoBrowser will be dismissed
}

func didDismissAtPageIndex(_ index: Int) {
// when PhotoBrowser did dismissed
}

Options

You can access via SKPhotoBrowserOptions, which can use for browser control. See SKPhotoBrowserOptions for more details.

  • single tap handling, dismiss/noaction
  • blackArea handling which is appearing outside of photo
  • bounce animation when appearing/dismissing
  • text color, font, or more
SKPhotoBrowserOptions.enableZoomBlackArea    = true  // default true
SKPhotoBrowserOptions.enableSingleTapDismiss = true  // default false

Photos from

License

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

Contributors

Thanks goes to these wonderful people (emoji key):


Alexander Khitev

๐Ÿ’ป

K Rummler

๐Ÿ’ป

Mads Bjerre

๐Ÿ’ป

Meng Ye

๐Ÿ’ป

_ant_one

๐Ÿ’ป

Tim Roesner

๐Ÿ’ป

่ƒฅๅ†ฅ

๐Ÿ’ป

Kevin Wolkober

๐Ÿ’ป

PJ Gray

๐Ÿ’ป

ghysrc

๐Ÿ’ป

Josef Doleลพal

๐Ÿ’ป

Mark Goody

๐Ÿ’ป

Philippe Riegert

๐Ÿ’ป

Bryan Irace

๐Ÿ’ป

dirtmelon

๐Ÿ’ป

Heberti Almeida

๐Ÿ’ป

Felix Weiss

๐Ÿ’ป

.Some

๐Ÿ’ป

Onur Var

๐Ÿ’ป

Andrew Barba

๐Ÿ’ป

This project follows the all-contributors specification. Contributions of any kind welcome!

Comments
  • Bug when zooming small image

    Bug when zooming small image

    Hi! First of all thanks for such control!

    There is a bug when trying to zoom a small image with double tap If you try to zoom such image with gesture everything is fine (it just not scale)

    Here is an example simulator screen shot 30 2016 16 37 07 simulator screen shot 30 2016 16 37 12

    opened by Sol88 11
  • Fatal Error: Array cannot be bridged from Objective-C

    Fatal Error: Array cannot be bridged from Objective-C

    I used 1.8.6 , it works fine. But since I updated to the new version ๏ผˆ1.8.8๏ผ‰, an error occurred var skPhotos = [SKPhoto]() let photoDatas = self.item.photos do{ for photoData in photoDatas{ let data = try photoData.getData() skPhotos.append(SKPhoto.photoWithImage(UIImage(data: data)!)) } }catch{ } let skPhotoBrowser = SKPhotoBrowser(photos: skPhotos)//Throw that error! Fatal Error: Array cannot be bridged from Objective-C

    opened by hjaurum 8
  • Several tweaks and impovements

    Several tweaks and impovements

    I had some issues regarding the transitions while opening and closing. I also updated the demo app to reflect the changes.

    • Changed content mode to .aspectFill so images don't become squished
    • Add support for cornerRadius transition when opening/closing
    • Option to bounce transition when opening/closing
    • Offset/size fixed when closing from zoomed/panned state
    opened by krummler 8
  • Device rotation doesn't refresh visible imageview frames

    Device rotation doesn't refresh visible imageview frames

    After device rotation if you change between images all are good but current image frame for initial state (after first rotation) is not good, have to be refreshed

    opened by turushan 8
  • SKPhotoBrowserOptions bug

    SKPhotoBrowserOptions bug

    SKPhotoBrowserOptions.displayCounterLabel = true SKPhotoBrowserOptions.displayBackAndForwardButton = true

    Some options don't work in release 4.1.1 I think you have introduced a bug cause I reverted back to 4.1.0 and they worked fine.

    I am not sure why, please give some feedback

    bug 
    opened by BrettWPather 7
  • Issue with multiple actionButtonTitles

    Issue with multiple actionButtonTitles

    Hi, When using multiple actions the default share action is not accessible (the action button is not public so you cannot use it as an anchor for a popup -for presenting a UIDocumentInteractionController) I solved the problem by not using the UIDocumentInteractionController and and changing this function

    func actionButtonPressed(ignoreAndShare ignoreAndShare: Bool) {
            delegate?.willShowActionSheet?(currentPageIndex)
    
            guard numberOfPhotos > 0 else {
                return
            }
    //CHANGES STARTS HERE
            if ignoreAndShare {
                let photo = photos[currentPageIndex]
                guard let underlyingImage = photo.underlyingImage else {
                    return
                }
    
                var activityItems: [AnyObject] = [underlyingImage]
                if photo.caption != nil {
                    if let shareExtraCaption = SKPhotoBrowserOptions.shareExtraCaption {
                        activityItems.append(photo.caption + shareExtraCaption)
                    } else {
                        activityItems.append(photo.caption)
                    }
                }
                activityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
                activityViewController.completionWithItemsHandler = {
                    (activity, success, items, error) in
                    self.hideControlsAfterDelay()
                    self.activityViewController = nil
                }
                if UI_USER_INTERFACE_IDIOM() == .Phone {
                    presentViewController(activityViewController, animated: true, completion: nil)
                } else {
                    activityViewController.modalPresentationStyle = .Popover
                    let popover: UIPopoverPresentationController! = activityViewController.popoverPresentationController
                    popover.barButtonItem = toolbar.toolActionButton
                    presentViewController(activityViewController, animated: true, completion: nil)
                }
                return
            }
            //CHANGES ENDs HERE
            if let titles = SKPhotoBrowserOptions.actionButtonTitles {
    

    I call it in

       func didDismissActionSheetWithButtonIndex(buttonIndex: Int, photoIndex: Int) {
          if buttonIndex == indexOfButtonUsedToShare {
                browser.actionButtonPressed(ignoreAndShare: true)}
          }else{
                //action for ther button
          }
    }
    

    Do you think this is the right way or it would be better to make the action button visible? (I don't know how to do it with the latest version of the browser)

    opened by rogomantik 7
  • Memory is not released

    Memory is not released

    I start it from a collectionView with 100+ images, someone bigger than 5MB SKPhotoBrowser(originImage: images[indexPath.row].underlyingImage, photos: images, animatedFromView: cell) when select a cellview the browsers shows but when I scroll the images the memory occupation continues to increase until the app crashes for excessive memory usage (500+MB) the memory of the not visible images don't seem to be released and neither the browser itself when closed

    using ios 10.3.2

    opened by rogomantik 6
  • Delete photo (image)

    Delete photo (image)

    I saw the delete function. But I want to offer a different resolution. If another developer need a function delete images, it is best to make subclass () and there to override this feature. Since we can not guess where to store the image. I show you my solution

    This is in SKPhotoBrowser

    public func deleteButtonPressed(sender: UIButton) {
    
        }
    
        public func deleteImage() {
            if photos.count > 1 {
                photos.removeAtIndex(currentPageIndex)
                gotoPreviousPage()
                updateToolbar()
            } else if photos.count == 1 {
                dismissPhotoBrowser()
            }
            reloadData()
        }
    

    This is a SKPhotoBrowser subclass

    class ImageBrowser: SKPhotoBrowser {
    
        override func deleteButtonPressed(sender: UIButton) {
            print("ImageBrowser")
            let userDefault = NSUserDefaults.standardUserDefaults()
            let documents = "documents"
            let deleteController = UIAlertController(title: nil, message: "ะ’ั‹ ะดะตะนัั‚ะฒะธั‚ะตะปัŒะฝะพ ั…ะพั‚ะธั‚ะต ัƒะดะฐะปะธั‚ัŒ ะดะพะบัƒะผะตะฝั‚?", preferredStyle: .Alert)
            deleteController.addAction(UIAlertAction(title: "ะะตั‚", style: .Cancel, handler: nil))
            deleteController.addAction(UIAlertAction(title: "ะ”ะฐ", style: .Destructive, handler: { (action) -> Void in
                var allDocuments = [DocumentEntity]()
                if let data = userDefault.objectForKey(documents) as? NSData {
                    allDocuments = (NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [DocumentEntity])!
                }
                allDocuments.removeAtIndex(self.currentPageIndex)
                let newData = NSKeyedArchiver.archivedDataWithRootObject(allDocuments)
                userDefault.setObject(newData, forKey: documents)
                userDefault.synchronize()
                self.deleteImage()
            }))
            presentViewController(deleteController, animated: true, completion: nil)
        }
    }
    
    

    And we can to use this subclass like

     let imageBrowser = ImageBrowser(photos: imageArray)
            imageBrowser.delegate = self
            imageBrowser.isForceStatusBarHidden = true
            imageBrowser.displayDeleteButton = true
            imageBrowser.initializePageIndex(indexPath.row)
            presentViewController(imageBrowser, animated: true) { () -> Void in
            }
    

    I checked it and it fine works. What do you think about it?

    opened by alexanderkhitev 6
  • Dismiss Animation to Origin

    Dismiss Animation to Origin

    Is there a way to dismiss the shown image back to the originImage/animatedFromView?

    Using the latest swift 3 version I get a nice animation from the animatedFromView to the SKPhotoBrowser but when dismissing the image is just faded out.

    Anything I'm missing?

    opened by winkelsdorf 5
  • fatal error: unexpectedly found nil while unwrapping an Optional value

    fatal error: unexpectedly found nil while unwrapping an Optional value

    Hello. With the newest version of SKPhotoBrowser ( 3.0.0 ) i am getting this fatal error when the browser loads and displays one of the pictures. It is marking this line from the code guard let page = self.pagingScrollView.pageDisplayingAtPhoto(photo), let photo = page.photo else { and using the debugger to get some information it shows that (lldb) p pagingScrollView (SKPhotoBrowser.SKPagingScrollView!) $R1 = nil and (lldb) po pagingScrollView fatal error: unexpectedly found nil while unwrapping an Optional value expression produced error: /var/folders/gv/hmkzdb493jbcg1drw2m_6h_80000gn/T/lldb/410/expr127.swift:1:95: error: 'SKPagingScrollView' is not a member type of '$__lldb_context' (aka 'SKPhotoBrowser') $__lldb__DumpForDebugger(Swift.UnsafePointer<Swift.ImplicitlyUnwrappedOptional<SKPhotoBrowser.SKPagingScrollView>>(bitPattern: 0x11f483eb0).memory) ~~~~~~~~~~~~~~ ^ /var/folders/gv/hmkzdb493jbcg1drw2m_6h_80000gn/T/lldb/410/expr127.swift:1:45: note: while parsing this '<' as a type parameter bracket $__lldb__DumpForDebugger(Swift.UnsafePointer<Swift.ImplicitlyUnwrappedOptional<SKPhotoBrowser.SKPagingScrollView>>(bitPattern: 0x11f483eb0).memory) And now im using version 2.0.3 since i don't have that problem there.

    opened by ibeleliev 5
  • Custom Cache and ImageDownloader + Floating View

    Custom Cache and ImageDownloader + Floating View

    How can I use a custom cache and downloader? I use Kingfisher as my MainImageManager, so when loading a new image from url, both SKPhotoBrowser and Kingfisher downloading the photo.

    P.S: I had one other problem: I have a floating view (like FAB button), when dismissing a photo by swipe, it's animation covers the floating view till it's fit in the source rect. How can I manage this? (I've tried to send the animating view to back of the floating view, but in another view I have two floating buttons that this workaround won't work.)

    Also when a photo is dismissed by swipe where source rect is not in view, the animation is weird (flickering till disappears), I've managed it by manipulating the SKPhotoBrowser class, but I just wanted to know do you have any straight solution for that?

    Thanks! ๐Ÿ˜Š

    opened by iAlirezaKML 5
  • archive ipa error

    archive ipa error

    Undefined symbols for architecture arm64: "_swift_stdlib_isStackAllocationSafe", referenced from: _$ss10_NativeSetV11subtractingyAByxGqd__7ElementQyd__RszSTRd__lF14SKPhotoBrowser19SKZoomingScrollViewC_SayAIGTg5Tf4ng_n in libSKPhotoBrowser.a(SKPagingScrollView.o) ld: symbol(s) not found for architecture arm64

    opened by zhangcheng1989 0
  • Video support added.

    Video support added.

    SKPhotoBrowser is a beautiful tool which save million of lives, only thing which I was missing is the video support, I tried my level best to write code following the same footprint, I hope my pull request will be accepted and I will become part of the community

    opened by engasix 0
  • Fix the problem that the Arabic share button cannot be clicked.

    Fix the problem that the Arabic share button cannot be clicked.

    If the Arabic share button is on the left, it will cause the button to be unclickable. I hope to release a version as soon as possible, and now I will overwrite the modified code every time I execute pod install.

    opened by iLiuChang 0
  • Add specifiable cache key for SKPhoto and some tests about SKPhoto.

    Add specifiable cache key for SKPhoto and some tests about SKPhoto.

    1. It will fix #425.
    2. Added some tests for SKPhoto to guarantee SKPhoto instances are functional.
    3. I'm willing to adjust the code if you had a better approach.
    opened by fattiger00 0
  • Fixed `SKZoomingScrollView` Initialization

    Fixed `SKZoomingScrollView` Initialization

    • When SKZoomingScrollView is initialized, the setup() method is called twice: once in init(frame:) and then once more in init(frame:browser:)
    • Double call of setup() results in UI elements (such as SKDetectingImageView) created twice
    • Even though SKZoomingScrollViewโ€™s properties (e.g. imageView) are reassigned on the second call of setup(), the UI elements remain in the view hierarchy and deviceโ€™s memory
    • To fix this, init(frame:browser:) has been to changed to be a designated initializer, and init(frame:) has been removed
    opened by yakovmanshin 0
Releases(7.0.0)
  • 7.0.0(Jul 20, 2021)

  • 6.1.0(Apr 3, 2019)

    Big Changed

    • #330 Changes for swift 5.0, Xcode 10.2,

    Updated

    • #339 fix #316 and #323 bug by xiaoweiFive
    • #342 update readme.md by SherlockQi
    • #344 fixed broken page recycling (regression from c6df44f9)
    • #348 keep thumbnail display until image download finished by seanxux
    • #353 loop call SKPhotoBrowserDelegate.controlsVisibilityToggled function by cp110
    • #361 Support for iPhoneXS, XSMax and XR by jdanthinne
    • #361 Xcode 10.2 optimization by TParizek
    Source code(tar.gz)
    Source code(zip)
  • 6.0.0(Sep 14, 2018)

    Big Changed

    • #330 Changes for swift 4.2, Xcode 10, and iOS 12 by jlcanale

    Updated

    • #314 Add possibility to provide custom request parameters by Fiser33
    • #315 Fix: Unable to set delete and close button images without setting size. by kiztonwose
    • #318 fix unreleased views in uiwindow for non-dismiss animation case by fans3210
    • #321 Set the backround view's background color from settings by pantelisss
    • #331 Add ability to lower caption and give caption a background gradient by corban123
    • #334 Prevent app crashed on zooming when xScale or yScale is NaN, Inf by GE-N
    • #335 use the size of the window instead of UIScreen to support SplitScreen by PatrickDotStar
    Source code(tar.gz)
    Source code(zip)
  • 5.1.0(May 7, 2018)

  • 5.0.9(Apr 23, 2018)

    5.0.9

    Updated

    • #304 CaptionViewForPhotoAtIndex is not work
    • #305 Padding properties for close and delete button.
    • Bug At iphoneX, close / delete / pagination can be tapped correctly.
    Source code(tar.gz)
    Source code(zip)
  • 5.0.8(Apr 12, 2018)

    5.0.8

    Updated

    • #224 override popupShare not working
    • #248 always ignore image cache, asked by FicowShen
    • #304 CaptionViewForPhotoAtIndex is not work
    • #301 SKPhotoBrowserOptions.displayDeleteButton not working
    • #302 Add method to remove all images for SKCache by filograno
    Source code(tar.gz)
    Source code(zip)
  • 5.0.7(Mar 29, 2018)

    Updated

    • #301 SKPhotoBrowserOptions.displayCounterLabel is not working
    • #297 I want to hide SKPagingScrollView's horizontal indicator by mothule
    Source code(tar.gz)
    Source code(zip)
  • 5.0.6(Mar 9, 2018)

  • 5.0.5(Feb 13, 2018)

    5.0.5

    • #271 SmartInvert now works properly
    • #288 Add the long photo width match screen option.
    • #289 Add SWIFT_VERSION to xcconfig
    • #273 Fixed crash on resizableImageView force unwrapping.
    Source code(tar.gz)
    Source code(zip)
  • 5.0.3(Dec 14, 2017)

  • 5.0.2(Dec 14, 2017)

    5.0.2

    Updated

    • Refactoring part1
    • #255 Fixed the crash where the PhotoBrowser could crash.
    • #262 Fix calling willDismissAtPageIndex delegate method
    • #263 Remove unused options
    • #263 Use iOS 11 Safe Area Insets to layout toolbar
    • #270 Added functionality to add new photos at the end or at the start of cโ€ฆ
    Source code(tar.gz)
    Source code(zip)
  • 5.0.0(Oct 5, 2017)

  • 4.1.1(Sep 19, 2017)

    Updated

    • #208 improve: change deleteButtonPressed(), currentPageIndex access level
    • #210 Fix Shorthand Operator Violation of Swiftlint
    • #215 swiftLint
    • #216 update code to Swift 3.1
    • #223 Removed deprecated constants
    • #225 Custom Cancel button title
    • #227 Attach toolbar and delete button to single browser instance
    • #236 improve SKPhotoBrowserDelegate
    Source code(tar.gz)
    Source code(zip)
  • 4.1.0(Aug 30, 2017)

    Updated

    • #173 Move the willDismiss delegate call closer to the dismissal
    • #196 Improved SKCaptionView
    • #197 fix: deleteButton frame does not update if screen has rotated
    • #199 Add SKPhotoBrowserOptions to customize indicator color & style
    • #200 Swap and custom padding for delete and close buttons
    • #205 Replaced deprecated Pi constants
    • #207 Update code style: to Swift3.1
    • #231 Update SKZoomingScrollView.swift
    Source code(tar.gz)
    Source code(zip)
  • 4.0.1(Jan 18, 2017)

    Fixed

    • Update README.md
    • #158 Button Position wrong with changed StatusBar handling
    • #162 Fix SKPhotoBrowserOptions background color
    • #181 Unclear how placeholder image is supposed to work
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0(Jan 5, 2017)

    4.0.0

    Released on 5-1-2017

    Breaking Change

    • go to swift3

    Fixed

    • #171 Add @escaping to delegate method's reload closure parameter.
    • #172 Fix caption font bug
    • #177 Fix a fatal error when app's window is customized.
    • #178 SKPagingScrollView fixes / swift3 branch
    • #179 SKPagingScrollView fixes
    • #182 Always load from the URL even if a placeholder image exists
    • #186 fix setStatusBarHidden is deprecated in iOS 9.0 and demo cannot run
    • #188 Added options for custom photo's caption.
    • #180 SKPhotoBrowserOptions not working Swift 3
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0-beta.1(Nov 14, 2016)

Owner
keishi suzuki
keishi suzuki
SwiftUI: Components Library Inspired by Twitter's Bootstrap

bootswiftui SwiftUI: Components Library Inspired by Twitter's Bootstrap Warning This is just SwiftUI exercise. Please do not consider using this repo

Robert Sandru 1 Oct 27, 2022
๐Ÿž A simple iOS photo and video browser with optional grid view, captions and selections written in Swift5.0

Introduction ?? MediaBrowser can display one or more images or videos by providing either UIImage objects, PHAsset objects, or URLs to library assets,

Kyle Yi 631 Dec 29, 2022
You can dismiss modal viewcontroller like Facebook Messenger by pulling scrollview or navigationbar in Swift.

PullToDismiss PullToDismiss provides dismiss modal viewcontroller function like Facebook Messenger by pulling scrollview or navigationbar with smooth

Suguru Kishimoto 479 Dec 5, 2022
FacebookMe is a Swift App Mimics the personal profile tab of Facebook.

FacebookMe FacebookMe is a Swift App Mimics the personal profile tab of Facebook. It demos one simple way to implement a UITableView with mutiple sect

Kushal Shingote 3 Feb 20, 2022
Fully customizable Facebook reactions like control

Reactions is a fully customizable control to give people more ways to share their reaction in a quick and easy way. Requirements โ€ข Usage โ€ข Installatio

Yannick Loriot 585 Dec 28, 2022
Twitter swift ui tutorial

twitter_swift_ui_tutorial MVVM ์•„ํ‚คํ…์ณ์™€ Swift UI๋ฅผ ์ด์šฉํ•ด์„œ Twitter์˜ MVP ๋ฒ„์ „ ์•ฑ์„ ์ œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šด๋‹ค. API๋ฅผ Firestore ๋ฐ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๊ณผ ํ†ตํ•ฉํ•˜๋Š” ์ž‘์—…, ์œ ์ €๋ฅผ ํŒ”๋กœ์šฐํ•˜๊ณ , tweet ์ƒ์„ฑ, ์ข‹์•„์š”, direc

donggyu 7 Apr 10, 2022
MUDownloadButton - a Progressive Download button written in pure swift and inspired by AppStore download button

MUDownloadButton is a Progressive Download button written in pure swift and inspired by AppStore download button . feel free to contribute and pull requests

Mohammad ShahibZadeh 2 Feb 20, 2022
SpriteKit Floating Bubble Picker (inspired by Apple Music) ๐Ÿงฒ

Magnetic Magnetic is a customizable bubble picker like the Apple Music genre selection. Demo Video $ pod try Magnetic Features Adding/Removing Nodes

Lasha Efremidze 1.4k Jan 6, 2023
Iridescent Effect View (inspired by Apple Pay Cash) โœจ

Shiny Shiny is an iOS library that generates an iridescent effect view matched to the gyroscope, similar to the Apple Pay Cash card in the Wallet app.

Lasha Efremidze 768 Dec 2, 2022
A modern HUD inspired by Apple Music and Apple Podcasts

HUD A modern HUD inspired by Apple Music and Apple Podcasts. Appearance Light Dark HUD Activity Indicator HUD Requirements iOS 13+ Installation You ca

Bei Li 30 Nov 18, 2022
A micro UIStackView convenience API inspired by SwiftUI

Stacks A micro UIStackView convenience API inspired by SwiftUI. let stack: UIView = .hStack(alignment: .center, margins: .all(16), [ .vStack(spaci

Alexander Grebenyuk 74 Jul 27, 2022
A spotlight-inspired quick action bar for macOS.

DSFQuickActionBar A spotlight-inspired quick action bar for macOS. Why? I've seen this in other mac applications (particularly spotlight) and it's ver

Darren Ford 31 Dec 14, 2022
Bubble pickers, inspired by Apple

AmazingBubbles Bubble pickers, inspired by Apple Requirements: iOS 9.1+ XCode 8.0+ Swift 3.0 Installation AmazingBubbles Library is available through

Gleb Radchenko 63 Oct 14, 2022
TSnackBarView is a simple and flexible UI component fully written in Swift

TSnackBarView is a simple and flexible UI component fully written in Swift. TSnackBarView helps you to show snackbar easily with 3 styles: normal, successful and error

Nguyen Duc Thinh 3 Aug 22, 2022
TDetailBoxView is a simple and flexible UI component fully written in Swift

TDetailBoxView is a simple and flexible UI component fully written in Swift. TDetailBoxView is developed to help users quickly display the detail screen without having to develop from scratch.

Nguyen Duc Thinh 2 Aug 18, 2022
TSwitchLabel is a simple and flexible UI component fully written in Swift.

TSwitchLabel is a simple and flexible UI component fully written in Swift. TSwitchLabel is developed for you to easily use when you need to design a UI with Label and Switch in the fastest way without having to spend time on develop from scratch.

Nguyen Duc Thinh 2 Aug 18, 2022
Creating a simple selectable tag view in SwiftUI is quite a challenge. here is a simple & elegant example of it.

SwiftUI TagView Creating a simple selectable tag view in SwiftUI is quite a challenge. here is a simple & elegant example of it. Usage: Just copy the

Ahmadreza 16 Dec 28, 2022
A message bar for iOS written in Swift.

Dodo, a message bar for iOS / Swift This is a UI widget for showing text messages in iOS apps. It is useful for showing short messages to the user, so

Evgenii Neumerzhitckii 874 Dec 13, 2022
Cool Animated music indicator view written in Swift

Cool Animated music indicator view written in Swift. ESTMusicIndicator is an implementation of NAKPlaybackIndicatorView in Swift for iOS 8. ๆœฌไบบ่‘—ไฝœ็š„ไนฆ็ฑใ€ŠLa

Aufree 465 Nov 28, 2022