Compare commits

..

No commits in common. "master" and "2.0.3" have entirely different histories.

28 changed files with 1176 additions and 1898 deletions

View File

@ -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
View File

@ -1,22 +1,18 @@
SKPhotoBrowser
========================
![Language](https://img.shields.io/badge/language-Swift%202.3-orange.svg)
[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Cocoapods Compatible](https://img.shields.io/cocoapods/v/SKPhotoBrowser.svg?style=flat)](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).
## 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
- 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
- Minimalistic Facebook-like interface, swipe up/down to dismiss
- Ability to custom control. (hide/ show toolbar for controls, / swipe control)
- Handling and caching photos from web
- Landscape handling
- has simple ability to custom photobrowser. (hide/show statusbar, some toolbar for controls, swipe control)
- Handling and caching photos from web
- Landscape handling.
- Delete photo support(by offbye). By set displayDelete=true show a delete icon in statusbar, deleted indexes can be obtain from delegate func didDeleted
![sample](Screenshots/example02.gif)
@ -46,45 +42,43 @@ github "suzuki-0000/SKPhotoBrowser"
Add the code directly into your project.
##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
// 1. create SKPhoto Array from UIImage
// add SKPhoto Array from UIImage
var images = [SKPhoto]()
let photo = SKPhoto.photoWithImage(UIImage())// add some UIImage
images.append(photo)
// 2. create PhotoBrowser Instance, and present from your viewController.
// create PhotoBrowser Instance, and present.
let browser = SKPhotoBrowser(photos: images)
browser.initializePageIndex(0)
browser.delegate = self
presentViewController(browser, animated: true, completion: {})
```
from URLs:
from web URLs:
```swift
// 1. create URL Array
// URL pattern snippet
var images = [SKPhoto]()
let photo = SKPhoto.photoWithImageURL("https://placehold.jp/150x150.png")
photo.shouldCachePhotoURLImage = false // you can use image cache by true(NSCache)
images.append(photo)
// 2. create PhotoBrowser Instance, and present.
// create PhotoBrowser Instance, and present.
let browser = SKPhotoBrowser(photos: images)
browser.initializePageIndex(0)
presentViewController(browser, animated: true, completion: {})
```
from local files:
```swift
// 1. create images from local files
// images from local files
var images = [SKLocalPhoto]()
let photo = SKLocalPhoto.photoWithImageURL("..some_local_path/150x150.png")
images.append(photo)
// 2. create PhotoBrowser Instance, and present.
// create PhotoBrowser Instance, and present.
let browser = SKPhotoBrowser(photos: images)
browser.initializePageIndex(0)
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) {
let cell = collectionView.cellForItemAtIndexPath(indexPath)
let originImage = cell.exampleImageView.image // some image for baseImage
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
browser.initializePageIndex(indexPath.row)
presentViewController(browser, animated: true, completion: {})
@ -104,65 +97,40 @@ func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath i
### Custom
#### 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
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)
```
#### Colors
You can customize text, icon and background colors via SKPhotoBrowserOptions
```swift
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()
browser.displayToolbar = false // all tool bar will be hidden
browser.displayCounterLabel = false // counter label will be hidden
browser.displayBackAndForwardButton = false // back / forward button will be hidden
browser.displayAction = false // action button will be hidden
browser.displayDeleteButton = true // delete button will be shown
```
#### CustomButton Image
Close, Delete buttons are able to change image and frame.
Close button is able to change image and frame.
``` swift
browser.updateCloseButton(UIImage())
browser.updateUpdateButton(UIImage())
browser.displayCustomCloseButton = true // custom close button will be enable
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
You can delete your photo for your own handling. detect button tap from `removePhoto` delegate function.
#### Delete
You can delete your photo for your own hanlding.
#### Photo Captions
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
vertical swipe can enable/disable:
``` swift
SKPhotoBrowserOptions.disableVerticalSwipe = true
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
browser.disableVerticalSwipe = true
```
#### Delegate
@ -208,16 +177,14 @@ func didDismissAtPageIndex(index: Int) {
```
#### Options
You can access via `SKPhotoBrowserOptions`, which can use for browser control.
- single tap handling, dismiss/noaction
#### Minor Option
- blackArea handling which is appearing outside of photo
- single tap handling, dismiss/noaction
- bounce animation when appearing/dismissing
- text color, font, or more
``` swift
SKPhotoBrowserOptions.enableZoomBlackArea = true // default true
SKPhotoBrowserOptions.enableSingleTapDismiss = true // default false
SKPhotoBrowserOptions.bounceAnimation = true // default false
enableZoomBlackArea = true // default true
enableSingleTapDismiss = true // default false
bounceAnimation = true // default false
```
## Photos from

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
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.homepage = "https://github.com/suzuki-0000/SKPhotoBrowser"
s.license = { :type => "MIT", :file => "LICENSE" }

View File

@ -7,7 +7,6 @@
objects = {
/* 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 */; };
210E53EF1C986D57008DD5E3 /* UIImage+Rotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210E53EE1C986D57008DD5E3 /* UIImage+Rotation.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 */; };
8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8909B5421BC791510060A053 /* SKZoomingScrollView.swift */; };
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 */; };
A64B89361CB04222000071B9 /* SKPhotoBrowserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A64B89351CB04222000071B9 /* SKPhotoBrowserTests.swift */; };
A64B89381CB04222000071B9 /* SKPhotoBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5301BC791280060A053 /* SKPhotoBrowser.framework */; };
@ -45,7 +37,6 @@
/* End PBXContainerItemProxy 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>"; };
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>"; };
@ -62,13 +53,6 @@
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>"; };
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>"; };
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>"; };
@ -124,25 +108,17 @@
8909B5321BC791280060A053 /* SKPhotoBrowser */ = {
isa = PBXGroup;
children = (
89D0BA461D5994A8002A811B /* SKAnimator.swift */,
8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */,
26C97AD41D0EB6870039F6CB /* SKCache.swift */,
26C97AD81D0EB8BB0039F6CB /* SKCacheable.swift */,
8909B53B1BC791510060A053 /* SKCaptionView.swift */,
8909B53C1BC791510060A053 /* SKDetectingImageView.swift */,
8909B53D1BC791510060A053 /* SKDetectingView.swift */,
8909B53E1BC791510060A053 /* SKIndicatorView.swift */,
8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */,
89C24A831D657AFE005F09A9 /* SKPagingScrollView.swift */,
8909B53F1BC791510060A053 /* SKPhoto.swift */,
8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.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 */,
8909B5331BC791280060A053 /* SKPhotoBrowser.h */,
8909B5351BC791280060A053 /* Info.plist */,
210E53EB1C986D1C008DD5E3 /* extensions */,
8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */,
@ -223,11 +199,9 @@
TargetAttributes = {
8909B52F1BC791280060A053 = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0800;
};
A64B89321CB04222000071B9 = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
};
};
};
@ -289,21 +263,13 @@
buildActionMask = 2147483647;
files = (
26C97AD91D0EB8BB0039F6CB /* SKCacheable.swift in Sources */,
89C24A841D657AFE005F09A9 /* SKPagingScrollView.swift in Sources */,
890A6F201D5D9E53003B01F0 /* SKToolbar.swift in Sources */,
8909B5441BC791510060A053 /* SKDetectingImageView.swift in Sources */,
8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */,
8CA6C6521CBE76E80054D3C2 /* SKLocalPhoto.swift in Sources */,
89D0BA471D5994A8002A811B /* SKAnimator.swift in Sources */,
210E53ED1C986D3A008DD5E3 /* UIView+Radius.swift in Sources */,
8917B1B01D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift in Sources */,
89D0BA491D59966B002A811B /* SKMesurement.swift in Sources */,
8909B5471BC791510060A053 /* SKPhoto.swift in Sources */,
8909B5461BC791510060A053 /* SKIndicatorView.swift in Sources */,
8917B1B41D5A14B0000CE1C4 /* SKButtons.swift in Sources */,
89C24A821D657AD1005F09A9 /* SKPhotoBrowserOptions.swift in Sources */,
26C97AD51D0EB6870039F6CB /* SKCache.swift in Sources */,
0AE527521DABB87500619FAD /* SKNavigationBar.swift in Sources */,
210E53EF1C986D57008DD5E3 /* UIImage+Rotation.swift in Sources */,
8909B5431BC791510060A053 /* SKCaptionView.swift in Sources */,
8909B5491BC791510060A053 /* SKPhotoBrowser.swift in Sources */,
@ -436,7 +402,6 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 2.3;
};
name = Debug;
};
@ -455,7 +420,6 @@
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.SKPhotoBrowser;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 2.3;
};
name = Release;
};
@ -468,7 +432,6 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "Alexsander-Khitev.SKPhotoBrowserTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3;
};
name = Debug;
};
@ -481,7 +444,6 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "Alexsander-Khitev.SKPhotoBrowserTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3;
};
name = Release;
};

View File

@ -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()
}
})
}
}

View File

@ -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)
}
}

View File

@ -61,13 +61,13 @@ private extension SKCaptionView {
photoLabel.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
photoLabel.opaque = false
photoLabel.backgroundColor = .clearColor()
photoLabel.textColor = SKPhotoBrowserOptions.textAndIconColor
photoLabel.textColor = .whiteColor()
photoLabel.textAlignment = .Center
photoLabel.lineBreakMode = .ByTruncatingTail
photoLabel.numberOfLines = 3
photoLabel.shadowColor = UIColor(white: 0.0, alpha: 0.5)
photoLabel.shadowOffset = CGSize(width: 0.0, height: 1.0)
photoLabel.font = SKPhotoBrowserOptions.captionFont
photoLabel.font = UIFont.systemFontOfSize(17.0)
photoLabel.text = photo?.caption
addSubview(photoLabel)
}

View File

@ -16,6 +16,6 @@ class SKIndicatorView: UIActivityIndicatorView {
override init(frame: CGRect) {
super.init(frame: frame)
center = CGPoint(x: frame.width / 2, y: frame.height / 2)
activityIndicatorViewStyle = SKPhotoBrowserOptions.backgroundColor.isEqual(UIColor.whiteColor()) ? .Gray : .WhiteLarge
activityIndicatorViewStyle = .WhiteLarge
}
}

View File

@ -13,7 +13,6 @@ public class SKLocalPhoto: NSObject, SKPhotoProtocol {
public var underlyingImage: UIImage!
public var photoURL: String!
public var contentMode: UIViewContentMode = .ScaleToFill
public var shouldCachePhotoURLImage: Bool = false
public var caption: String!
public var index: Int = 0
@ -50,7 +49,9 @@ public class SKLocalPhoto: NSObject, SKPhotoProtocol {
self.underlyingImage = image
self.loadUnderlyingImageComplete()
}
}
}
}
}

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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
}
}

View File

@ -12,7 +12,6 @@ import UIKit
var underlyingImage: UIImage! { get }
var caption: String! { get }
var index: Int { get set}
var contentMode: UIViewContentMode { get set }
func loadUnderlyingImageAndNotify()
func checkCache()
}
@ -22,7 +21,6 @@ public class SKPhoto: NSObject, SKPhotoProtocol {
public var underlyingImage: UIImage!
public var photoURL: String!
public var contentMode: UIViewContentMode = .ScaleAspectFill
public var shouldCachePhotoURLImage: Bool = false
public var caption: String!
public var index: Int = 0
@ -48,30 +46,24 @@ public class SKPhoto: NSObject, SKPhotoProtocol {
}
public func checkCache() {
guard let photoURL = photoURL else {
return
}
guard shouldCachePhotoURLImage else {
return
}
if SKCache.sharedCache.imageCache is SKRequestResponseCacheable {
let request = NSURLRequest(URL: NSURL(string: photoURL)!)
if let img = SKCache.sharedCache.imageForRequest(request) {
underlyingImage = img
}
} else {
if let img = SKCache.sharedCache.imageForKey(photoURL) {
underlyingImage = img
if photoURL != nil && shouldCachePhotoURLImage {
if SKCache.sharedCache.imageCache is SKRequestResponseCacheable {
let request = NSURLRequest(URL: NSURL(string: photoURL)!)
if let img = SKCache.sharedCache.imageForRequest(request) {
underlyingImage = img
}
} else {
if let img = SKCache.sharedCache.imageForKey(photoURL) {
underlyingImage = img
}
}
}
}
public func loadUnderlyingImageAndNotify() {
if underlyingImage != nil {
if underlyingImage != nil && photoURL == nil {
loadUnderlyingImageComplete()
return
}
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 SKCache.sharedCache.imageCache is SKRequestResponseCacheable {
SKCache.sharedCache.setImageData(response!, response: data!, request: task.originalRequest!)

File diff suppressed because it is too large Load Diff

View File

@ -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?
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -8,7 +8,8 @@
import UIKit
public class SKZoomingScrollView: UIScrollView {
public class SKZoomingScrollView: UIScrollView, UIScrollViewDelegate, SKDetectingViewDelegate, SKDetectingImageViewDelegate {
var captionView: SKCaptionView!
var photo: SKPhotoProtocol! {
didSet {
@ -48,14 +49,14 @@ public class SKZoomingScrollView: UIScrollView {
// tap
tapView = SKDetectingView(frame: bounds)
tapView.delegate = self
tapView.backgroundColor = .clearColor()
tapView.backgroundColor = UIColor.clearColor()
tapView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
addSubview(tapView)
// image
photoImageView = SKDetectingImageView(frame: frame)
photoImageView.delegate = self
photoImageView.contentMode = .Bottom
photoImageView.contentMode = .ScaleAspectFill
photoImageView.backgroundColor = .clearColor()
addSubview(photoImageView)
@ -103,6 +104,7 @@ public class SKZoomingScrollView: UIScrollView {
}
public func setMaxMinZoomScalesForCurrentBounds() {
maximumZoomScale = 1
minimumZoomScale = 1
zoomScale = 1
@ -117,12 +119,28 @@ public class SKZoomingScrollView: UIScrollView {
let xScale = boundsSize.width / imageSize.width
let yScale = boundsSize.height / imageSize.height
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 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 {
// 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 {
@ -136,7 +154,7 @@ public class SKZoomingScrollView: UIScrollView {
// here if photoImageView.frame.width == deviceScreenWidth
maxScale = 2.5
}
maximumZoomScale = maxScale
minimumZoomScale = minScale
zoomScale = minScale
@ -182,25 +200,9 @@ public class SKZoomingScrollView: UIScrollView {
}
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
photoImageView.image = image
photoImageView.contentMode = photo.contentMode
photoImageView.backgroundColor = SKPhotoBrowserOptions.backgroundColor
var photoImageViewFrame = CGRect.zero
photoImageViewFrame.origin = CGPoint.zero
@ -236,18 +238,23 @@ public class SKZoomingScrollView: UIScrollView {
newZoom = maximumZoomScale
}
*/
let zoomRect = zoomRectForScrollViewWith(maximumZoomScale, touchPoint: touchPoint)
zoomToRect(zoomRect, animated: true)
zoomToRect(zoomRectForScrollViewWith(maximumZoomScale, touchPoint: touchPoint), animated: true)
}
// delay control
photoBrowser?.hideControlsAfterDelay()
}
}
// MARK: - UIScrollViewDelegate
extension SKZoomingScrollView: UIScrollViewDelegate {
public func zoomRectForScrollViewWith(scale: CGFloat, touchPoint: CGPoint) -> CGRect {
let w = frame.size.width / scale
let h = frame.size.height / scale
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? {
return photoImageView
}
@ -260,56 +267,26 @@ extension SKZoomingScrollView: UIScrollViewDelegate {
setNeedsLayout()
layoutIfNeeded()
}
}
// MARK: - SKDetectingImageViewDelegate
extension SKZoomingScrollView: SKDetectingViewDelegate {
// MARK: - SKDetectingViewDelegate
func handleSingleTap(view: UIView, touch: UITouch) {
guard let browser = photoBrowser else {
return
}
guard SKPhotoBrowserOptions.enableZoomBlackArea == true else {
return
}
if browser.areControlsHidden() == false && SKPhotoBrowserOptions.enableSingleTapDismiss == true {
browser.determineAndClose()
} else {
browser.toggleControls()
if photoBrowser?.enableZoomBlackArea == true {
if photoBrowser?.areControlsHidden() == false && photoBrowser?.enableSingleTapDismiss == true {
photoBrowser?.determineAndClose()
}
photoBrowser?.toggleControls()
}
}
func handleDoubleTap(view: UIView, touch: UITouch) {
if SKPhotoBrowserOptions.enableZoomBlackArea == true {
if photoBrowser?.enableZoomBlackArea == true {
let needPoint = getViewFramePercent(view, touch: touch)
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) {
handleDoubleTap(touchPoint)
}
}
private extension SKZoomingScrollView {
func getViewFramePercent(view: UIView, touch: UITouch) -> CGPoint {
private func getViewFramePercent(view: UIView, touch: UITouch) -> CGPoint {
let oneWidthViewPercent = view.bounds.width / 100
let viewTouchPoint = touch.locationInView(view)
let viewWidthTouch = viewTouchPoint.x
@ -330,12 +307,16 @@ private extension SKZoomingScrollView {
return allPoint
}
func zoomRectForScrollViewWith(scale: CGFloat, touchPoint: CGPoint) -> CGRect {
let w = frame.size.width / scale
let h = frame.size.height / scale
let x = touchPoint.x - (h / max(UIScreen.mainScreen().scale, 2.0))
let y = touchPoint.y - (w / max(UIScreen.mainScreen().scale, 2.0))
return CGRect(x: x, y: y, width: w, height: h)
// MARK: - SKDetectingImageViewDelegate
func handleImageViewSingleTap(touchPoint: CGPoint) {
if photoBrowser!.enableSingleTapDismiss {
photoBrowser?.determineAndClose()
} else {
photoBrowser?.toggleControls()
}
}
}
func handleImageViewDoubleTap(touchPoint: CGPoint) {
handleDoubleTap(touchPoint)
}
}

View File

@ -14,69 +14,63 @@ extension UIImage {
guard self.imageOrientation != .Up else {
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
// calculated above.
let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage!), 0,
CGImageGetColorSpace(self.CGImage!)!,
CGImageGetBitmapInfo(self.CGImage!).rawValue)
CGContextConcatCTM(ctx!, transform)
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage).rawValue)
CGContextConcatCTM(ctx, transform)
switch self.imageOrientation {
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:
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
if let cgImage = CGBitmapContextCreateImage(ctx!) {
if let cgImage = CGBitmapContextCreateImage(ctx) {
return UIImage(CGImage: cgImage)
} else {
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
}
}

View File

@ -1,5 +0,0 @@
platform :ios, '8.0'
use_frameworks!
pod 'SDWebImage', '~>3.8'

View File

@ -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

View File

@ -28,7 +28,6 @@
89FC5DBB1D54A04900F1BE52 /* FromWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FC5DBA1D54A04900F1BE52 /* FromWebViewController.swift */; };
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, ); }; };
DDFD24AF2FBA5A60984D378D /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C2188E912BB106233AA4AB2 /* Pods.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -71,7 +70,6 @@
/* Begin PBXFileReference section */
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; };
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>"; };
@ -93,8 +91,6 @@
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>"; };
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 */
/* Begin PBXFrameworksBuildPhase section */
@ -103,7 +99,6 @@
buildActionMask = 2147483647;
files = (
A6A7B7801C9578E30025AC07 /* SKPhotoBrowser.framework in Frameworks */,
DDFD24AF2FBA5A60984D378D /* Pods.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -116,8 +111,6 @@
8909B56C1BC792570060A053 /* SKPhotoBrowser.xcodeproj */,
8909B5591BC792150060A053 /* SKPhotoBrowserExample */,
8909B5581BC792150060A053 /* Products */,
D1D8ECD45B290372235B8168 /* Pods */,
C646D2C27A5B9CCC003A9BD1 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -205,23 +198,6 @@
name = Info;
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 */
/* Begin PBXNativeTarget section */
@ -229,13 +205,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 8909B5691BC792150060A053 /* Build configuration list for PBXNativeTarget "SKPhotoBrowserExample" */;
buildPhases = (
F19A62C34B2F0CFF753F30C3 /* Check Pods Manifest.lock */,
8909B5531BC792150060A053 /* Sources */,
8909B5541BC792150060A053 /* Frameworks */,
8909B5551BC792150060A053 /* Resources */,
A6A7B7841C9578E30025AC07 /* Embed Frameworks */,
575DBD5855AB711E5773767A /* Embed Pods Frameworks */,
2ECF43C4E99CDE3D98AE6842 /* Copy Pods Resources */,
);
buildRules = (
);
@ -258,7 +231,6 @@
TargetAttributes = {
8909B5561BC792150060A053 = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0800;
};
};
};
@ -328,54 +300,6 @@
};
/* 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 */
8909B5531BC792150060A053 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@ -503,7 +427,6 @@
};
8909B56A1BC792150060A053 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B3E081D4F2C8623852C459F5 /* Pods.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
@ -512,13 +435,11 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.aSKPhotoBrowserExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3;
};
name = Debug;
};
8909B56B1BC792150060A053 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DD077DBD0C164C96BCC7494F /* Pods.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
@ -527,7 +448,6 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.keishi.suzuki.aSKPhotoBrowserExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3;
};
name = Release;
};

View File

@ -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>

View File

@ -1,5 +1,5 @@
<?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>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
@ -88,26 +88,14 @@
<action selector="pushButton:" destination="wTD-ba-cWw" eventType="touchUpInside" id="xIc-2O-Gmb"/>
</connections>
</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>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<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="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>
</view>
<tabBarItem key="tabBarItem" title="FromWeb" id="2lE-np-9H3"/>
<connections>
<outlet property="imageView" destination="yxe-Wd-8iE" id="aMH-Df-3r0"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="jdP-ty-Ygs" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>

View File

@ -107,9 +107,10 @@ class FromCameraRollViewController: UIViewController, SKPhotoBrowserDelegate, UI
browser.initializePageIndex(indexPath.row)
browser.delegate = self
// browser.bounceAnimation = true
// browser.displayDeleteButton = true
// browser.displayAction = false
browser.bounceAnimation = true
browser.displayDeleteButton = true
browser.displayAction = false
browser.statusBarStyle = .LightContent
self.presentViewController(browser, animated: true, completion: {})
}
@ -167,7 +168,8 @@ class FromCameraRollViewController: UIViewController, SKPhotoBrowserDelegate, UI
let requestId = dict?[PHImageResultRequestIDKey] as? NSNumber
completion(image: image, requestId: requestId?.intValue)
}
} else {
}
else {
return imageManager.requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: options) { image, dict in
let requestId = dict?[PHImageResultRequestIDKey] as? NSNumber
completion(image: image, requestId: requestId?.intValue)

View File

@ -47,7 +47,6 @@ extension FromLocalViewController {
}
cell.exampleImageView.image = UIImage(named: "image\(indexPath.row % 10).jpg")
// cell.exampleImageView.contentMode = .ScaleAspectFill
return cell
}
}
@ -62,13 +61,11 @@ extension FromLocalViewController {
guard let originImage = cell.exampleImageView.image else {
return
}
// SKPhotoBrowserOptions.displayToolbar = false
let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell)
// let browser = SKPhotoBrowser(photos: images)
browser.initializePageIndex(indexPath.row)
browser.delegate = self
// browser.updateCloseButton(UIImage(named: "image1.jpg")!)
browser.statusBarStyle = .LightContent
presentViewController(browser, animated: true, completion: {})
}
@ -133,7 +130,6 @@ private extension FromLocalViewController {
return (0..<10).map { (i: Int) -> SKPhotoProtocol in
let photo = SKPhoto.photoWithImage(UIImage(named: "image\(i%10).jpg")!)
photo.caption = caption[i%10]
// photo.contentMode = .ScaleAspectFill
return photo
}
}

View File

@ -8,20 +8,12 @@
import UIKit
import SKPhotoBrowser
import SDWebImage
class FromWebViewController: UIViewController, SKPhotoBrowserDelegate {
@IBOutlet weak var imageView: UIImageView!
var images = [SKPhotoProtocol]()
override func 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) {
@ -43,8 +35,6 @@ extension FromWebViewController {
}
func removePhoto(browser: SKPhotoBrowser, index: Int, reload: (() -> Void)) {
SKCache.sharedCache.removeImageForKey("somekey")
reload()
}
}
@ -53,7 +43,7 @@ extension FromWebViewController {
private extension FromWebViewController {
func createWebPhotos() -> [SKPhotoProtocol] {
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.shouldCachePhotoURLImage = true
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) {
}
}

View File

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>for example, this app accesses the users photo library</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
@ -48,10 +46,10 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>