Compare commits
No commits in common. "master" and "2.0.3" have entirely different histories.
186
CHANGELOG.md
186
CHANGELOG.md
|
|
@ -1,186 +0,0 @@
|
||||||
# Change Log
|
|
||||||
|
|
||||||
## 3.1.2
|
|
||||||
|
|
||||||
Released on 16-9-2016
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Scrolling performance slowed #145
|
|
||||||
|
|
||||||
## 3.1.1
|
|
||||||
|
|
||||||
Released on 15-9-2016
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Example crash in xcode8 fixed
|
|
||||||
- Provides various UI configuration options via SKPhotoBrowserOptions. #144
|
|
||||||
|
|
||||||
## 3.1.0
|
|
||||||
|
|
||||||
Released on 9-2016
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Issue with multiple actionButtonTitles #137
|
|
||||||
- fix swiftlint warnings #140
|
|
||||||
- Update for Xcode 8 GM (swift 2.3). #141
|
|
||||||
|
|
||||||
## 3.0.2
|
|
||||||
|
|
||||||
Released on 9-2016
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Issue with multiple actionButtonTitles #137
|
|
||||||
- Impossible to zoom when resolution is 1024x768 #134
|
|
||||||
- Crash bug at zooming scrool view #133
|
|
||||||
|
|
||||||
## 3.0.1
|
|
||||||
|
|
||||||
Released on 9-2016
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Skip loading image if already loaded #135
|
|
||||||
|
|
||||||
Released on 8-2016
|
|
||||||
|
|
||||||
#### Some Interface is removed, changed this version.
|
|
||||||
- status bar handling is removed.
|
|
||||||
- custom button handling interface is chagned.
|
|
||||||
- custom option goes internal/private. use option via SKPhotoBrowserOptions.
|
|
||||||
|
|
||||||
#### Add
|
|
||||||
- Add changelog
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- prepare for swift3.0.
|
|
||||||
- refactoring code for new implement.
|
|
||||||
- Parent View disappears when dismissed. #120
|
|
||||||
- Glitch when origin imageview is not correct size #108
|
|
||||||
- Problems with the "long" photo #116
|
|
||||||
|
|
||||||
#### Remove
|
|
||||||
- Statusbar handling.
|
|
||||||
- Some public property to internal for improving
|
|
||||||
|
|
||||||
## 2.0.x
|
|
||||||
Released on 8-2016
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- Migrate UIImage cache category to new SKCache
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Make cached response data return optional
|
|
||||||
- Fixed issue when animatedFromView not has a superview but has superlayer
|
|
||||||
- Fixed when image downloaded then not show activityindicator
|
|
||||||
- Update for Swift2.3
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.9.x
|
|
||||||
Released on 6-2016
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- Delegate to notify when the user scroll to an index
|
|
||||||
- Single tap to dismiss
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Fixed a bug where the activity indicator was only visible
|
|
||||||
- Fixed unit test and problems running when being bridged
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.8.x
|
|
||||||
Released on 4-2016
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- Using SKPhotoProtocol to enable usage from SKLocalPhoto
|
|
||||||
- SKLocalPhoto to support local photo from file
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Bug when animation when tap.
|
|
||||||
- The indicator may not disappear when loading local image
|
|
||||||
- Event crash when closing before image has been loaded
|
|
||||||
- Fix crash on initialisation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.7.x
|
|
||||||
Released on 3-2016
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- Enable ability to override statusBar style
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Update for swift2.0
|
|
||||||
- Bug when zooming small image
|
|
||||||
- Prevent crash when closing before image has been loaded
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.6.x
|
|
||||||
Released on 2016-3
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Change maxScale to 1.0 it works perfectly.
|
|
||||||
- Fixed the bug which was after the device rotation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.5.x
|
|
||||||
Released on 2016-3
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- Delete Button
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Change maxScale to 1.0 it works perfectly.
|
|
||||||
- Rew algorithm for maxScale.
|
|
||||||
- Changed UIActionSheet to UIAlertController with ActionSheet style
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.4.x
|
|
||||||
Released on 2-2016
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- Delegate add for actionbutton.
|
|
||||||
- DidShowPhotoAtIndex delegate goes to optional.
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Zooming bug fixed.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.3.x
|
|
||||||
Released on 1-2016
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- Added action functionality similar to IDMPhotoBrowser.
|
|
||||||
- Add extra caption for share
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Bug fixed for mail crash
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.2.x
|
|
||||||
Released on 10-2015
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
- SKPhotoProtocol is implemented.
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- Double tap bug fixed
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1.1.x
|
|
||||||
Released on 10-2015
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
- some property make private.
|
|
||||||
- layout bug fixed when zoom.
|
|
||||||
|
|
||||||
## 1.0.0
|
|
||||||
Released on 10-2015
|
|
||||||
|
|
||||||
123
README.md
123
README.md
|
|
@ -1,22 +1,18 @@
|
||||||
SKPhotoBrowser
|
SKPhotoBrowser
|
||||||
========================
|
========================
|
||||||
|
|
||||||

|
|
||||||
[](https://github.com/Carthage/Carthage)
|
[](https://github.com/Carthage/Carthage)
|
||||||
[](http://cocoadocs.org/docsets/SKPhotoBrowser)
|
[](http://cocoadocs.org/docsets/SKPhotoBrowser)
|
||||||
|
|
||||||
Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift, based on [IDMPhotoBrowser](https://github.com/ideaismobile/IDMPhotoBrowser), [MWPhotoBrowser](https://github.com/mwaterfall/MWPhotoBrowser).
|
Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift, based on [IDMPhotoBrowser](https://github.com/ideaismobile/IDMPhotoBrowser), [MWPhotoBrowser](https://github.com/mwaterfall/MWPhotoBrowser).
|
||||||
|
|
||||||
## Note
|
|
||||||
- released v3.0.x and this version goes some breaking changes. please check [CHANGELOG](https://github.com/suzuki-0000/SKPhotoBrowser/blob/master/CHANGELOG.md).
|
|
||||||
|
|
||||||
## features
|
## features
|
||||||
- Display one or more images by providing either `UIImage` objects, or string of URL array.
|
- Can 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
|
- Photos can be zoomed and panned, and optional captions can be displayed
|
||||||
- Minimalistic Facebook-like interface, swipe up/down to dismiss
|
- Minimalistic Facebook-like interface, swipe up/down to dismiss
|
||||||
- Ability to custom control. (hide/ show toolbar for controls, / swipe control)
|
- has simple ability to custom photobrowser. (hide/show statusbar, some toolbar for controls, swipe control)
|
||||||
- Handling and caching photos from web
|
- Handling and caching photos from web
|
||||||
- Landscape handling
|
- 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
|
- Delete photo support(by offbye). By set displayDelete=true show a delete icon in statusbar, deleted indexes can be obtain from delegate func didDeleted
|
||||||
|
|
||||||

|

|
||||||
|
|
@ -46,45 +42,43 @@ github "suzuki-0000/SKPhotoBrowser"
|
||||||
Add the code directly into your project.
|
Add the code directly into your project.
|
||||||
|
|
||||||
##Usage
|
##Usage
|
||||||
See the code snippet below for an example of how to implement, or see the example project.
|
See the code snippet below for an example of how to implement, or example project would be easy to understand.
|
||||||
|
|
||||||
from UIImages:
|
|
||||||
```swift
|
```swift
|
||||||
// 1. create SKPhoto Array from UIImage
|
// add SKPhoto Array from UIImage
|
||||||
var images = [SKPhoto]()
|
var images = [SKPhoto]()
|
||||||
let photo = SKPhoto.photoWithImage(UIImage())// add some UIImage
|
let photo = SKPhoto.photoWithImage(UIImage())// add some UIImage
|
||||||
images.append(photo)
|
images.append(photo)
|
||||||
|
|
||||||
// 2. create PhotoBrowser Instance, and present from your viewController.
|
// create PhotoBrowser Instance, and present.
|
||||||
let browser = SKPhotoBrowser(photos: images)
|
let browser = SKPhotoBrowser(photos: images)
|
||||||
browser.initializePageIndex(0)
|
browser.initializePageIndex(0)
|
||||||
|
browser.delegate = self
|
||||||
presentViewController(browser, animated: true, completion: {})
|
presentViewController(browser, animated: true, completion: {})
|
||||||
```
|
```
|
||||||
|
|
||||||
from URLs:
|
from web URLs:
|
||||||
```swift
|
```swift
|
||||||
// 1. create URL Array
|
// URL pattern snippet
|
||||||
var images = [SKPhoto]()
|
var images = [SKPhoto]()
|
||||||
let photo = SKPhoto.photoWithImageURL("https://placehold.jp/150x150.png")
|
let photo = SKPhoto.photoWithImageURL("https://placehold.jp/150x150.png")
|
||||||
photo.shouldCachePhotoURLImage = false // you can use image cache by true(NSCache)
|
photo.shouldCachePhotoURLImage = false // you can use image cache by true(NSCache)
|
||||||
images.append(photo)
|
images.append(photo)
|
||||||
|
|
||||||
// 2. create PhotoBrowser Instance, and present.
|
// create PhotoBrowser Instance, and present.
|
||||||
let browser = SKPhotoBrowser(photos: images)
|
let browser = SKPhotoBrowser(photos: images)
|
||||||
browser.initializePageIndex(0)
|
|
||||||
presentViewController(browser, animated: true, completion: {})
|
presentViewController(browser, animated: true, completion: {})
|
||||||
```
|
```
|
||||||
|
|
||||||
from local files:
|
from local files:
|
||||||
```swift
|
```swift
|
||||||
// 1. create images from local files
|
// images from local files
|
||||||
var images = [SKLocalPhoto]()
|
var images = [SKLocalPhoto]()
|
||||||
let photo = SKLocalPhoto.photoWithImageURL("..some_local_path/150x150.png")
|
let photo = SKLocalPhoto.photoWithImageURL("..some_local_path/150x150.png")
|
||||||
images.append(photo)
|
images.append(photo)
|
||||||
|
|
||||||
// 2. create PhotoBrowser Instance, and present.
|
// create PhotoBrowser Instance, and present.
|
||||||
let browser = SKPhotoBrowser(photos: images)
|
let browser = SKPhotoBrowser(photos: images)
|
||||||
browser.initializePageIndex(0)
|
|
||||||
presentViewController(browser, animated: true, completion: {})
|
presentViewController(browser, animated: true, completion: {})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -94,7 +88,6 @@ If you want to use zooming effect from an existing view, use another initializer
|
||||||
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
|
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
|
||||||
let cell = collectionView.cellForItemAtIndexPath(indexPath)
|
let cell = collectionView.cellForItemAtIndexPath(indexPath)
|
||||||
let originImage = cell.exampleImageView.image // some image for baseImage
|
let originImage = cell.exampleImageView.image // some image for baseImage
|
||||||
|
|
||||||
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
|
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
|
||||||
browser.initializePageIndex(indexPath.row)
|
browser.initializePageIndex(indexPath.row)
|
||||||
presentViewController(browser, animated: true, completion: {})
|
presentViewController(browser, animated: true, completion: {})
|
||||||
|
|
@ -104,65 +97,40 @@ func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath i
|
||||||
### Custom
|
### Custom
|
||||||
|
|
||||||
#### Toolbar
|
#### Toolbar
|
||||||
You can customize Toolbar via SKPhotoBrowserOptions.
|
You can customize the toolbar(back/forward, counter, some action) button.
|
||||||
|
- displayCounterLabel (default is true)
|
||||||
|
- displayBackAndForwardButton (default is true)
|
||||||
|
- displayAction (default is true)
|
||||||
|
|
||||||
|
If you dont want the toolbar at all, you can set displayToolbar = false (default is true)
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
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.displayDeleteButton = true // delete button will be shown
|
|
||||||
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)
|
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
|
||||||
```
|
browser.displayToolbar = false // all tool bar will be hidden
|
||||||
|
browser.displayCounterLabel = false // counter label will be hidden
|
||||||
#### Colors
|
browser.displayBackAndForwardButton = false // back / forward button will be hidden
|
||||||
You can customize text, icon and background colors via SKPhotoBrowserOptions
|
browser.displayAction = false // action button will be hidden
|
||||||
```swift
|
browser.displayDeleteButton = true // delete button will be shown
|
||||||
SKPhotoBrowserOptions.backgroundColor = UIColor.whiteColor() // browser view will be white
|
|
||||||
SKPhotoBrowserOptions.textAndIconColor = UIColor.blackColor() // text and icons will be black
|
|
||||||
SKPhotoBrowserOptions.toolbarTextShadowColor = UIColor.clearColor() // shadow of toolbar text will be removed
|
|
||||||
SKPhotoBrowserOptions.toolbarFont = UIFont(name: "Futura", size: 16.0) // font of toolbar will be 'Futura'
|
|
||||||
SKPhotoBrowserOptions.captionFont = UIFont(name: "Helvetica", size: 18.0) // font of toolbar will be 'Helvetica'
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Images
|
|
||||||
You can customize the padding of displayed images via SKPhotoBrowserOptions
|
|
||||||
```swift
|
|
||||||
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
|
|
||||||
```swift
|
|
||||||
SKPhotoBrowserOptions.displayStatusbar = false // status bar will be hidden
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Custom Cache From Web URL
|
|
||||||
You can use SKCacheable protocol if others are adaptable. (SKImageCacheable or SKRequestResponseCacheable)
|
|
||||||
|
|
||||||
```swift
|
|
||||||
e.g. SDWebImage
|
|
||||||
|
|
||||||
// 1. create custon cache. implement function for protocol
|
|
||||||
class CustomImageCache: SKImageCacheable { var cache: SDImageCache }
|
|
||||||
|
|
||||||
// 2. replace SKCache instance with custom cache
|
|
||||||
SKCache.sharedCache.imageCache = CustomImageCache()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### CustomButton Image
|
#### CustomButton Image
|
||||||
Close, Delete buttons are able to change image and frame.
|
Close button is able to change image and frame.
|
||||||
``` swift
|
``` swift
|
||||||
browser.updateCloseButton(UIImage())
|
browser.displayCustomCloseButton = true // custom close button will be enable
|
||||||
browser.updateUpdateButton(UIImage())
|
browser.customCloseButtonImage = UIImage(named: "some.png")
|
||||||
|
browser.customCloseButtonShowFrame = CGRect()
|
||||||
|
browser.customCloseButtonHideFrame = CGRect()
|
||||||
|
```
|
||||||
|
Delete button is able to change image and frame.
|
||||||
|
``` swift
|
||||||
|
browser.displayCustomDeleteButton = true // custom delete button will be enable
|
||||||
|
browser.customDeleteButtonImage = UIImage(named: "some.png")
|
||||||
|
browser.customDeleteButtonShowFrame = CGRect()
|
||||||
|
browser.customDeleteButtonHideFrame = CGRect()
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Delete Photo
|
#### Delete
|
||||||
You can delete your photo for your own handling. detect button tap from `removePhoto` delegate function.
|
You can delete your photo for your own hanlding.
|
||||||
|
|
||||||
|
|
||||||
#### Photo Captions
|
#### Photo Captions
|
||||||
Photo captions can be displayed simply bottom of PhotoBrowser. by setting the `caption` property on specific photos:
|
Photo captions can be displayed simply bottom of PhotoBrowser. by setting the `caption` property on specific photos:
|
||||||
|
|
@ -175,7 +143,8 @@ images.append(photo)
|
||||||
#### SwipeGesture
|
#### SwipeGesture
|
||||||
vertical swipe can enable/disable:
|
vertical swipe can enable/disable:
|
||||||
``` swift
|
``` swift
|
||||||
SKPhotoBrowserOptions.disableVerticalSwipe = true
|
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
|
||||||
|
browser.disableVerticalSwipe = true
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Delegate
|
#### Delegate
|
||||||
|
|
@ -208,16 +177,14 @@ func didDismissAtPageIndex(index: Int) {
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Options
|
#### Minor Option
|
||||||
You can access via `SKPhotoBrowserOptions`, which can use for browser control.
|
|
||||||
- single tap handling, dismiss/noaction
|
|
||||||
- blackArea handling which is appearing outside of photo
|
- blackArea handling which is appearing outside of photo
|
||||||
|
- single tap handling, dismiss/noaction
|
||||||
- bounce animation when appearing/dismissing
|
- bounce animation when appearing/dismissing
|
||||||
- text color, font, or more
|
|
||||||
``` swift
|
``` swift
|
||||||
SKPhotoBrowserOptions.enableZoomBlackArea = true // default true
|
enableZoomBlackArea = true // default true
|
||||||
SKPhotoBrowserOptions.enableSingleTapDismiss = true // default false
|
enableSingleTapDismiss = true // default false
|
||||||
SKPhotoBrowserOptions.bounceAnimation = true // default false
|
bounceAnimation = true // default false
|
||||||
```
|
```
|
||||||
|
|
||||||
## Photos from
|
## Photos from
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "SKPhotoBrowser"
|
s.name = "SKPhotoBrowser"
|
||||||
s.version = "3.1.2"
|
s.version = "2.0.3"
|
||||||
s.summary = "Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift2.0."
|
s.summary = "Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift2.0."
|
||||||
s.homepage = "https://github.com/suzuki-0000/SKPhotoBrowser"
|
s.homepage = "https://github.com/suzuki-0000/SKPhotoBrowser"
|
||||||
s.license = { :type => "MIT", :file => "LICENSE" }
|
s.license = { :type => "MIT", :file => "LICENSE" }
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
0AE527521DABB87500619FAD /* SKNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE527511DABB87500619FAD /* SKNavigationBar.swift */; };
|
|
||||||
210E53ED1C986D3A008DD5E3 /* UIView+Radius.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210E53EC1C986D3A008DD5E3 /* UIView+Radius.swift */; };
|
210E53ED1C986D3A008DD5E3 /* UIView+Radius.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210E53EC1C986D3A008DD5E3 /* UIView+Radius.swift */; };
|
||||||
210E53EF1C986D57008DD5E3 /* UIImage+Rotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210E53EE1C986D57008DD5E3 /* UIImage+Rotation.swift */; };
|
210E53EF1C986D57008DD5E3 /* UIImage+Rotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210E53EE1C986D57008DD5E3 /* UIImage+Rotation.swift */; };
|
||||||
26C97AD51D0EB6870039F6CB /* SKCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C97AD41D0EB6870039F6CB /* SKCache.swift */; };
|
26C97AD51D0EB6870039F6CB /* SKCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C97AD41D0EB6870039F6CB /* SKCache.swift */; };
|
||||||
|
|
@ -22,13 +21,6 @@
|
||||||
8909B5491BC791510060A053 /* SKPhotoBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8909B5411BC791510060A053 /* SKPhotoBrowser.swift */; };
|
8909B5491BC791510060A053 /* SKPhotoBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8909B5411BC791510060A053 /* SKPhotoBrowser.swift */; };
|
||||||
8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8909B5421BC791510060A053 /* SKZoomingScrollView.swift */; };
|
8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8909B5421BC791510060A053 /* SKZoomingScrollView.swift */; };
|
||||||
8909B54D1BC7916E0060A053 /* SKPhotoBrowser.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */; };
|
8909B54D1BC7916E0060A053 /* SKPhotoBrowser.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */; };
|
||||||
890A6F201D5D9E53003B01F0 /* SKToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 890A6F1F1D5D9E53003B01F0 /* SKToolbar.swift */; };
|
|
||||||
8917B1B01D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8917B1AF1D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift */; };
|
|
||||||
8917B1B41D5A14B0000CE1C4 /* SKButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */; };
|
|
||||||
89C24A821D657AD1005F09A9 /* SKPhotoBrowserOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C24A811D657AD1005F09A9 /* SKPhotoBrowserOptions.swift */; };
|
|
||||||
89C24A841D657AFE005F09A9 /* SKPagingScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C24A831D657AFE005F09A9 /* SKPagingScrollView.swift */; };
|
|
||||||
89D0BA471D5994A8002A811B /* SKAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89D0BA461D5994A8002A811B /* SKAnimator.swift */; };
|
|
||||||
89D0BA491D59966B002A811B /* SKMesurement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89D0BA481D59966B002A811B /* SKMesurement.swift */; };
|
|
||||||
8CA6C6521CBE76E80054D3C2 /* SKLocalPhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */; };
|
8CA6C6521CBE76E80054D3C2 /* SKLocalPhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */; };
|
||||||
A64B89361CB04222000071B9 /* SKPhotoBrowserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A64B89351CB04222000071B9 /* SKPhotoBrowserTests.swift */; };
|
A64B89361CB04222000071B9 /* SKPhotoBrowserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A64B89351CB04222000071B9 /* SKPhotoBrowserTests.swift */; };
|
||||||
A64B89381CB04222000071B9 /* SKPhotoBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5301BC791280060A053 /* SKPhotoBrowser.framework */; };
|
A64B89381CB04222000071B9 /* SKPhotoBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5301BC791280060A053 /* SKPhotoBrowser.framework */; };
|
||||||
|
|
@ -45,7 +37,6 @@
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
0AE527511DABB87500619FAD /* SKNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKNavigationBar.swift; sourceTree = "<group>"; };
|
|
||||||
210E53EC1C986D3A008DD5E3 /* UIView+Radius.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+Radius.swift"; path = "extensions/UIView+Radius.swift"; sourceTree = "<group>"; };
|
210E53EC1C986D3A008DD5E3 /* UIView+Radius.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+Radius.swift"; path = "extensions/UIView+Radius.swift"; sourceTree = "<group>"; };
|
||||||
210E53EE1C986D57008DD5E3 /* UIImage+Rotation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIImage+Rotation.swift"; path = "extensions/UIImage+Rotation.swift"; sourceTree = "<group>"; };
|
210E53EE1C986D57008DD5E3 /* UIImage+Rotation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIImage+Rotation.swift"; path = "extensions/UIImage+Rotation.swift"; sourceTree = "<group>"; };
|
||||||
26C97AD41D0EB6870039F6CB /* SKCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKCache.swift; sourceTree = "<group>"; };
|
26C97AD41D0EB6870039F6CB /* SKCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKCache.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -62,13 +53,6 @@
|
||||||
8909B5411BC791510060A053 /* SKPhotoBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowser.swift; sourceTree = "<group>"; };
|
8909B5411BC791510060A053 /* SKPhotoBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowser.swift; sourceTree = "<group>"; };
|
||||||
8909B5421BC791510060A053 /* SKZoomingScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKZoomingScrollView.swift; sourceTree = "<group>"; };
|
8909B5421BC791510060A053 /* SKZoomingScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKZoomingScrollView.swift; sourceTree = "<group>"; };
|
||||||
8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SKPhotoBrowser.bundle; sourceTree = "<group>"; };
|
8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SKPhotoBrowser.bundle; sourceTree = "<group>"; };
|
||||||
890A6F1F1D5D9E53003B01F0 /* SKToolbar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKToolbar.swift; sourceTree = "<group>"; };
|
|
||||||
8917B1AF1D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowserDelegate.swift; sourceTree = "<group>"; };
|
|
||||||
8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKButtons.swift; sourceTree = "<group>"; };
|
|
||||||
89C24A811D657AD1005F09A9 /* SKPhotoBrowserOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowserOptions.swift; sourceTree = "<group>"; };
|
|
||||||
89C24A831D657AFE005F09A9 /* SKPagingScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPagingScrollView.swift; sourceTree = "<group>"; };
|
|
||||||
89D0BA461D5994A8002A811B /* SKAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKAnimator.swift; sourceTree = "<group>"; };
|
|
||||||
89D0BA481D59966B002A811B /* SKMesurement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKMesurement.swift; sourceTree = "<group>"; };
|
|
||||||
8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKLocalPhoto.swift; sourceTree = "<group>"; };
|
8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKLocalPhoto.swift; sourceTree = "<group>"; };
|
||||||
A64B89331CB04222000071B9 /* SKPhotoBrowserTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SKPhotoBrowserTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
A64B89331CB04222000071B9 /* SKPhotoBrowserTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SKPhotoBrowserTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
A64B89351CB04222000071B9 /* SKPhotoBrowserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowserTests.swift; sourceTree = "<group>"; };
|
A64B89351CB04222000071B9 /* SKPhotoBrowserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowserTests.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -124,25 +108,17 @@
|
||||||
8909B5321BC791280060A053 /* SKPhotoBrowser */ = {
|
8909B5321BC791280060A053 /* SKPhotoBrowser */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
89D0BA461D5994A8002A811B /* SKAnimator.swift */,
|
|
||||||
8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */,
|
|
||||||
26C97AD41D0EB6870039F6CB /* SKCache.swift */,
|
26C97AD41D0EB6870039F6CB /* SKCache.swift */,
|
||||||
26C97AD81D0EB8BB0039F6CB /* SKCacheable.swift */,
|
26C97AD81D0EB8BB0039F6CB /* SKCacheable.swift */,
|
||||||
8909B53B1BC791510060A053 /* SKCaptionView.swift */,
|
8909B53B1BC791510060A053 /* SKCaptionView.swift */,
|
||||||
8909B53C1BC791510060A053 /* SKDetectingImageView.swift */,
|
8909B53C1BC791510060A053 /* SKDetectingImageView.swift */,
|
||||||
8909B53D1BC791510060A053 /* SKDetectingView.swift */,
|
8909B53D1BC791510060A053 /* SKDetectingView.swift */,
|
||||||
8909B53E1BC791510060A053 /* SKIndicatorView.swift */,
|
8909B53E1BC791510060A053 /* SKIndicatorView.swift */,
|
||||||
8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */,
|
|
||||||
89C24A831D657AFE005F09A9 /* SKPagingScrollView.swift */,
|
|
||||||
8909B53F1BC791510060A053 /* SKPhoto.swift */,
|
8909B53F1BC791510060A053 /* SKPhoto.swift */,
|
||||||
|
8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */,
|
||||||
8909B5411BC791510060A053 /* SKPhotoBrowser.swift */,
|
8909B5411BC791510060A053 /* SKPhotoBrowser.swift */,
|
||||||
89C24A811D657AD1005F09A9 /* SKPhotoBrowserOptions.swift */,
|
|
||||||
890A6F1F1D5D9E53003B01F0 /* SKToolbar.swift */,
|
|
||||||
0AE527511DABB87500619FAD /* SKNavigationBar.swift */,
|
|
||||||
8909B5331BC791280060A053 /* SKPhotoBrowser.h */,
|
|
||||||
8917B1AF1D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift */,
|
|
||||||
89D0BA481D59966B002A811B /* SKMesurement.swift */,
|
|
||||||
8909B5421BC791510060A053 /* SKZoomingScrollView.swift */,
|
8909B5421BC791510060A053 /* SKZoomingScrollView.swift */,
|
||||||
|
8909B5331BC791280060A053 /* SKPhotoBrowser.h */,
|
||||||
8909B5351BC791280060A053 /* Info.plist */,
|
8909B5351BC791280060A053 /* Info.plist */,
|
||||||
210E53EB1C986D1C008DD5E3 /* extensions */,
|
210E53EB1C986D1C008DD5E3 /* extensions */,
|
||||||
8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */,
|
8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */,
|
||||||
|
|
@ -223,11 +199,9 @@
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8909B52F1BC791280060A053 = {
|
8909B52F1BC791280060A053 = {
|
||||||
CreatedOnToolsVersion = 7.0;
|
CreatedOnToolsVersion = 7.0;
|
||||||
LastSwiftMigration = 0800;
|
|
||||||
};
|
};
|
||||||
A64B89321CB04222000071B9 = {
|
A64B89321CB04222000071B9 = {
|
||||||
CreatedOnToolsVersion = 7.3;
|
CreatedOnToolsVersion = 7.3;
|
||||||
LastSwiftMigration = 0800;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -289,21 +263,13 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
26C97AD91D0EB8BB0039F6CB /* SKCacheable.swift in Sources */,
|
26C97AD91D0EB8BB0039F6CB /* SKCacheable.swift in Sources */,
|
||||||
89C24A841D657AFE005F09A9 /* SKPagingScrollView.swift in Sources */,
|
|
||||||
890A6F201D5D9E53003B01F0 /* SKToolbar.swift in Sources */,
|
|
||||||
8909B5441BC791510060A053 /* SKDetectingImageView.swift in Sources */,
|
8909B5441BC791510060A053 /* SKDetectingImageView.swift in Sources */,
|
||||||
8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */,
|
8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */,
|
||||||
8CA6C6521CBE76E80054D3C2 /* SKLocalPhoto.swift in Sources */,
|
8CA6C6521CBE76E80054D3C2 /* SKLocalPhoto.swift in Sources */,
|
||||||
89D0BA471D5994A8002A811B /* SKAnimator.swift in Sources */,
|
|
||||||
210E53ED1C986D3A008DD5E3 /* UIView+Radius.swift in Sources */,
|
210E53ED1C986D3A008DD5E3 /* UIView+Radius.swift in Sources */,
|
||||||
8917B1B01D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift in Sources */,
|
|
||||||
89D0BA491D59966B002A811B /* SKMesurement.swift in Sources */,
|
|
||||||
8909B5471BC791510060A053 /* SKPhoto.swift in Sources */,
|
8909B5471BC791510060A053 /* SKPhoto.swift in Sources */,
|
||||||
8909B5461BC791510060A053 /* SKIndicatorView.swift in Sources */,
|
8909B5461BC791510060A053 /* SKIndicatorView.swift in Sources */,
|
||||||
8917B1B41D5A14B0000CE1C4 /* SKButtons.swift in Sources */,
|
|
||||||
89C24A821D657AD1005F09A9 /* SKPhotoBrowserOptions.swift in Sources */,
|
|
||||||
26C97AD51D0EB6870039F6CB /* SKCache.swift in Sources */,
|
26C97AD51D0EB6870039F6CB /* SKCache.swift in Sources */,
|
||||||
0AE527521DABB87500619FAD /* SKNavigationBar.swift in Sources */,
|
|
||||||
210E53EF1C986D57008DD5E3 /* UIImage+Rotation.swift in Sources */,
|
210E53EF1C986D57008DD5E3 /* UIImage+Rotation.swift in Sources */,
|
||||||
8909B5431BC791510060A053 /* SKCaptionView.swift in Sources */,
|
8909B5431BC791510060A053 /* SKCaptionView.swift in Sources */,
|
||||||
8909B5491BC791510060A053 /* SKPhotoBrowser.swift in Sources */,
|
8909B5491BC791510060A053 /* SKPhotoBrowser.swift in Sources */,
|
||||||
|
|
@ -436,7 +402,6 @@
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 2.3;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
|
@ -455,7 +420,6 @@
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.SKPhotoBrowser;
|
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.SKPhotoBrowser;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 2.3;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
|
@ -468,7 +432,6 @@
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "Alexsander-Khitev.SKPhotoBrowserTests";
|
PRODUCT_BUNDLE_IDENTIFIER = "Alexsander-Khitev.SKPhotoBrowserTests";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 2.3;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
|
@ -481,7 +444,6 @@
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "Alexsander-Khitev.SKPhotoBrowserTests";
|
PRODUCT_BUNDLE_IDENTIFIER = "Alexsander-Khitev.SKPhotoBrowserTests";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 2.3;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,189 +0,0 @@
|
||||||
//
|
|
||||||
// SKAnimator.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by keishi suzuki on 2016/08/09.
|
|
||||||
// Copyright © 2016 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
|
|
||||||
@objc public protocol SKPhotoBrowserAnimatorDelegate {
|
|
||||||
func willPresent(browser: SKPhotoBrowser)
|
|
||||||
func willDismiss(browser: SKPhotoBrowser)
|
|
||||||
}
|
|
||||||
|
|
||||||
class SKAnimator: NSObject, SKPhotoBrowserAnimatorDelegate {
|
|
||||||
var resizableImageView: UIImageView?
|
|
||||||
|
|
||||||
var senderOriginImage: UIImage!
|
|
||||||
var senderViewOriginalFrame: CGRect = .zero
|
|
||||||
var senderViewForAnimation: UIView?
|
|
||||||
|
|
||||||
var finalImageViewFrame: CGRect = .zero
|
|
||||||
|
|
||||||
var bounceAnimation: Bool = false
|
|
||||||
var animationDuration: NSTimeInterval {
|
|
||||||
if SKPhotoBrowserOptions.bounceAnimation {
|
|
||||||
return 0.5
|
|
||||||
}
|
|
||||||
return 0.35
|
|
||||||
}
|
|
||||||
var animationDamping: CGFloat {
|
|
||||||
if SKPhotoBrowserOptions.bounceAnimation {
|
|
||||||
return 0.8
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func willPresent(browser: SKPhotoBrowser) {
|
|
||||||
guard let appWindow = UIApplication.sharedApplication().delegate?.window else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard let window = appWindow else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard let sender = browser.delegate?.viewForPhoto?(browser, index: browser.initialPageIndex) ?? senderViewForAnimation else {
|
|
||||||
presentAnimation(browser)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let photo = browser.photoAtIndex(browser.currentPageIndex)
|
|
||||||
let imageFromView = (senderOriginImage ?? browser.getImageFromView(sender)).rotateImageByOrientation()
|
|
||||||
let imageRatio = imageFromView.size.width / imageFromView.size.height
|
|
||||||
|
|
||||||
senderViewOriginalFrame = calcOriginFrame(sender)
|
|
||||||
finalImageViewFrame = calcFinalFrame(imageRatio)
|
|
||||||
|
|
||||||
resizableImageView = UIImageView(image: imageFromView)
|
|
||||||
resizableImageView!.frame = senderViewOriginalFrame
|
|
||||||
resizableImageView!.clipsToBounds = true
|
|
||||||
resizableImageView!.contentMode = photo.contentMode
|
|
||||||
if sender.layer.cornerRadius != 0 {
|
|
||||||
let duration = (animationDuration * Double(animationDamping))
|
|
||||||
resizableImageView!.layer.masksToBounds = true
|
|
||||||
resizableImageView!.addCornerRadiusAnimation(sender.layer.cornerRadius, to: 0, duration: duration)
|
|
||||||
}
|
|
||||||
window.addSubview(resizableImageView!)
|
|
||||||
|
|
||||||
presentAnimation(browser)
|
|
||||||
}
|
|
||||||
|
|
||||||
func willDismiss(browser: SKPhotoBrowser) {
|
|
||||||
guard let sender = browser.delegate?.viewForPhoto?(browser, index: browser.currentPageIndex),
|
|
||||||
image = browser.photoAtIndex(browser.currentPageIndex).underlyingImage,
|
|
||||||
scrollView = browser.pageDisplayedAtIndex(browser.currentPageIndex) else {
|
|
||||||
|
|
||||||
senderViewForAnimation?.hidden = false
|
|
||||||
browser.dismissPhotoBrowser(animated: false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
senderViewForAnimation = sender
|
|
||||||
browser.view.hidden = true
|
|
||||||
browser.backgroundView.hidden = false
|
|
||||||
browser.backgroundView.alpha = 1
|
|
||||||
|
|
||||||
senderViewOriginalFrame = calcOriginFrame(sender)
|
|
||||||
|
|
||||||
let photo = browser.photoAtIndex(browser.currentPageIndex)
|
|
||||||
let contentOffset = scrollView.contentOffset
|
|
||||||
let scrollFrame = scrollView.photoImageView.frame
|
|
||||||
let offsetY = scrollView.center.y - (scrollView.bounds.height/2)
|
|
||||||
let frame = CGRect(
|
|
||||||
x: scrollFrame.origin.x - contentOffset.x,
|
|
||||||
y: scrollFrame.origin.y + contentOffset.y + offsetY,
|
|
||||||
width: scrollFrame.width,
|
|
||||||
height: scrollFrame.height)
|
|
||||||
|
|
||||||
// resizableImageView.image = scrollView.photo?.underlyingImage?.rotateImageByOrientation()
|
|
||||||
resizableImageView!.image = image.rotateImageByOrientation()
|
|
||||||
resizableImageView!.frame = frame
|
|
||||||
resizableImageView!.alpha = 1.0
|
|
||||||
resizableImageView!.clipsToBounds = true
|
|
||||||
resizableImageView!.contentMode = photo.contentMode
|
|
||||||
if let view = senderViewForAnimation where view.layer.cornerRadius != 0 {
|
|
||||||
let duration = (animationDuration * Double(animationDamping))
|
|
||||||
resizableImageView!.layer.masksToBounds = true
|
|
||||||
resizableImageView!.addCornerRadiusAnimation(0, to: view.layer.cornerRadius, duration: duration)
|
|
||||||
}
|
|
||||||
|
|
||||||
dismissAnimation(browser)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension SKAnimator {
|
|
||||||
func calcOriginFrame(sender: UIView) -> CGRect {
|
|
||||||
if let senderViewOriginalFrameTemp = sender.superview?.convertRect(sender.frame, toView:nil) {
|
|
||||||
return senderViewOriginalFrameTemp
|
|
||||||
} else if let senderViewOriginalFrameTemp = sender.layer.superlayer?.convertRect(sender.frame, toLayer: nil) {
|
|
||||||
return senderViewOriginalFrameTemp
|
|
||||||
} else {
|
|
||||||
return .zero
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func calcFinalFrame(imageRatio: CGFloat) -> CGRect {
|
|
||||||
if SKMesurement.screenRatio < imageRatio {
|
|
||||||
let width = SKMesurement.screenWidth
|
|
||||||
let height = width / imageRatio
|
|
||||||
let yOffset = (SKMesurement.screenHeight - height) / 2
|
|
||||||
return CGRect(x: 0, y: yOffset, width: width, height: height)
|
|
||||||
} else {
|
|
||||||
let height = SKMesurement.screenHeight
|
|
||||||
let width = height * imageRatio
|
|
||||||
let xOffset = (SKMesurement.screenWidth - width) / 2
|
|
||||||
return CGRect(x: xOffset, y: 0, width: width, height: height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension SKAnimator {
|
|
||||||
func presentAnimation(browser: SKPhotoBrowser, completion: (Void -> Void)? = nil) {
|
|
||||||
browser.view.hidden = true
|
|
||||||
browser.view.alpha = 0.0
|
|
||||||
|
|
||||||
UIView.animateWithDuration(
|
|
||||||
animationDuration,
|
|
||||||
delay: 0,
|
|
||||||
usingSpringWithDamping:animationDamping,
|
|
||||||
initialSpringVelocity:0,
|
|
||||||
options:.CurveEaseInOut,
|
|
||||||
animations: {
|
|
||||||
browser.showButtons()
|
|
||||||
browser.backgroundView.alpha = 1.0
|
|
||||||
|
|
||||||
self.resizableImageView?.frame = self.finalImageViewFrame
|
|
||||||
},
|
|
||||||
completion: { (Bool) -> Void in
|
|
||||||
UIApplication.sharedApplication().setStatusBarHidden(!SKPhotoBrowserOptions.displayStatusbar, withAnimation: .Fade)
|
|
||||||
|
|
||||||
browser.view.hidden = false
|
|
||||||
browser.view.alpha = 1.0
|
|
||||||
browser.backgroundView.hidden = true
|
|
||||||
|
|
||||||
self.resizableImageView?.alpha = 0.0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func dismissAnimation(browser: SKPhotoBrowser, completion: (Void -> Void)? = nil) {
|
|
||||||
UIView.animateWithDuration(
|
|
||||||
animationDuration,
|
|
||||||
delay:0,
|
|
||||||
usingSpringWithDamping:animationDamping,
|
|
||||||
initialSpringVelocity:0,
|
|
||||||
options:.CurveEaseInOut,
|
|
||||||
animations: {
|
|
||||||
browser.backgroundView.alpha = 0.0
|
|
||||||
|
|
||||||
self.resizableImageView?.layer.frame = self.senderViewOriginalFrame
|
|
||||||
},
|
|
||||||
completion: { (Bool) -> () in
|
|
||||||
browser.dismissPhotoBrowser(animated: true) {
|
|
||||||
self.resizableImageView?.removeFromSuperview()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
//
|
|
||||||
// SKButtons.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by 鈴木 啓司 on 2016/08/09.
|
|
||||||
// Copyright © 2016年 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
// helpers which often used
|
|
||||||
private let bundle = NSBundle(forClass: SKPhotoBrowser.self)
|
|
||||||
|
|
||||||
class SKButton: UIButton {
|
|
||||||
var showFrame: CGRect!
|
|
||||||
var hideFrame: CGRect!
|
|
||||||
var insets: UIEdgeInsets {
|
|
||||||
|
|
||||||
|
|
||||||
return UI_USER_INTERFACE_IDIOM() == .Phone
|
|
||||||
? UIEdgeInsets(top: 15.25, left: 15.25, bottom: 15.25, right: 15.25) : UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12)
|
|
||||||
}
|
|
||||||
var size: CGSize = CGSize(width: 44, height: 44)
|
|
||||||
var margin: CGFloat = 5
|
|
||||||
|
|
||||||
var buttonTopOffset: CGFloat { return 5 }
|
|
||||||
|
|
||||||
func setup(imageName: String) {
|
|
||||||
backgroundColor = .clearColor()
|
|
||||||
tintColor = SKPhotoBrowserOptions.textAndIconColor
|
|
||||||
imageEdgeInsets = insets
|
|
||||||
// clipsToBounds = true
|
|
||||||
translatesAutoresizingMaskIntoConstraints = true
|
|
||||||
autoresizingMask = [.FlexibleBottomMargin, .FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin]
|
|
||||||
|
|
||||||
let image = UIImage(named: "SKPhotoBrowser.bundle/images/\(imageName)",
|
|
||||||
inBundle: bundle, compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate) ?? UIImage()
|
|
||||||
setImage(image, forState: .Normal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateFrame() { }
|
|
||||||
|
|
||||||
func setFrameSize(size: CGSize) {
|
|
||||||
let newRect = CGRect(x: margin, y: buttonTopOffset, width: size.width, height: size.height)
|
|
||||||
self.frame = newRect
|
|
||||||
showFrame = newRect
|
|
||||||
hideFrame = CGRect(x: margin, y: -20, width: size.width, height: size.height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SKCloseButton: SKButton {
|
|
||||||
let imageName = "btn_common_close_wh"
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
setup(imageName)
|
|
||||||
showFrame = CGRect(x: margin, y: buttonTopOffset, width: size.width, height: size.height)
|
|
||||||
hideFrame = CGRect(x: margin, y: -20, width: size.width, height: size.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func updateFrame() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SKDeleteButton: SKButton {
|
|
||||||
let imageName = "btn_common_delete_wh"
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
setup(imageName)
|
|
||||||
showFrame = CGRect(x: SKMesurement.screenWidth - size.width, y: buttonTopOffset, width: size.width, height: size.height)
|
|
||||||
hideFrame = CGRect(x: SKMesurement.screenWidth - size.width, y: -20, width: size.width, height: size.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func updateFrame() {
|
|
||||||
}
|
|
||||||
|
|
||||||
override func setFrameSize(size: CGSize) {
|
|
||||||
let newRect = CGRect(x: SKMesurement.screenWidth - size.width, y: buttonTopOffset, width: size.width, height: size.height)
|
|
||||||
self.frame = newRect
|
|
||||||
showFrame = newRect
|
|
||||||
hideFrame = CGRect(x: SKMesurement.screenWidth - size.width, y: -20, width: size.width, height: size.height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -61,13 +61,13 @@ private extension SKCaptionView {
|
||||||
photoLabel.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
|
photoLabel.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
|
||||||
photoLabel.opaque = false
|
photoLabel.opaque = false
|
||||||
photoLabel.backgroundColor = .clearColor()
|
photoLabel.backgroundColor = .clearColor()
|
||||||
photoLabel.textColor = SKPhotoBrowserOptions.textAndIconColor
|
photoLabel.textColor = .whiteColor()
|
||||||
photoLabel.textAlignment = .Center
|
photoLabel.textAlignment = .Center
|
||||||
photoLabel.lineBreakMode = .ByTruncatingTail
|
photoLabel.lineBreakMode = .ByTruncatingTail
|
||||||
photoLabel.numberOfLines = 3
|
photoLabel.numberOfLines = 3
|
||||||
photoLabel.shadowColor = UIColor(white: 0.0, alpha: 0.5)
|
photoLabel.shadowColor = UIColor(white: 0.0, alpha: 0.5)
|
||||||
photoLabel.shadowOffset = CGSize(width: 0.0, height: 1.0)
|
photoLabel.shadowOffset = CGSize(width: 0.0, height: 1.0)
|
||||||
photoLabel.font = SKPhotoBrowserOptions.captionFont
|
photoLabel.font = UIFont.systemFontOfSize(17.0)
|
||||||
photoLabel.text = photo?.caption
|
photoLabel.text = photo?.caption
|
||||||
addSubview(photoLabel)
|
addSubview(photoLabel)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,6 @@ class SKIndicatorView: UIActivityIndicatorView {
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
center = CGPoint(x: frame.width / 2, y: frame.height / 2)
|
center = CGPoint(x: frame.width / 2, y: frame.height / 2)
|
||||||
activityIndicatorViewStyle = SKPhotoBrowserOptions.backgroundColor.isEqual(UIColor.whiteColor()) ? .Gray : .WhiteLarge
|
activityIndicatorViewStyle = .WhiteLarge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ public class SKLocalPhoto: NSObject, SKPhotoProtocol {
|
||||||
|
|
||||||
public var underlyingImage: UIImage!
|
public var underlyingImage: UIImage!
|
||||||
public var photoURL: String!
|
public var photoURL: String!
|
||||||
public var contentMode: UIViewContentMode = .ScaleToFill
|
|
||||||
public var shouldCachePhotoURLImage: Bool = false
|
public var shouldCachePhotoURLImage: Bool = false
|
||||||
public var caption: String!
|
public var caption: String!
|
||||||
public var index: Int = 0
|
public var index: Int = 0
|
||||||
|
|
@ -50,7 +49,9 @@ public class SKLocalPhoto: NSObject, SKPhotoProtocol {
|
||||||
self.underlyingImage = image
|
self.underlyingImage = image
|
||||||
self.loadUnderlyingImageComplete()
|
self.loadUnderlyingImageComplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
//
|
|
||||||
// SKMesurement.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by 鈴木 啓司 on 2016/08/09.
|
|
||||||
// Copyright © 2016年 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
struct SKMesurement {
|
|
||||||
static let isPhone: Bool = UIDevice.currentDevice().userInterfaceIdiom == .Phone
|
|
||||||
static let isPad: Bool = UIDevice.currentDevice().userInterfaceIdiom == .Pad
|
|
||||||
static var statusBarH: CGFloat {
|
|
||||||
return UIApplication.sharedApplication().statusBarFrame.height
|
|
||||||
}
|
|
||||||
static var screenHeight: CGFloat {
|
|
||||||
return UIScreen.mainScreen().bounds.height
|
|
||||||
}
|
|
||||||
static var screenWidth: CGFloat {
|
|
||||||
return UIScreen.mainScreen().bounds.width
|
|
||||||
}
|
|
||||||
static var screenScale: CGFloat {
|
|
||||||
return UIScreen.mainScreen().scale
|
|
||||||
}
|
|
||||||
static var screenRatio: CGFloat {
|
|
||||||
return screenWidth / screenHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
//
|
|
||||||
// SKNavigationBar.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by Григорий Уланов on 10.10.16.
|
|
||||||
// Copyright © 2016 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class SKNavigationBar: UINavigationBar {
|
|
||||||
var showFrame: CGRect!
|
|
||||||
var hideFrame: CGRect!
|
|
||||||
|
|
||||||
private static let toolBarHeight: CGFloat = 64.0
|
|
||||||
|
|
||||||
private weak var browser: SKPhotoBrowser?
|
|
||||||
|
|
||||||
convenience init(browser: SKPhotoBrowser) {
|
|
||||||
self.init(frame: CGRect.zero)
|
|
||||||
|
|
||||||
self.browser = browser
|
|
||||||
|
|
||||||
translucent = false
|
|
||||||
tintColor = UIColor.whiteColor()
|
|
||||||
barTintColor = UIColor.blackColor()
|
|
||||||
titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
|
|
||||||
|
|
||||||
let navigationItem = UINavigationItem()
|
|
||||||
pushNavigationItem(navigationItem, animated: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateNavigationBar(currentPageIndex: Int) {
|
|
||||||
guard let browser = browser else { return }
|
|
||||||
|
|
||||||
if browser.numberOfPhotos > 1 {
|
|
||||||
self.topItem?.title = "\(currentPageIndex + 1) \(SKPhotoBrowserOptions.navigationBarCounterSepatator) \(browser.numberOfPhotos)"
|
|
||||||
} else {
|
|
||||||
self.topItem?.title = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setNewFrame(rect: CGRect) {
|
|
||||||
self.frame = rect
|
|
||||||
showFrame = rect
|
|
||||||
|
|
||||||
hideFrame = CGRect(x: rect.origin.x, y: rect.origin.y - 20, width: rect.size.width, height: rect.size.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateFrame(parentSize: CGSize) {
|
|
||||||
let newRect = CGRect(x: 0, y: 0, width: parentSize.width, height: SKNavigationBar.toolBarHeight)
|
|
||||||
setNewFrame(newRect)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,238 +0,0 @@
|
||||||
//
|
|
||||||
// SKPagingScrollView.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by 鈴木 啓司 on 2016/08/18.
|
|
||||||
// Copyright © 2016年 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
class SKPagingScrollView: UIScrollView {
|
|
||||||
let pageIndexTagOffset: Int = 1000
|
|
||||||
let sideMargin: CGFloat = 10
|
|
||||||
private var visiblePages = [SKZoomingScrollView]()
|
|
||||||
private var recycledPages = [SKZoomingScrollView]()
|
|
||||||
|
|
||||||
private weak var browser: SKPhotoBrowser?
|
|
||||||
var numberOfPhotos: Int {
|
|
||||||
return browser?.photos.count ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
|
|
||||||
pagingEnabled = true
|
|
||||||
showsHorizontalScrollIndicator = SKPhotoBrowserOptions.displayHorizontalScrollIndicator
|
|
||||||
showsVerticalScrollIndicator = SKPhotoBrowserOptions.displayHorizontalScrollIndicator
|
|
||||||
}
|
|
||||||
|
|
||||||
convenience init(frame: CGRect, browser: SKPhotoBrowser) {
|
|
||||||
self.init(frame: frame)
|
|
||||||
self.browser = browser
|
|
||||||
|
|
||||||
updateFrame(bounds, currentPageIndex: browser.currentPageIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
func reload() {
|
|
||||||
visiblePages.forEach({$0.removeFromSuperview()})
|
|
||||||
visiblePages.removeAll()
|
|
||||||
recycledPages.removeAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadAdjacentPhotosIfNecessary(photo: SKPhotoProtocol, currentPageIndex: Int) {
|
|
||||||
guard let browser = browser, page = pageDisplayingAtPhoto(photo) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let pageIndex = (page.tag - pageIndexTagOffset)
|
|
||||||
if currentPageIndex == pageIndex {
|
|
||||||
// Previous
|
|
||||||
if pageIndex > 0 {
|
|
||||||
let previousPhoto = browser.photos[pageIndex - 1]
|
|
||||||
if previousPhoto.underlyingImage == nil {
|
|
||||||
previousPhoto.loadUnderlyingImageAndNotify()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Next
|
|
||||||
if pageIndex < numberOfPhotos - 1 {
|
|
||||||
let nextPhoto = browser.photos[pageIndex + 1]
|
|
||||||
if nextPhoto.underlyingImage == nil {
|
|
||||||
nextPhoto.loadUnderlyingImageAndNotify()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteImage() {
|
|
||||||
// index equals 0 because when we slide between photos delete button is hidden and user cannot to touch on delete button. And visible pages number equals 0
|
|
||||||
if numberOfPhotos > 0 {
|
|
||||||
visiblePages[0].captionView?.removeFromSuperview()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func animate(frame: CGRect) {
|
|
||||||
setContentOffset(CGPoint(x: frame.origin.x - sideMargin, y: 0), animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateFrame(bounds: CGRect, currentPageIndex: Int) {
|
|
||||||
var frame = bounds
|
|
||||||
frame.origin.x -= sideMargin
|
|
||||||
frame.size.width += (2 * sideMargin)
|
|
||||||
|
|
||||||
self.frame = frame
|
|
||||||
|
|
||||||
if visiblePages.count > 0 {
|
|
||||||
for page in visiblePages {
|
|
||||||
let pageIndex = page.tag - pageIndexTagOffset
|
|
||||||
page.frame = frameForPageAtIndex(pageIndex)
|
|
||||||
page.setMaxMinZoomScalesForCurrentBounds()
|
|
||||||
if page.captionView != nil {
|
|
||||||
page.captionView.frame = frameForCaptionView(page.captionView, index: pageIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateContentSize()
|
|
||||||
updateContentOffset(currentPageIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateContentSize() {
|
|
||||||
contentSize = CGSize(width: bounds.size.width * CGFloat(numberOfPhotos), height: bounds.size.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateContentOffset(index: Int) {
|
|
||||||
let pageWidth = bounds.size.width
|
|
||||||
let newOffset = CGFloat(index) * pageWidth
|
|
||||||
contentOffset = CGPoint(x: newOffset, y: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func tilePages() {
|
|
||||||
guard let browser = browser else { return }
|
|
||||||
|
|
||||||
let firstIndex: Int = getFirstIndex()
|
|
||||||
let lastIndex: Int = getLastIndex()
|
|
||||||
|
|
||||||
visiblePages
|
|
||||||
.filter({ $0.tag - pageIndexTagOffset < firstIndex || $0.tag - pageIndexTagOffset < lastIndex })
|
|
||||||
.forEach { page in
|
|
||||||
recycledPages.append(page)
|
|
||||||
page.prepareForReuse()
|
|
||||||
page.removeFromSuperview()
|
|
||||||
}
|
|
||||||
|
|
||||||
let visibleSet: Set<SKZoomingScrollView> = Set(visiblePages)
|
|
||||||
let visibleSetWithoutRecycled: Set<SKZoomingScrollView> = visibleSet.subtract(recycledPages)
|
|
||||||
visiblePages = Array(visibleSetWithoutRecycled)
|
|
||||||
|
|
||||||
while recycledPages.count > 2 {
|
|
||||||
recycledPages.removeFirst()
|
|
||||||
}
|
|
||||||
|
|
||||||
for index: Int in firstIndex...lastIndex {
|
|
||||||
if visiblePages.filter({ $0.tag - pageIndexTagOffset == index }).count > 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
let page: SKZoomingScrollView = SKZoomingScrollView(frame: frame, browser: browser)
|
|
||||||
page.frame = frameForPageAtIndex(index)
|
|
||||||
page.tag = index + pageIndexTagOffset
|
|
||||||
page.photo = browser.photos[index]
|
|
||||||
|
|
||||||
visiblePages.append(page)
|
|
||||||
addSubview(page)
|
|
||||||
|
|
||||||
// if exists caption, insert
|
|
||||||
if let captionView: SKCaptionView = createCaptionView(index) {
|
|
||||||
captionView.frame = frameForCaptionView(captionView, index: index)
|
|
||||||
captionView.alpha = browser.areControlsHidden() ? 0 : 1
|
|
||||||
addSubview(captionView)
|
|
||||||
// ref val for control
|
|
||||||
page.captionView = captionView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func frameForCaptionView(captionView: SKCaptionView, index: Int) -> CGRect {
|
|
||||||
let pageFrame = frameForPageAtIndex(index)
|
|
||||||
let captionSize = captionView.sizeThatFits(CGSize(width: pageFrame.size.width, height: 0))
|
|
||||||
let navHeight = browser?.navigationController?.navigationBar.frame.size.height ?? 44
|
|
||||||
return CGRect(x: pageFrame.origin.x, y: pageFrame.size.height - captionSize.height - navHeight,
|
|
||||||
width: pageFrame.size.width, height: captionSize.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
func pageDisplayedAtIndex(index: Int) -> SKZoomingScrollView? {
|
|
||||||
for page in visiblePages {
|
|
||||||
if page.tag - pageIndexTagOffset == index {
|
|
||||||
return page
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func pageDisplayingAtPhoto(photo: SKPhotoProtocol) -> SKZoomingScrollView? {
|
|
||||||
for page in visiblePages {
|
|
||||||
if page.photo === photo {
|
|
||||||
return page
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCaptionViews() -> Set<SKCaptionView> {
|
|
||||||
var captionViews = Set<SKCaptionView>()
|
|
||||||
visiblePages
|
|
||||||
.filter({ $0.captionView != nil })
|
|
||||||
.forEach {
|
|
||||||
captionViews.insert($0.captionView)
|
|
||||||
}
|
|
||||||
return captionViews
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension SKPagingScrollView {
|
|
||||||
func frameForPageAtIndex(index: Int) -> CGRect {
|
|
||||||
var pageFrame = bounds
|
|
||||||
pageFrame.size.width -= (2 * 10)
|
|
||||||
pageFrame.origin.x = (bounds.size.width * CGFloat(index)) + sideMargin
|
|
||||||
return pageFrame
|
|
||||||
}
|
|
||||||
|
|
||||||
func createCaptionView(index: Int) -> SKCaptionView? {
|
|
||||||
guard let photo = browser?.photoAtIndex(index) where photo.caption != nil else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return SKCaptionView(photo: photo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFirstIndex() -> Int {
|
|
||||||
let firstIndex = Int(floor((bounds.minX + sideMargin * 2) / bounds.width))
|
|
||||||
if firstIndex < 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if firstIndex > numberOfPhotos - 1 {
|
|
||||||
return numberOfPhotos - 1
|
|
||||||
}
|
|
||||||
return firstIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
func getLastIndex() -> Int {
|
|
||||||
let lastIndex = Int(floor((bounds.maxX - sideMargin * 2 - 1) / bounds.width))
|
|
||||||
if lastIndex < 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if lastIndex > numberOfPhotos - 1 {
|
|
||||||
return numberOfPhotos - 1
|
|
||||||
}
|
|
||||||
return lastIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12,7 +12,6 @@ import UIKit
|
||||||
var underlyingImage: UIImage! { get }
|
var underlyingImage: UIImage! { get }
|
||||||
var caption: String! { get }
|
var caption: String! { get }
|
||||||
var index: Int { get set}
|
var index: Int { get set}
|
||||||
var contentMode: UIViewContentMode { get set }
|
|
||||||
func loadUnderlyingImageAndNotify()
|
func loadUnderlyingImageAndNotify()
|
||||||
func checkCache()
|
func checkCache()
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +21,6 @@ public class SKPhoto: NSObject, SKPhotoProtocol {
|
||||||
|
|
||||||
public var underlyingImage: UIImage!
|
public var underlyingImage: UIImage!
|
||||||
public var photoURL: String!
|
public var photoURL: String!
|
||||||
public var contentMode: UIViewContentMode = .ScaleAspectFill
|
|
||||||
public var shouldCachePhotoURLImage: Bool = false
|
public var shouldCachePhotoURLImage: Bool = false
|
||||||
public var caption: String!
|
public var caption: String!
|
||||||
public var index: Int = 0
|
public var index: Int = 0
|
||||||
|
|
@ -48,30 +46,24 @@ public class SKPhoto: NSObject, SKPhotoProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func checkCache() {
|
public func checkCache() {
|
||||||
guard let photoURL = photoURL else {
|
if photoURL != nil && shouldCachePhotoURLImage {
|
||||||
return
|
if SKCache.sharedCache.imageCache is SKRequestResponseCacheable {
|
||||||
}
|
let request = NSURLRequest(URL: NSURL(string: photoURL)!)
|
||||||
guard shouldCachePhotoURLImage else {
|
if let img = SKCache.sharedCache.imageForRequest(request) {
|
||||||
return
|
underlyingImage = img
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if SKCache.sharedCache.imageCache is SKRequestResponseCacheable {
|
if let img = SKCache.sharedCache.imageForKey(photoURL) {
|
||||||
let request = NSURLRequest(URL: NSURL(string: photoURL)!)
|
underlyingImage = img
|
||||||
if let img = SKCache.sharedCache.imageForRequest(request) {
|
}
|
||||||
underlyingImage = img
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let img = SKCache.sharedCache.imageForKey(photoURL) {
|
|
||||||
underlyingImage = img
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func loadUnderlyingImageAndNotify() {
|
public func loadUnderlyingImageAndNotify() {
|
||||||
|
|
||||||
if underlyingImage != nil {
|
if underlyingImage != nil && photoURL == nil {
|
||||||
loadUnderlyingImageComplete()
|
loadUnderlyingImageComplete()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if photoURL != nil {
|
if photoURL != nil {
|
||||||
|
|
@ -88,7 +80,7 @@ public class SKPhoto: NSObject, SKPhotoProtocol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let res = response, image = UIImage(data: res) {
|
if let res = response, let image = UIImage(data: res) {
|
||||||
if _self.shouldCachePhotoURLImage {
|
if _self.shouldCachePhotoURLImage {
|
||||||
if SKCache.sharedCache.imageCache is SKRequestResponseCacheable {
|
if SKCache.sharedCache.imageCache is SKRequestResponseCacheable {
|
||||||
SKCache.sharedCache.setImageData(response!, response: data!, request: task.originalRequest!)
|
SKCache.sharedCache.setImageData(response!, response: data!, request: task.originalRequest!)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,76 +0,0 @@
|
||||||
//
|
|
||||||
// SKPhotoBrowserDelegate.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by 鈴木 啓司 on 2016/08/09.
|
|
||||||
// Copyright © 2016年 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
@objc public protocol SKPhotoBrowserDelegate {
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tells the delegate that the browser started displaying a new photo
|
|
||||||
|
|
||||||
- Parameter index: the index of the new photo
|
|
||||||
*/
|
|
||||||
optional func didShowPhotoAtIndex(index: Int)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tells the delegate the browser will start to dismiss
|
|
||||||
|
|
||||||
- Parameter index: the index of the current photo
|
|
||||||
*/
|
|
||||||
optional func willDismissAtPageIndex(index: Int)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tells the delegate that the browser will start showing the `UIActionSheet`
|
|
||||||
|
|
||||||
- Parameter photoIndex: the index of the current photo
|
|
||||||
*/
|
|
||||||
optional func willShowActionSheet(photoIndex: Int)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tells the delegate that the browser has been dismissed
|
|
||||||
|
|
||||||
- Parameter index: the index of the current photo
|
|
||||||
*/
|
|
||||||
optional func didDismissAtPageIndex(index: Int)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tells the delegate that the browser did dismiss the UIActionSheet
|
|
||||||
|
|
||||||
- Parameter buttonIndex: the index of the pressed button
|
|
||||||
- Parameter photoIndex: the index of the current photo
|
|
||||||
*/
|
|
||||||
optional func didDismissActionSheetWithButtonIndex(buttonIndex: Int, photoIndex: Int)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tells the delegate that the browser did scroll to index
|
|
||||||
|
|
||||||
- Parameter index: the index of the photo where the user had scroll
|
|
||||||
*/
|
|
||||||
optional func didScrollToIndex(index: Int)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tells the delegate the user removed a photo, when implementing this call, be sure to call reload to finish the deletion process
|
|
||||||
|
|
||||||
- Parameter browser: reference to the calling SKPhotoBrowser
|
|
||||||
- Parameter index: the index of the removed photo
|
|
||||||
- Parameter reload: function that needs to be called after finishing syncing up
|
|
||||||
*/
|
|
||||||
optional func removePhoto(browser: SKPhotoBrowser, index: Int, reload: (() -> Void))
|
|
||||||
|
|
||||||
/**
|
|
||||||
Asks the delegate for the view for a certain photo. Needed to detemine the animation when presenting/closing the browser.
|
|
||||||
|
|
||||||
- Parameter browser: reference to the calling SKPhotoBrowser
|
|
||||||
- Parameter index: the index of the removed photo
|
|
||||||
|
|
||||||
- Returns: the view to animate to
|
|
||||||
*/
|
|
||||||
optional func viewForPhoto(browser: SKPhotoBrowser, index: Int) -> UIView?
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
//
|
|
||||||
// SKPhotoBrowserOptions.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by 鈴木 啓司 on 2016/08/18.
|
|
||||||
// Copyright © 2016年 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
public struct SKPhotoBrowserOptions {
|
|
||||||
public static var displayStatusbar: Bool = false
|
|
||||||
|
|
||||||
public static var displayAction: Bool = true
|
|
||||||
public static var shareExtraCaption: String? = nil
|
|
||||||
public static var actionButtonTitles: [String]?
|
|
||||||
|
|
||||||
public static var displayToolbar: Bool = true
|
|
||||||
public static var displayCounterLabel: Bool = true
|
|
||||||
public static var displayBackAndForwardButton: Bool = true
|
|
||||||
public static var disableVerticalSwipe: Bool = false
|
|
||||||
|
|
||||||
public static var displayCloseButton: Bool = true
|
|
||||||
public static var displayNavigationBar: Bool = true
|
|
||||||
public static var displayDeleteButton: Bool = false
|
|
||||||
|
|
||||||
public static var displayHorizontalScrollIndicator: Bool = true
|
|
||||||
public static var displayVerticalScrollIndicator: Bool = true
|
|
||||||
|
|
||||||
public static var bounceAnimation: Bool = false
|
|
||||||
public static var enableZoomBlackArea: Bool = true
|
|
||||||
public static var enableSingleTapDismiss: Bool = false
|
|
||||||
|
|
||||||
public static var backgroundColor = UIColor.blackColor()
|
|
||||||
public static var textAndIconColor = UIColor.whiteColor()
|
|
||||||
public static var toolbarTextShadowColor = UIColor.darkTextColor()
|
|
||||||
|
|
||||||
public static var navigationBarCounterSepatator: String = "из"
|
|
||||||
|
|
||||||
public static var toolbarFont = UIFont(name: "Helvetica", size: 16.0)
|
|
||||||
public static var captionFont = UIFont.systemFontOfSize(17.0)
|
|
||||||
|
|
||||||
// FIXED: Scrolling performance slowed #145
|
|
||||||
// public static var imagePaddingX: CGFloat = 0
|
|
||||||
// public static var imagePaddingY: CGFloat = 0
|
|
||||||
}
|
|
||||||
|
|
@ -1,165 +0,0 @@
|
||||||
//
|
|
||||||
// SKToolbar.swift
|
|
||||||
// SKPhotoBrowser
|
|
||||||
//
|
|
||||||
// Created by 鈴木 啓司 on 2016/08/12.
|
|
||||||
// Copyright © 2016年 suzuki_keishi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
// helpers which often used
|
|
||||||
private let bundle = NSBundle(forClass: SKPhotoBrowser.self)
|
|
||||||
|
|
||||||
class SKToolbar: UIToolbar {
|
|
||||||
var toolCounterLabel: UILabel!
|
|
||||||
var toolCounterButton: UIBarButtonItem!
|
|
||||||
var toolPreviousButton: UIBarButtonItem!
|
|
||||||
var toolNextButton: UIBarButtonItem!
|
|
||||||
var toolActionButton: UIBarButtonItem!
|
|
||||||
|
|
||||||
private weak var browser: SKPhotoBrowser?
|
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
convenience init(frame: CGRect, browser: SKPhotoBrowser) {
|
|
||||||
self.init(frame: frame)
|
|
||||||
self.browser = browser
|
|
||||||
|
|
||||||
setupApperance()
|
|
||||||
setupPreviousButton()
|
|
||||||
setupNextButton()
|
|
||||||
setupCounterLabel()
|
|
||||||
setupActionButton()
|
|
||||||
setupToolbar()
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateToolbar(currentPageIndex: Int) {
|
|
||||||
guard let browser = browser else { return }
|
|
||||||
|
|
||||||
if browser.numberOfPhotos > 1 {
|
|
||||||
toolCounterLabel.text = "\(currentPageIndex + 1) / \(browser.numberOfPhotos)"
|
|
||||||
} else {
|
|
||||||
toolCounterLabel.text = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
toolPreviousButton.enabled = (currentPageIndex > 0)
|
|
||||||
toolNextButton.enabled = (currentPageIndex < browser.numberOfPhotos - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension SKToolbar {
|
|
||||||
func setupApperance() {
|
|
||||||
backgroundColor = .clearColor()
|
|
||||||
clipsToBounds = true
|
|
||||||
translucent = true
|
|
||||||
setBackgroundImage(UIImage(), forToolbarPosition: .Any, barMetrics: .Default)
|
|
||||||
|
|
||||||
// toolbar
|
|
||||||
if !SKPhotoBrowserOptions.displayToolbar {
|
|
||||||
hidden = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupToolbar() {
|
|
||||||
guard let browser = browser else { return }
|
|
||||||
|
|
||||||
let flexSpace = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: self, action: nil)
|
|
||||||
var items = [UIBarButtonItem]()
|
|
||||||
items.append(flexSpace)
|
|
||||||
if browser.numberOfPhotos > 1 && SKPhotoBrowserOptions.displayBackAndForwardButton {
|
|
||||||
items.append(toolPreviousButton)
|
|
||||||
}
|
|
||||||
if SKPhotoBrowserOptions.displayCounterLabel {
|
|
||||||
items.append(flexSpace)
|
|
||||||
items.append(toolCounterButton)
|
|
||||||
items.append(flexSpace)
|
|
||||||
} else {
|
|
||||||
items.append(flexSpace)
|
|
||||||
}
|
|
||||||
if browser.numberOfPhotos > 1 && SKPhotoBrowserOptions.displayBackAndForwardButton {
|
|
||||||
items.append(toolNextButton)
|
|
||||||
}
|
|
||||||
items.append(flexSpace)
|
|
||||||
if SKPhotoBrowserOptions.displayAction {
|
|
||||||
items.append(toolActionButton)
|
|
||||||
}
|
|
||||||
setItems(items, animated: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupPreviousButton() {
|
|
||||||
let previousBtn = SKPreviousButton(frame: frame)
|
|
||||||
previousBtn.addTarget(browser, action: #selector(SKPhotoBrowser.gotoPreviousPage), forControlEvents: .TouchUpInside)
|
|
||||||
toolPreviousButton = UIBarButtonItem(customView: previousBtn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupNextButton() {
|
|
||||||
let nextBtn = SKNextButton(frame: frame)
|
|
||||||
nextBtn.addTarget(browser, action: #selector(SKPhotoBrowser.gotoNextPage), forControlEvents: .TouchUpInside)
|
|
||||||
toolNextButton = UIBarButtonItem(customView: nextBtn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupCounterLabel() {
|
|
||||||
toolCounterLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 95, height: 40))
|
|
||||||
toolCounterLabel.textAlignment = .Center
|
|
||||||
toolCounterLabel.backgroundColor = .clearColor()
|
|
||||||
toolCounterLabel.font = SKPhotoBrowserOptions.toolbarFont
|
|
||||||
toolCounterLabel.textColor = SKPhotoBrowserOptions.textAndIconColor
|
|
||||||
toolCounterLabel.shadowColor = SKPhotoBrowserOptions.toolbarTextShadowColor
|
|
||||||
toolCounterLabel.shadowOffset = CGSize(width: 0.0, height: 1.0)
|
|
||||||
toolCounterButton = UIBarButtonItem(customView: toolCounterLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupActionButton() {
|
|
||||||
toolActionButton = UIBarButtonItem(barButtonSystemItem: .Action, target: browser, action: #selector(SKPhotoBrowser.actionButtonPressed))
|
|
||||||
toolActionButton.tintColor = SKPhotoBrowserOptions.textAndIconColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class SKToolbarButton: UIButton {
|
|
||||||
let insets: UIEdgeInsets = UIEdgeInsets(top: 13.25, left: 17.25, bottom: 13.25, right: 17.25)
|
|
||||||
|
|
||||||
func setup(imageName: String) {
|
|
||||||
backgroundColor = .clearColor()
|
|
||||||
tintColor = SKPhotoBrowserOptions.textAndIconColor
|
|
||||||
imageEdgeInsets = insets
|
|
||||||
translatesAutoresizingMaskIntoConstraints = true
|
|
||||||
autoresizingMask = [.FlexibleBottomMargin, .FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin]
|
|
||||||
contentMode = .Center
|
|
||||||
|
|
||||||
let image = UIImage(named: "SKPhotoBrowser.bundle/images/\(imageName)",
|
|
||||||
inBundle: bundle, compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate) ?? UIImage()
|
|
||||||
setImage(image, forState: .Normal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SKPreviousButton: SKToolbarButton {
|
|
||||||
let imageName = "btn_common_back_wh"
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
|
|
||||||
setup(imageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SKNextButton: SKToolbarButton {
|
|
||||||
let imageName = "btn_common_forward_wh"
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
|
|
||||||
setup(imageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,7 +8,8 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public class SKZoomingScrollView: UIScrollView {
|
public class SKZoomingScrollView: UIScrollView, UIScrollViewDelegate, SKDetectingViewDelegate, SKDetectingImageViewDelegate {
|
||||||
|
|
||||||
var captionView: SKCaptionView!
|
var captionView: SKCaptionView!
|
||||||
var photo: SKPhotoProtocol! {
|
var photo: SKPhotoProtocol! {
|
||||||
didSet {
|
didSet {
|
||||||
|
|
@ -48,14 +49,14 @@ public class SKZoomingScrollView: UIScrollView {
|
||||||
// tap
|
// tap
|
||||||
tapView = SKDetectingView(frame: bounds)
|
tapView = SKDetectingView(frame: bounds)
|
||||||
tapView.delegate = self
|
tapView.delegate = self
|
||||||
tapView.backgroundColor = .clearColor()
|
tapView.backgroundColor = UIColor.clearColor()
|
||||||
tapView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
|
tapView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
|
||||||
addSubview(tapView)
|
addSubview(tapView)
|
||||||
|
|
||||||
// image
|
// image
|
||||||
photoImageView = SKDetectingImageView(frame: frame)
|
photoImageView = SKDetectingImageView(frame: frame)
|
||||||
photoImageView.delegate = self
|
photoImageView.delegate = self
|
||||||
photoImageView.contentMode = .Bottom
|
photoImageView.contentMode = .ScaleAspectFill
|
||||||
photoImageView.backgroundColor = .clearColor()
|
photoImageView.backgroundColor = .clearColor()
|
||||||
addSubview(photoImageView)
|
addSubview(photoImageView)
|
||||||
|
|
||||||
|
|
@ -103,6 +104,7 @@ public class SKZoomingScrollView: UIScrollView {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setMaxMinZoomScalesForCurrentBounds() {
|
public func setMaxMinZoomScalesForCurrentBounds() {
|
||||||
|
|
||||||
maximumZoomScale = 1
|
maximumZoomScale = 1
|
||||||
minimumZoomScale = 1
|
minimumZoomScale = 1
|
||||||
zoomScale = 1
|
zoomScale = 1
|
||||||
|
|
@ -117,12 +119,28 @@ public class SKZoomingScrollView: UIScrollView {
|
||||||
let xScale = boundsSize.width / imageSize.width
|
let xScale = boundsSize.width / imageSize.width
|
||||||
let yScale = boundsSize.height / imageSize.height
|
let yScale = boundsSize.height / imageSize.height
|
||||||
let minScale: CGFloat = min(xScale, yScale)
|
let minScale: CGFloat = min(xScale, yScale)
|
||||||
var maxScale: CGFloat = 1.0
|
var maxScale: CGFloat!
|
||||||
|
|
||||||
let scale = max(UIScreen.mainScreen().scale, 2.0)
|
|
||||||
|
let scale = UIScreen.mainScreen().scale
|
||||||
let deviceScreenWidth = UIScreen.mainScreen().bounds.width * scale // width in pixels. scale needs to remove if to use the old algorithm
|
let deviceScreenWidth = UIScreen.mainScreen().bounds.width * scale // width in pixels. scale needs to remove if to use the old algorithm
|
||||||
let deviceScreenHeight = UIScreen.mainScreen().bounds.height * scale // height in pixels. scale needs to remove if to use the old algorithm
|
let deviceScreenHeight = UIScreen.mainScreen().bounds.height * scale // height in pixels. scale needs to remove if to use the old algorithm
|
||||||
|
|
||||||
|
// it is the old algorithm
|
||||||
|
/* if photoImageView.frame.width < deviceScreenWidth {
|
||||||
|
// I think that we should to get coefficient between device screen width and image width and assign it to maxScale. I made two mode that we will get the same result for different device orientations.
|
||||||
|
if UIApplication.sharedApplication().statusBarOrientation.isPortrait {
|
||||||
|
maxScale = deviceScreenHeight / photoImageView.frame.width
|
||||||
|
} else {
|
||||||
|
maxScale = deviceScreenWidth / photoImageView.frame.width
|
||||||
|
}
|
||||||
|
} else if photoImageView.frame.width > deviceScreenWidth {
|
||||||
|
maxScale = 1.0
|
||||||
|
} else {
|
||||||
|
// here if photoImageView.frame.width == deviceScreenWidth
|
||||||
|
maxScale = 2.5
|
||||||
|
} */
|
||||||
|
|
||||||
if photoImageView.frame.width < deviceScreenWidth {
|
if photoImageView.frame.width < deviceScreenWidth {
|
||||||
// I think that we should to get coefficient between device screen width and image width and assign it to maxScale. I made two mode that we will get the same result for different device orientations.
|
// I think that we should to get coefficient between device screen width and image width and assign it to maxScale. I made two mode that we will get the same result for different device orientations.
|
||||||
if UIApplication.sharedApplication().statusBarOrientation.isPortrait {
|
if UIApplication.sharedApplication().statusBarOrientation.isPortrait {
|
||||||
|
|
@ -136,7 +154,7 @@ public class SKZoomingScrollView: UIScrollView {
|
||||||
// here if photoImageView.frame.width == deviceScreenWidth
|
// here if photoImageView.frame.width == deviceScreenWidth
|
||||||
maxScale = 2.5
|
maxScale = 2.5
|
||||||
}
|
}
|
||||||
|
|
||||||
maximumZoomScale = maxScale
|
maximumZoomScale = maxScale
|
||||||
minimumZoomScale = minScale
|
minimumZoomScale = minScale
|
||||||
zoomScale = minScale
|
zoomScale = minScale
|
||||||
|
|
@ -182,25 +200,9 @@ public class SKZoomingScrollView: UIScrollView {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let image = photo.underlyingImage {
|
if let image = photo.underlyingImage {
|
||||||
|
|
||||||
// FIXED: Scrolling performance slowed #145
|
|
||||||
|
|
||||||
// create padding
|
|
||||||
// let width: CGFloat = image.size.width + SKPhotoBrowserOptions.imagePaddingX
|
|
||||||
// let height: CGFloat = image.size.height + SKPhotoBrowserOptions.imagePaddingY;
|
|
||||||
// UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), false, 0.0);
|
|
||||||
// let context: CGContextRef = UIGraphicsGetCurrentContext()!;
|
|
||||||
// UIGraphicsPushContext(context);
|
|
||||||
// let origin: CGPoint = CGPointMake((width - image.size.width) / 2, (height - image.size.height) / 2);
|
|
||||||
// image.drawAtPoint(origin)
|
|
||||||
// UIGraphicsPopContext();
|
|
||||||
// let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext();
|
|
||||||
// UIGraphicsEndImageContext();
|
|
||||||
|
|
||||||
// image
|
// image
|
||||||
photoImageView.image = image
|
photoImageView.image = image
|
||||||
photoImageView.contentMode = photo.contentMode
|
|
||||||
photoImageView.backgroundColor = SKPhotoBrowserOptions.backgroundColor
|
|
||||||
|
|
||||||
var photoImageViewFrame = CGRect.zero
|
var photoImageViewFrame = CGRect.zero
|
||||||
photoImageViewFrame.origin = CGPoint.zero
|
photoImageViewFrame.origin = CGPoint.zero
|
||||||
|
|
@ -236,18 +238,23 @@ public class SKZoomingScrollView: UIScrollView {
|
||||||
newZoom = maximumZoomScale
|
newZoom = maximumZoomScale
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
let zoomRect = zoomRectForScrollViewWith(maximumZoomScale, touchPoint: touchPoint)
|
zoomToRect(zoomRectForScrollViewWith(maximumZoomScale, touchPoint: touchPoint), animated: true)
|
||||||
zoomToRect(zoomRect, animated: true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delay control
|
// delay control
|
||||||
photoBrowser?.hideControlsAfterDelay()
|
photoBrowser?.hideControlsAfterDelay()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public func zoomRectForScrollViewWith(scale: CGFloat, touchPoint: CGPoint) -> CGRect {
|
||||||
// MARK: - UIScrollViewDelegate
|
let w = frame.size.width / scale
|
||||||
|
let h = frame.size.height / scale
|
||||||
extension SKZoomingScrollView: UIScrollViewDelegate {
|
let x = touchPoint.x - (w / 2.0)
|
||||||
|
let y = touchPoint.y - (h / 2.0)
|
||||||
|
|
||||||
|
return CGRect(x: x, y: y, width: w, height: h)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UIScrollViewDelegate
|
||||||
public func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
|
public func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
|
||||||
return photoImageView
|
return photoImageView
|
||||||
}
|
}
|
||||||
|
|
@ -260,56 +267,26 @@ extension SKZoomingScrollView: UIScrollViewDelegate {
|
||||||
setNeedsLayout()
|
setNeedsLayout()
|
||||||
layoutIfNeeded()
|
layoutIfNeeded()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - SKDetectingImageViewDelegate
|
// MARK: - SKDetectingViewDelegate
|
||||||
|
|
||||||
extension SKZoomingScrollView: SKDetectingViewDelegate {
|
|
||||||
func handleSingleTap(view: UIView, touch: UITouch) {
|
func handleSingleTap(view: UIView, touch: UITouch) {
|
||||||
guard let browser = photoBrowser else {
|
if photoBrowser?.enableZoomBlackArea == true {
|
||||||
return
|
if photoBrowser?.areControlsHidden() == false && photoBrowser?.enableSingleTapDismiss == true {
|
||||||
}
|
photoBrowser?.determineAndClose()
|
||||||
guard SKPhotoBrowserOptions.enableZoomBlackArea == true else {
|
}
|
||||||
return
|
photoBrowser?.toggleControls()
|
||||||
}
|
|
||||||
|
|
||||||
if browser.areControlsHidden() == false && SKPhotoBrowserOptions.enableSingleTapDismiss == true {
|
|
||||||
browser.determineAndClose()
|
|
||||||
} else {
|
|
||||||
browser.toggleControls()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleDoubleTap(view: UIView, touch: UITouch) {
|
func handleDoubleTap(view: UIView, touch: UITouch) {
|
||||||
if SKPhotoBrowserOptions.enableZoomBlackArea == true {
|
if photoBrowser?.enableZoomBlackArea == true {
|
||||||
let needPoint = getViewFramePercent(view, touch: touch)
|
let needPoint = getViewFramePercent(view, touch: touch)
|
||||||
handleDoubleTap(needPoint)
|
handleDoubleTap(needPoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - SKDetectingImageViewDelegate
|
|
||||||
|
|
||||||
extension SKZoomingScrollView: SKDetectingImageViewDelegate {
|
|
||||||
func handleImageViewSingleTap(touchPoint: CGPoint) {
|
|
||||||
guard let browser = photoBrowser else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if SKPhotoBrowserOptions.enableSingleTapDismiss {
|
|
||||||
browser.determineAndClose()
|
|
||||||
} else {
|
|
||||||
browser.toggleControls()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleImageViewDoubleTap(touchPoint: CGPoint) {
|
private func getViewFramePercent(view: UIView, touch: UITouch) -> CGPoint {
|
||||||
handleDoubleTap(touchPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension SKZoomingScrollView {
|
|
||||||
func getViewFramePercent(view: UIView, touch: UITouch) -> CGPoint {
|
|
||||||
let oneWidthViewPercent = view.bounds.width / 100
|
let oneWidthViewPercent = view.bounds.width / 100
|
||||||
let viewTouchPoint = touch.locationInView(view)
|
let viewTouchPoint = touch.locationInView(view)
|
||||||
let viewWidthTouch = viewTouchPoint.x
|
let viewWidthTouch = viewTouchPoint.x
|
||||||
|
|
@ -330,12 +307,16 @@ private extension SKZoomingScrollView {
|
||||||
return allPoint
|
return allPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
func zoomRectForScrollViewWith(scale: CGFloat, touchPoint: CGPoint) -> CGRect {
|
// MARK: - SKDetectingImageViewDelegate
|
||||||
let w = frame.size.width / scale
|
func handleImageViewSingleTap(touchPoint: CGPoint) {
|
||||||
let h = frame.size.height / scale
|
if photoBrowser!.enableSingleTapDismiss {
|
||||||
let x = touchPoint.x - (h / max(UIScreen.mainScreen().scale, 2.0))
|
photoBrowser?.determineAndClose()
|
||||||
let y = touchPoint.y - (w / max(UIScreen.mainScreen().scale, 2.0))
|
} else {
|
||||||
|
photoBrowser?.toggleControls()
|
||||||
return CGRect(x: x, y: y, width: w, height: h)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
func handleImageViewDoubleTap(touchPoint: CGPoint) {
|
||||||
|
handleDoubleTap(touchPoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,69 +14,63 @@ extension UIImage {
|
||||||
guard self.imageOrientation != .Up else {
|
guard self.imageOrientation != .Up else {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
let transform = calculateAffineTransform()
|
// We need to calculate the proper transformation to make the image upright.
|
||||||
|
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
|
||||||
|
var transform = CGAffineTransformIdentity
|
||||||
|
|
||||||
|
switch self.imageOrientation {
|
||||||
|
case .Down, .DownMirrored:
|
||||||
|
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
|
||||||
|
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
|
||||||
|
|
||||||
|
case .Left, .LeftMirrored:
|
||||||
|
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
|
||||||
|
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
|
||||||
|
|
||||||
|
case .Right, .RightMirrored:
|
||||||
|
transform = CGAffineTransformTranslate(transform, 0, self.size.height)
|
||||||
|
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
switch self.imageOrientation {
|
||||||
|
case .UpMirrored, .DownMirrored:
|
||||||
|
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
|
||||||
|
transform = CGAffineTransformScale(transform, -1, 1)
|
||||||
|
|
||||||
|
case .LeftMirrored, .RightMirrored:
|
||||||
|
transform = CGAffineTransformTranslate(transform, self.size.height, 0)
|
||||||
|
transform = CGAffineTransformScale(transform, -1, 1)
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// Now we draw the underlying CGImage into a new context, applying the transform
|
// Now we draw the underlying CGImage into a new context, applying the transform
|
||||||
// calculated above.
|
// calculated above.
|
||||||
let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
|
let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
|
||||||
CGImageGetBitsPerComponent(self.CGImage!), 0,
|
CGImageGetBitsPerComponent(self.CGImage), 0,
|
||||||
CGImageGetColorSpace(self.CGImage!)!,
|
CGImageGetColorSpace(self.CGImage),
|
||||||
CGImageGetBitmapInfo(self.CGImage!).rawValue)
|
CGImageGetBitmapInfo(self.CGImage).rawValue)
|
||||||
CGContextConcatCTM(ctx!, transform)
|
CGContextConcatCTM(ctx, transform)
|
||||||
|
|
||||||
switch self.imageOrientation {
|
switch self.imageOrientation {
|
||||||
case .Left, .LeftMirrored, .Right, .RightMirrored:
|
case .Left, .LeftMirrored, .Right, .RightMirrored:
|
||||||
CGContextDrawImage(ctx!, CGRect(x: 0, y: 0, width: size.height, height: size.width), self.CGImage!)
|
CGContextDrawImage(ctx, CGRect(x: 0, y: 0, width: size.height, height: size.width), self.CGImage)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CGContextDrawImage(ctx!, CGRect(x: 0, y: 0, width: size.width, height: size.height), self.CGImage!)
|
CGContextDrawImage(ctx, CGRect(x: 0, y: 0, width: size.width, height: size.height), self.CGImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// And now we just create a new UIImage from the drawing context
|
// And now we just create a new UIImage from the drawing context
|
||||||
if let cgImage = CGBitmapContextCreateImage(ctx!) {
|
if let cgImage = CGBitmapContextCreateImage(ctx) {
|
||||||
return UIImage(CGImage: cgImage)
|
return UIImage(CGImage: cgImage)
|
||||||
} else {
|
} else {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func calculateAffineTransform() -> CGAffineTransform {
|
|
||||||
// We need to calculate the proper transformation to make the image upright.
|
|
||||||
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
|
|
||||||
var transform = CGAffineTransformIdentity
|
|
||||||
|
|
||||||
switch self.imageOrientation {
|
|
||||||
case .Down, .DownMirrored:
|
|
||||||
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
|
|
||||||
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
|
|
||||||
|
|
||||||
case .Left, .LeftMirrored:
|
|
||||||
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
|
|
||||||
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
|
|
||||||
|
|
||||||
case .Right, .RightMirrored:
|
|
||||||
transform = CGAffineTransformTranslate(transform, 0, self.size.height)
|
|
||||||
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
switch self.imageOrientation {
|
|
||||||
case .UpMirrored, .DownMirrored:
|
|
||||||
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
|
|
||||||
transform = CGAffineTransformScale(transform, -1, 1)
|
|
||||||
|
|
||||||
case .LeftMirrored, .RightMirrored:
|
|
||||||
transform = CGAffineTransformTranslate(transform, self.size.height, 0)
|
|
||||||
transform = CGAffineTransformScale(transform, -1, 1)
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return transform
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
platform :ios, '8.0'
|
|
||||||
use_frameworks!
|
|
||||||
|
|
||||||
pod 'SDWebImage', '~>3.8'
|
|
||||||
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
PODS:
|
|
||||||
- SDWebImage (3.8.1):
|
|
||||||
- SDWebImage/Core (= 3.8.1)
|
|
||||||
- SDWebImage/Core (3.8.1)
|
|
||||||
|
|
||||||
DEPENDENCIES:
|
|
||||||
- SDWebImage (~> 3.8)
|
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
|
||||||
SDWebImage: 35f9627a3e44b4f292a8a8ce6a531fa488239b91
|
|
||||||
|
|
||||||
COCOAPODS: 0.39.0
|
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
89FC5DBB1D54A04900F1BE52 /* FromWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FC5DBA1D54A04900F1BE52 /* FromWebViewController.swift */; };
|
89FC5DBB1D54A04900F1BE52 /* FromWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FC5DBA1D54A04900F1BE52 /* FromWebViewController.swift */; };
|
||||||
A6A7B7801C9578E30025AC07 /* SKPhotoBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5711BC792570060A053 /* SKPhotoBrowser.framework */; };
|
A6A7B7801C9578E30025AC07 /* SKPhotoBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5711BC792570060A053 /* SKPhotoBrowser.framework */; };
|
||||||
A6A7B7811C9578E30025AC07 /* SKPhotoBrowser.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5711BC792570060A053 /* SKPhotoBrowser.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
A6A7B7811C9578E30025AC07 /* SKPhotoBrowser.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5711BC792570060A053 /* SKPhotoBrowser.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
DDFD24AF2FBA5A60984D378D /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C2188E912BB106233AA4AB2 /* Pods.framework */; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
|
@ -71,7 +70,6 @@
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
212705881C92C69C00466223 /* FromCameraRollViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FromCameraRollViewController.swift; sourceTree = "<group>"; };
|
212705881C92C69C00466223 /* FromCameraRollViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FromCameraRollViewController.swift; sourceTree = "<group>"; };
|
||||||
7C2188E912BB106233AA4AB2 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
8909B5571BC792150060A053 /* SKPhotoBrowserExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SKPhotoBrowserExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
8909B5571BC792150060A053 /* SKPhotoBrowserExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SKPhotoBrowserExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
8909B55A1BC792150060A053 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
8909B55A1BC792150060A053 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
8909B55C1BC792150060A053 /* FromLocalViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FromLocalViewController.swift; sourceTree = "<group>"; };
|
8909B55C1BC792150060A053 /* FromLocalViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FromLocalViewController.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -93,8 +91,6 @@
|
||||||
8909B57F1BC792DC0060A053 /* image8.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = image8.jpg; sourceTree = "<group>"; };
|
8909B57F1BC792DC0060A053 /* image8.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = image8.jpg; sourceTree = "<group>"; };
|
||||||
8909B5801BC792DC0060A053 /* image9.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = image9.jpg; sourceTree = "<group>"; };
|
8909B5801BC792DC0060A053 /* image9.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = image9.jpg; sourceTree = "<group>"; };
|
||||||
89FC5DBA1D54A04900F1BE52 /* FromWebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FromWebViewController.swift; sourceTree = "<group>"; };
|
89FC5DBA1D54A04900F1BE52 /* FromWebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FromWebViewController.swift; sourceTree = "<group>"; };
|
||||||
B3E081D4F2C8623852C459F5 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
DD077DBD0C164C96BCC7494F /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
|
@ -103,7 +99,6 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A6A7B7801C9578E30025AC07 /* SKPhotoBrowser.framework in Frameworks */,
|
A6A7B7801C9578E30025AC07 /* SKPhotoBrowser.framework in Frameworks */,
|
||||||
DDFD24AF2FBA5A60984D378D /* Pods.framework in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
@ -116,8 +111,6 @@
|
||||||
8909B56C1BC792570060A053 /* SKPhotoBrowser.xcodeproj */,
|
8909B56C1BC792570060A053 /* SKPhotoBrowser.xcodeproj */,
|
||||||
8909B5591BC792150060A053 /* SKPhotoBrowserExample */,
|
8909B5591BC792150060A053 /* SKPhotoBrowserExample */,
|
||||||
8909B5581BC792150060A053 /* Products */,
|
8909B5581BC792150060A053 /* Products */,
|
||||||
D1D8ECD45B290372235B8168 /* Pods */,
|
|
||||||
C646D2C27A5B9CCC003A9BD1 /* Frameworks */,
|
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
|
@ -205,23 +198,6 @@
|
||||||
name = Info;
|
name = Info;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C646D2C27A5B9CCC003A9BD1 /* Frameworks */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
7C2188E912BB106233AA4AB2 /* Pods.framework */,
|
|
||||||
);
|
|
||||||
name = Frameworks;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
D1D8ECD45B290372235B8168 /* Pods */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B3E081D4F2C8623852C459F5 /* Pods.debug.xcconfig */,
|
|
||||||
DD077DBD0C164C96BCC7494F /* Pods.release.xcconfig */,
|
|
||||||
);
|
|
||||||
name = Pods;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
|
@ -229,13 +205,10 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 8909B5691BC792150060A053 /* Build configuration list for PBXNativeTarget "SKPhotoBrowserExample" */;
|
buildConfigurationList = 8909B5691BC792150060A053 /* Build configuration list for PBXNativeTarget "SKPhotoBrowserExample" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
F19A62C34B2F0CFF753F30C3 /* Check Pods Manifest.lock */,
|
|
||||||
8909B5531BC792150060A053 /* Sources */,
|
8909B5531BC792150060A053 /* Sources */,
|
||||||
8909B5541BC792150060A053 /* Frameworks */,
|
8909B5541BC792150060A053 /* Frameworks */,
|
||||||
8909B5551BC792150060A053 /* Resources */,
|
8909B5551BC792150060A053 /* Resources */,
|
||||||
A6A7B7841C9578E30025AC07 /* Embed Frameworks */,
|
A6A7B7841C9578E30025AC07 /* Embed Frameworks */,
|
||||||
575DBD5855AB711E5773767A /* Embed Pods Frameworks */,
|
|
||||||
2ECF43C4E99CDE3D98AE6842 /* Copy Pods Resources */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
|
@ -258,7 +231,6 @@
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8909B5561BC792150060A053 = {
|
8909B5561BC792150060A053 = {
|
||||||
CreatedOnToolsVersion = 7.0;
|
CreatedOnToolsVersion = 7.0;
|
||||||
LastSwiftMigration = 0800;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -328,54 +300,6 @@
|
||||||
};
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
2ECF43C4E99CDE3D98AE6842 /* Copy Pods Resources */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "Copy Pods Resources";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
575DBD5855AB711E5773767A /* Embed Pods Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "Embed Pods Frameworks";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
F19A62C34B2F0CFF753F30C3 /* Check Pods Manifest.lock */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "Check Pods Manifest.lock";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
8909B5531BC792150060A053 /* Sources */ = {
|
8909B5531BC792150060A053 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
|
|
@ -503,7 +427,6 @@
|
||||||
};
|
};
|
||||||
8909B56A1BC792150060A053 /* Debug */ = {
|
8909B56A1BC792150060A053 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = B3E081D4F2C8623852C459F5 /* Pods.debug.xcconfig */;
|
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
|
@ -512,13 +435,11 @@
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.aSKPhotoBrowserExample;
|
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.aSKPhotoBrowserExample;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 2.3;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
8909B56B1BC792150060A053 /* Release */ = {
|
8909B56B1BC792150060A053 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = DD077DBD0C164C96BCC7494F /* Pods.release.xcconfig */;
|
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
|
@ -527,7 +448,6 @@
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.aSKPhotoBrowserExample;
|
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.aSKPhotoBrowserExample;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 2.3;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "group:SKPhotoBrowserExample.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
<FileRef
|
|
||||||
location = "group:Pods/Pods.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="qgG-zu-Htx">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="qgG-zu-Htx">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
@ -88,26 +88,14 @@
|
||||||
<action selector="pushButton:" destination="wTD-ba-cWw" eventType="touchUpInside" id="xIc-2O-Gmb"/>
|
<action selector="pushButton:" destination="wTD-ba-cWw" eventType="touchUpInside" id="xIc-2O-Gmb"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yxe-Wd-8iE">
|
|
||||||
<rect key="frame" x="180" y="78" width="240" height="128"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" constant="128" id="a4K-nx-MJW"/>
|
|
||||||
<constraint firstAttribute="width" constant="240" id="tzG-IV-N9z"/>
|
|
||||||
</constraints>
|
|
||||||
</imageView>
|
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="ZK0-HE-9Bs" firstAttribute="top" secondItem="yxe-Wd-8iE" secondAttribute="bottom" constant="50" id="8Aq-op-KMh"/>
|
|
||||||
<constraint firstItem="ZK0-HE-9Bs" firstAttribute="centerY" secondItem="pNX-nL-SLw" secondAttribute="centerY" id="9jd-Un-cAK"/>
|
<constraint firstItem="ZK0-HE-9Bs" firstAttribute="centerY" secondItem="pNX-nL-SLw" secondAttribute="centerY" id="9jd-Un-cAK"/>
|
||||||
<constraint firstItem="ZK0-HE-9Bs" firstAttribute="centerX" secondItem="pNX-nL-SLw" secondAttribute="centerX" id="h6U-H1-RV4"/>
|
<constraint firstItem="ZK0-HE-9Bs" firstAttribute="centerX" secondItem="pNX-nL-SLw" secondAttribute="centerX" id="h6U-H1-RV4"/>
|
||||||
<constraint firstItem="yxe-Wd-8iE" firstAttribute="centerX" secondItem="pNX-nL-SLw" secondAttribute="centerX" id="xA1-uS-dJw"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<tabBarItem key="tabBarItem" title="FromWeb" id="2lE-np-9H3"/>
|
<tabBarItem key="tabBarItem" title="FromWeb" id="2lE-np-9H3"/>
|
||||||
<connections>
|
|
||||||
<outlet property="imageView" destination="yxe-Wd-8iE" id="aMH-Df-3r0"/>
|
|
||||||
</connections>
|
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="jdP-ty-Ygs" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="jdP-ty-Ygs" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,10 @@ class FromCameraRollViewController: UIViewController, SKPhotoBrowserDelegate, UI
|
||||||
|
|
||||||
browser.initializePageIndex(indexPath.row)
|
browser.initializePageIndex(indexPath.row)
|
||||||
browser.delegate = self
|
browser.delegate = self
|
||||||
// browser.bounceAnimation = true
|
browser.bounceAnimation = true
|
||||||
// browser.displayDeleteButton = true
|
browser.displayDeleteButton = true
|
||||||
// browser.displayAction = false
|
browser.displayAction = false
|
||||||
|
browser.statusBarStyle = .LightContent
|
||||||
self.presentViewController(browser, animated: true, completion: {})
|
self.presentViewController(browser, animated: true, completion: {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,7 +168,8 @@ class FromCameraRollViewController: UIViewController, SKPhotoBrowserDelegate, UI
|
||||||
let requestId = dict?[PHImageResultRequestIDKey] as? NSNumber
|
let requestId = dict?[PHImageResultRequestIDKey] as? NSNumber
|
||||||
completion(image: image, requestId: requestId?.intValue)
|
completion(image: image, requestId: requestId?.intValue)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return imageManager.requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: options) { image, dict in
|
return imageManager.requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: options) { image, dict in
|
||||||
let requestId = dict?[PHImageResultRequestIDKey] as? NSNumber
|
let requestId = dict?[PHImageResultRequestIDKey] as? NSNumber
|
||||||
completion(image: image, requestId: requestId?.intValue)
|
completion(image: image, requestId: requestId?.intValue)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ extension FromLocalViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
cell.exampleImageView.image = UIImage(named: "image\(indexPath.row % 10).jpg")
|
cell.exampleImageView.image = UIImage(named: "image\(indexPath.row % 10).jpg")
|
||||||
// cell.exampleImageView.contentMode = .ScaleAspectFill
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -62,13 +61,11 @@ extension FromLocalViewController {
|
||||||
guard let originImage = cell.exampleImageView.image else {
|
guard let originImage = cell.exampleImageView.image else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SKPhotoBrowserOptions.displayToolbar = false
|
|
||||||
|
|
||||||
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
|
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
|
||||||
|
// let browser = SKPhotoBrowser(photos: images)
|
||||||
browser.initializePageIndex(indexPath.row)
|
browser.initializePageIndex(indexPath.row)
|
||||||
browser.delegate = self
|
browser.delegate = self
|
||||||
// browser.updateCloseButton(UIImage(named: "image1.jpg")!)
|
browser.statusBarStyle = .LightContent
|
||||||
|
|
||||||
presentViewController(browser, animated: true, completion: {})
|
presentViewController(browser, animated: true, completion: {})
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +130,6 @@ private extension FromLocalViewController {
|
||||||
return (0..<10).map { (i: Int) -> SKPhotoProtocol in
|
return (0..<10).map { (i: Int) -> SKPhotoProtocol in
|
||||||
let photo = SKPhoto.photoWithImage(UIImage(named: "image\(i%10).jpg")!)
|
let photo = SKPhoto.photoWithImage(UIImage(named: "image\(i%10).jpg")!)
|
||||||
photo.caption = caption[i%10]
|
photo.caption = caption[i%10]
|
||||||
// photo.contentMode = .ScaleAspectFill
|
|
||||||
return photo
|
return photo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,20 +8,12 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import SKPhotoBrowser
|
import SKPhotoBrowser
|
||||||
import SDWebImage
|
|
||||||
|
|
||||||
class FromWebViewController: UIViewController, SKPhotoBrowserDelegate {
|
class FromWebViewController: UIViewController, SKPhotoBrowserDelegate {
|
||||||
@IBOutlet weak var imageView: UIImageView!
|
|
||||||
var images = [SKPhotoProtocol]()
|
var images = [SKPhotoProtocol]()
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
SKCache.sharedCache.imageCache = CustomImageCache()
|
|
||||||
imageView.sd_setImageWithURL(NSURL(string: "https://placehold.jp/1500x1500.png")) {
|
|
||||||
guard let url = $0.3.absoluteString else { return }
|
|
||||||
SKCache.sharedCache.setImage($0.0, forKey: url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func pushButton(sender: AnyObject) {
|
@IBAction func pushButton(sender: AnyObject) {
|
||||||
|
|
@ -43,8 +35,6 @@ extension FromWebViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func removePhoto(browser: SKPhotoBrowser, index: Int, reload: (() -> Void)) {
|
func removePhoto(browser: SKPhotoBrowser, index: Int, reload: (() -> Void)) {
|
||||||
SKCache.sharedCache.removeImageForKey("somekey")
|
|
||||||
reload()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +43,7 @@ extension FromWebViewController {
|
||||||
private extension FromWebViewController {
|
private extension FromWebViewController {
|
||||||
func createWebPhotos() -> [SKPhotoProtocol] {
|
func createWebPhotos() -> [SKPhotoProtocol] {
|
||||||
return (0..<10).map { (i: Int) -> SKPhotoProtocol in
|
return (0..<10).map { (i: Int) -> SKPhotoProtocol in
|
||||||
let photo = SKPhoto.photoWithImageURL("https://placehold.jp/150\(i)x150\(i).png")
|
let photo = SKPhoto.photoWithImageURL("https://placehold.jp/15\(i)x15\(i).png")
|
||||||
photo.caption = caption[i%10]
|
photo.caption = caption[i%10]
|
||||||
photo.shouldCachePhotoURLImage = true
|
photo.shouldCachePhotoURLImage = true
|
||||||
return photo
|
return photo
|
||||||
|
|
@ -61,24 +51,3 @@ private extension FromWebViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomImageCache: SKImageCacheable {
|
|
||||||
var cache: SDImageCache
|
|
||||||
|
|
||||||
init() {
|
|
||||||
let cache = SDImageCache(namespace: "com.suzuki.custom.cache")
|
|
||||||
self.cache = cache
|
|
||||||
}
|
|
||||||
|
|
||||||
func imageForKey(key: String) -> UIImage? {
|
|
||||||
guard let image = cache.imageFromDiskCacheForKey(key) else { return nil }
|
|
||||||
|
|
||||||
return image
|
|
||||||
}
|
|
||||||
|
|
||||||
func setImage(image: UIImage, forKey key: String) {
|
|
||||||
cache.storeImage(image, forKey: key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeImageForKey(key: String) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
|
||||||
<string>for example, this app accesses the user’s photo library</string>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
|
|
@ -48,10 +46,10 @@
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue