jumppage功能
This commit is contained in:
22
Pods/DynamicBlurView/LICENSE
generated
Normal file
22
Pods/DynamicBlurView/LICENSE
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Kyohei Ito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
162
Pods/DynamicBlurView/README.md
generated
Normal file
162
Pods/DynamicBlurView/README.md
generated
Normal file
@@ -0,0 +1,162 @@
|
||||
# DynamicBlurView
|
||||
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
[](http://cocoadocs.org/docsets/DynamicBlurView)
|
||||
[](http://cocoadocs.org/docsets/DynamicBlurView)
|
||||
[](http://cocoadocs.org/docsets/DynamicBlurView)
|
||||
|
||||
DynamicBlurView is a dynamic and high performance UIView subclass for Blur.
|
||||
|
||||
#### [Appetize's Demo](https://appetize.io/app/9pvxr367tm0jj2bcy8zavxnqkg?device=iphone6&scale=75&orientation=portrait)
|
||||
|
||||

|
||||
|
||||
|
||||
- Since using the CADisplayLink, it is a high performance.
|
||||
- Can generate a plurality of BlurView.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Swift 4.2
|
||||
- iOS 8.0 or later
|
||||
- tvOS 9.0 or later
|
||||
|
||||
## How to Install DynamicBlurView
|
||||
|
||||
#### CocoaPods
|
||||
|
||||
Add the following to your `Podfile`:
|
||||
|
||||
```Ruby
|
||||
pod "DynamicBlurView"
|
||||
```
|
||||
|
||||
#### Carthage
|
||||
|
||||
Add the following to your `Cartfile`:
|
||||
|
||||
```Ruby
|
||||
github "KyoheiG3/DynamicBlurView"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Example
|
||||
|
||||
Blur the whole
|
||||
|
||||
```swift
|
||||
let blurView = DynamicBlurView(frame: view.bounds)
|
||||
blurView.blurRadius = 10
|
||||
view.addSubview(blurView)
|
||||
```
|
||||
|
||||
Animation
|
||||
|
||||
```swift
|
||||
UIView.animateWithDuration(0.5) {
|
||||
blurView.blurRadius = 30
|
||||
}
|
||||
```
|
||||
|
||||
Ratio
|
||||
|
||||
```swift
|
||||
blurView.blurRatio = 0.5
|
||||
```
|
||||
|
||||
### Variable
|
||||
|
||||
```swift
|
||||
var drawsAsynchronously: Bool
|
||||
```
|
||||
|
||||
- When true, it captures displays image and blur it asynchronously. Try to set true if needs more performance.
|
||||
- Asynchronous drawing is possibly crash when needs to process on main thread that drawing with animation for example.
|
||||
- Default is false.
|
||||
|
||||
```Swift
|
||||
var blurRadius: CGFloat
|
||||
```
|
||||
|
||||
- Strength of the blur.
|
||||
|
||||
```Swift
|
||||
var trackingMode: TrackingMode
|
||||
```
|
||||
|
||||
- Mode for update frequency.
|
||||
- `Common` is constantly updated.
|
||||
- `Tracking` is only during scrolling update.
|
||||
- `None` is not update.
|
||||
|
||||
```swift
|
||||
var blendColor: UIColor?
|
||||
```
|
||||
|
||||
- Blend in the blurred image.
|
||||
|
||||
```swift
|
||||
var iterations: Int
|
||||
```
|
||||
|
||||
- Number of times for blur.
|
||||
- Default is 3.
|
||||
|
||||
```swift
|
||||
var isDeepRendering: Bool
|
||||
```
|
||||
|
||||
- If the view want to render beyond the layer, should be true.
|
||||
- Default is false.
|
||||
|
||||
```swift
|
||||
var blurRatio: CGFloat
|
||||
```
|
||||
|
||||
- When none of tracking mode, it can change the radius of blur with the ratio. Should set from 0 to 1.
|
||||
- Default is 1.
|
||||
|
||||
```swift
|
||||
var quality: CaptureQuality
|
||||
```
|
||||
|
||||
- Quality of captured image.
|
||||
- Default is medium.
|
||||
|
||||
### Function
|
||||
|
||||
```swift
|
||||
func refresh()
|
||||
```
|
||||
|
||||
- Remove cache of blur image then get it again.
|
||||
|
||||
```swift
|
||||
func remove()
|
||||
```
|
||||
|
||||
- Remove cache of blur image.
|
||||
|
||||
```swift
|
||||
func animate()
|
||||
```
|
||||
|
||||
- Should use when needs to change layout with animation when is set none of tracking mode.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
- Inspired by [FXBlurView](https://github.com/nicklockwood/FXBlurView) in [nicklockwood](https://github.com/nicklockwood).
|
||||
|
||||
## Author
|
||||
|
||||
#### Kyohei Ito
|
||||
|
||||
- [GitHub](https://github.com/kyoheig3)
|
||||
- [Twitter](https://twitter.com/kyoheig3)
|
||||
|
||||
Follow me 🎉
|
||||
|
||||
## LICENSE
|
||||
|
||||
Under the MIT license. See LICENSE file for details.
|
||||
131
Pods/DynamicBlurView/Sources/DynamicBlurView/BlurLayer.swift
generated
Normal file
131
Pods/DynamicBlurView/Sources/DynamicBlurView/BlurLayer.swift
generated
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// BlurLayer.swift
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2017/08/14.
|
||||
// Copyright © 2017年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
private extension CGRect {
|
||||
func rectangle(_ s: CGSize) -> CGRect {
|
||||
let x = origin.x / s.width
|
||||
let y = origin.y / s.height
|
||||
let width = size.width / s.width
|
||||
let height = size.height / s.height
|
||||
return CGRect(x: x, y: y, width: width, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
class BlurLayer: CALayer {
|
||||
private static let blurRadiusKey = "blurRadius"
|
||||
private static let blurLayoutKey = "blurLayout"
|
||||
@NSManaged var blurRadius: CGFloat
|
||||
@NSManaged private var blurLayout: CGFloat
|
||||
|
||||
private var fromBlurRadius: CGFloat?
|
||||
var presentationRadius: CGFloat {
|
||||
if let radius = fromBlurRadius {
|
||||
if let layer = presentation() {
|
||||
return layer.blurRadius
|
||||
} else {
|
||||
return radius
|
||||
}
|
||||
} else {
|
||||
return blurRadius
|
||||
}
|
||||
}
|
||||
|
||||
override class func needsDisplay(forKey key: String) -> Bool {
|
||||
if key == blurRadiusKey || key == blurLayoutKey {
|
||||
return true
|
||||
}
|
||||
return super.needsDisplay(forKey: key)
|
||||
}
|
||||
|
||||
open override func action(forKey event: String) -> CAAction? {
|
||||
if event == BlurLayer.blurRadiusKey {
|
||||
fromBlurRadius = nil
|
||||
|
||||
if let action = super.action(forKey: "opacity") as? CABasicAnimation {
|
||||
fromBlurRadius = (presentation() ?? self).blurRadius
|
||||
|
||||
action.keyPath = event
|
||||
action.fromValue = fromBlurRadius
|
||||
return action
|
||||
}
|
||||
}
|
||||
|
||||
if event == BlurLayer.blurLayoutKey, let action = super.action(forKey: "opacity") as? CABasicAnimation {
|
||||
action.keyPath = event
|
||||
action.fromValue = 0
|
||||
action.toValue = 1
|
||||
return action
|
||||
}
|
||||
|
||||
return super.action(forKey: event)
|
||||
}
|
||||
}
|
||||
|
||||
extension BlurLayer {
|
||||
func draw(_ image: UIImage, fixes isFixes: Bool, baseLayer: CALayer?) {
|
||||
contents = image.cgImage
|
||||
contentsScale = image.scale
|
||||
|
||||
if isFixes, let blurLayer = presentation() {
|
||||
contentsRect = blurLayer.convert(blurLayer.bounds, to: baseLayer).rectangle(image.size)
|
||||
}
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
fromBlurRadius = nil
|
||||
}
|
||||
|
||||
func animate() {
|
||||
UIView.performWithoutAnimation {
|
||||
blurLayout = 0
|
||||
}
|
||||
blurLayout = 1
|
||||
}
|
||||
|
||||
func render(in context: CGContext, for layer: CALayer) {
|
||||
let layers = hideOverlappingLayers(layer.sublayers)
|
||||
layer.render(in: context)
|
||||
layers.forEach {
|
||||
$0.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
private func hideOverlappingLayers(_ layers: [CALayer]?) -> [CALayer] {
|
||||
var hiddenLayers: [CALayer] = []
|
||||
guard let layers = layers else {
|
||||
return hiddenLayers
|
||||
}
|
||||
|
||||
for layer in layers.reversed() {
|
||||
if isHang(to: layer) {
|
||||
return hiddenLayers + hideOverlappingLayers(layer.sublayers)
|
||||
}
|
||||
if layer.isHidden == false {
|
||||
layer.isHidden = true
|
||||
hiddenLayers.append(layer)
|
||||
}
|
||||
if layer == self {
|
||||
return hiddenLayers
|
||||
}
|
||||
}
|
||||
return hiddenLayers
|
||||
}
|
||||
|
||||
private func isHang(to target: CALayer) -> Bool {
|
||||
var layer = superlayer
|
||||
while layer != nil {
|
||||
if layer == target {
|
||||
return true
|
||||
}
|
||||
layer = layer?.superlayer
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
33
Pods/DynamicBlurView/Sources/DynamicBlurView/CGContext+CGImage.swift
generated
Normal file
33
Pods/DynamicBlurView/Sources/DynamicBlurView/CGContext+CGImage.swift
generated
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// CGContext+CGImage.swift
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2017/08/17.
|
||||
// Copyright © 2017年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension CGContext {
|
||||
static func imageContext(with quality: CaptureQuality, rect: CGRect, opaque: Bool) -> CGContext? {
|
||||
UIGraphicsBeginImageContextWithOptions(rect.size, opaque, quality.imageScale)
|
||||
guard let context = UIGraphicsGetCurrentContext() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
context.translateBy(x: -rect.origin.x, y: -rect.origin.y)
|
||||
context.interpolationQuality = quality.interpolationQuality
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
func makeImage(with blendColor: UIColor?, blendMode: CGBlendMode, size: CGSize) -> CGImage? {
|
||||
if let color = blendColor {
|
||||
setFillColor(color.cgColor)
|
||||
setBlendMode(blendMode)
|
||||
fill(CGRect(origin: .zero, size: size))
|
||||
}
|
||||
|
||||
return makeImage()
|
||||
}
|
||||
}
|
||||
66
Pods/DynamicBlurView/Sources/DynamicBlurView/CGImage+Accelerate.swift
generated
Normal file
66
Pods/DynamicBlurView/Sources/DynamicBlurView/CGImage+Accelerate.swift
generated
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// CGImage+Accelerate.swift
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2017/08/17.
|
||||
// Copyright © 2017年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
import Accelerate
|
||||
import UIKit
|
||||
|
||||
extension CGImage {
|
||||
var area: Int {
|
||||
return width * height
|
||||
}
|
||||
|
||||
private var size: CGSize {
|
||||
return CGSize(width: width, height: height)
|
||||
}
|
||||
|
||||
private var bytes: Int {
|
||||
return bytesPerRow * height
|
||||
}
|
||||
|
||||
private func imageBuffer(from data: UnsafeMutableRawPointer!) -> vImage_Buffer {
|
||||
return vImage_Buffer(data: data, height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: bytesPerRow)
|
||||
}
|
||||
|
||||
func blurred(with boxSize: UInt32, iterations: Int, blendColor: UIColor?, blendMode: CGBlendMode) -> CGImage? {
|
||||
guard let providerData = dataProvider?.data else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let inData = malloc(bytes)
|
||||
var inBuffer = imageBuffer(from: inData)
|
||||
|
||||
let outData = malloc(bytes)
|
||||
var outBuffer = imageBuffer(from: outData)
|
||||
|
||||
let tempSize = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, 0, 0, boxSize, boxSize, nil, vImage_Flags(kvImageEdgeExtend + kvImageGetTempBufferSize))
|
||||
let tempData = malloc(tempSize)
|
||||
|
||||
defer {
|
||||
free(inData)
|
||||
free(outData)
|
||||
free(tempData)
|
||||
}
|
||||
|
||||
let source = CFDataGetBytePtr(providerData)
|
||||
memcpy(inBuffer.data, source, bytes)
|
||||
|
||||
for _ in 0..<iterations {
|
||||
vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, tempData, 0, 0, boxSize, boxSize, nil, vImage_Flags(kvImageEdgeExtend))
|
||||
|
||||
let temp = inBuffer.data
|
||||
inBuffer.data = outBuffer.data
|
||||
outBuffer.data = temp
|
||||
}
|
||||
|
||||
let context = colorSpace.flatMap {
|
||||
CGContext(data: inBuffer.data, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: $0, bitmapInfo: bitmapInfo.rawValue)
|
||||
}
|
||||
|
||||
return context?.makeImage(with: blendColor, blendMode: blendMode, size: size)
|
||||
}
|
||||
}
|
||||
34
Pods/DynamicBlurView/Sources/DynamicBlurView/CaptureQuality.swift
generated
Normal file
34
Pods/DynamicBlurView/Sources/DynamicBlurView/CaptureQuality.swift
generated
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// CaptureQuality.swift
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2017/08/17.
|
||||
// Copyright © 2017年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public enum CaptureQuality {
|
||||
case `default`
|
||||
case low
|
||||
case medium
|
||||
case high
|
||||
|
||||
var imageScale: CGFloat {
|
||||
switch self {
|
||||
case .default, .high:
|
||||
return 0
|
||||
case .low, .medium:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
var interpolationQuality: CGInterpolationQuality {
|
||||
switch self {
|
||||
case .default, .low:
|
||||
return .none
|
||||
case .medium, .high:
|
||||
return .default
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Pods/DynamicBlurView/Sources/DynamicBlurView/DynamicBlurView.h
generated
Normal file
19
Pods/DynamicBlurView/Sources/DynamicBlurView/DynamicBlurView.h
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// DynamicBlurView.h
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2015/04/08.
|
||||
// Copyright (c) 2015年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//! Project version number for DynamicBlurView.
|
||||
FOUNDATION_EXPORT double DynamicBlurViewVersionNumber;
|
||||
|
||||
//! Project version string for DynamicBlurView.
|
||||
FOUNDATION_EXPORT const unsigned char DynamicBlurViewVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <DynamicBlurView/PublicHeader.h>
|
||||
|
||||
|
||||
195
Pods/DynamicBlurView/Sources/DynamicBlurView/DynamicBlurView.swift
generated
Normal file
195
Pods/DynamicBlurView/Sources/DynamicBlurView/DynamicBlurView.swift
generated
Normal file
@@ -0,0 +1,195 @@
|
||||
//
|
||||
// DynamicBlurView.swift
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2015/04/08.
|
||||
// Copyright (c) 2015年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
open class DynamicBlurView: UIView {
|
||||
open override class var layerClass : AnyClass {
|
||||
return BlurLayer.self
|
||||
}
|
||||
|
||||
private var staticImage: UIImage?
|
||||
private var displayLink: CADisplayLink?
|
||||
private var blurLayer: BlurLayer {
|
||||
return layer as! BlurLayer
|
||||
}
|
||||
private let mainQueue = DispatchQueue.main
|
||||
private let globalQueue: DispatchQueue = {
|
||||
if #available (iOS 8.0, *) {
|
||||
return .global(qos: .userInteractive)
|
||||
} else {
|
||||
return .global(priority: .high)
|
||||
}
|
||||
}()
|
||||
private var renderingTarget: UIView? {
|
||||
if isDeepRendering {
|
||||
return window
|
||||
} else {
|
||||
return superview
|
||||
}
|
||||
}
|
||||
|
||||
/// When true, it captures displays image and blur it asynchronously. Try to set true if needs more performance.
|
||||
/// Asynchronous drawing is possibly crash when needs to process on main thread that drawing with animation for example.
|
||||
open var drawsAsynchronously: Bool = false
|
||||
/// Radius of blur.
|
||||
open var blurRadius: CGFloat {
|
||||
set { blurLayer.blurRadius = newValue }
|
||||
get { return blurLayer.blurRadius }
|
||||
}
|
||||
/// Default is none.
|
||||
open var trackingMode: TrackingMode = .none {
|
||||
didSet {
|
||||
if trackingMode != oldValue {
|
||||
linkForDisplay()
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Blend color.
|
||||
open var blendColor: UIColor?
|
||||
/// Blend mode.
|
||||
open var blendMode: CGBlendMode = .plusLighter
|
||||
/// Default is 3.
|
||||
open var iterations: Int = 3
|
||||
/// If the view want to render beyond the layer, should be true.
|
||||
open var isDeepRendering: Bool = false
|
||||
/// When none of tracking mode, it can change the radius of blur with the ratio. Should set from 0 to 1.
|
||||
open var blurRatio: CGFloat = 1 {
|
||||
didSet {
|
||||
if let image = staticImage, oldValue != blurRatio {
|
||||
draw(image, blurRadius: blurRadius, fixes: false, baseLayer: renderingTarget?.layer)
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Quality of captured image.
|
||||
open var quality: CaptureQuality = .medium
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
open override func didMoveToWindow() {
|
||||
super.didMoveToWindow()
|
||||
|
||||
if let view = renderingTarget, window != nil && trackingMode == .none {
|
||||
staticImage = snapshotImage(for: view.layer, conversion: !isDeepRendering)
|
||||
}
|
||||
}
|
||||
|
||||
open override func didMoveToSuperview() {
|
||||
super.didMoveToSuperview()
|
||||
|
||||
if superview == nil {
|
||||
displayLink?.invalidate()
|
||||
displayLink = nil
|
||||
} else {
|
||||
linkForDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
private func async(on queue: DispatchQueue, actions: @escaping () -> Void) {
|
||||
if drawsAsynchronously {
|
||||
queue.async(execute: actions)
|
||||
} else {
|
||||
actions()
|
||||
}
|
||||
}
|
||||
|
||||
private func sync(on queue: DispatchQueue, actions: () -> Void) {
|
||||
if drawsAsynchronously {
|
||||
queue.sync(execute: actions)
|
||||
} else {
|
||||
actions()
|
||||
}
|
||||
}
|
||||
|
||||
private func draw(_ image: UIImage, blurRadius radius: CGFloat, fixes isFixes: Bool, baseLayer: CALayer?) {
|
||||
async(on: globalQueue) { [weak self] in
|
||||
if let me = self, let blurredImage = image.blurred(radius: radius, iterations: me.iterations, ratio: me.blurRatio, blendColor: me.blendColor, blendMode: me.blendMode) {
|
||||
me.sync(on: me.mainQueue) {
|
||||
me.blurLayer.draw(blurredImage, fixes: isFixes, baseLayer: baseLayer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func blurLayerRect(to layer: CALayer, conversion: Bool) -> CGRect {
|
||||
if conversion {
|
||||
let presentationLayer = blurLayer.presentation() ?? blurLayer
|
||||
return presentationLayer.convert(presentationLayer.bounds, to: layer)
|
||||
} else {
|
||||
return layer.bounds
|
||||
}
|
||||
}
|
||||
|
||||
private func snapshotImage(for layer: CALayer, conversion: Bool) -> UIImage? {
|
||||
let rect = blurLayerRect(to: layer, conversion: conversion)
|
||||
guard let context = CGContext.imageContext(with: quality, rect: rect, opaque: isOpaque) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
blurLayer.render(in: context, for: layer)
|
||||
|
||||
defer {
|
||||
UIGraphicsEndImageContext()
|
||||
}
|
||||
|
||||
return UIGraphicsGetImageFromCurrentImageContext()
|
||||
}
|
||||
}
|
||||
|
||||
extension DynamicBlurView {
|
||||
open override func display(_ layer: CALayer) {
|
||||
let blurRadius = blurLayer.presentationRadius
|
||||
let isFixes = isDeepRendering && staticImage != nil
|
||||
if let view = renderingTarget, let image = staticImage ?? snapshotImage(for: view.layer, conversion: !isFixes) {
|
||||
draw(image, blurRadius: blurRadius, fixes: isFixes, baseLayer: view.layer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DynamicBlurView {
|
||||
private func linkForDisplay() {
|
||||
displayLink?.invalidate()
|
||||
displayLink = UIScreen.main.displayLink(withTarget: self, selector: #selector(DynamicBlurView.displayDidRefresh(_:)))
|
||||
displayLink?.add(to: .main, forMode: RunLoop.Mode(rawValue: trackingMode.description))
|
||||
}
|
||||
|
||||
@objc private func displayDidRefresh(_ displayLink: CADisplayLink) {
|
||||
display(layer)
|
||||
}
|
||||
}
|
||||
|
||||
extension DynamicBlurView {
|
||||
/// Remove cache of blur image then get it again.
|
||||
open func refresh() {
|
||||
blurLayer.refresh()
|
||||
staticImage = nil
|
||||
blurRatio = 1
|
||||
display(layer)
|
||||
}
|
||||
|
||||
/// Remove cache of blur image.
|
||||
open func remove() {
|
||||
blurLayer.refresh()
|
||||
staticImage = nil
|
||||
blurRatio = 1
|
||||
layer.contents = nil
|
||||
}
|
||||
|
||||
/// Should use when needs to change layout with animation when is set none of tracking mode.
|
||||
public func animate() {
|
||||
blurLayer.animate()
|
||||
}
|
||||
}
|
||||
27
Pods/DynamicBlurView/Sources/DynamicBlurView/TrackingMode.swift
generated
Normal file
27
Pods/DynamicBlurView/Sources/DynamicBlurView/TrackingMode.swift
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// TrackingMode.swift
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2017/08/17.
|
||||
// Copyright © 2017年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public enum TrackingMode: CustomStringConvertible {
|
||||
case tracking
|
||||
case common
|
||||
case none
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
case .tracking:
|
||||
return RunLoop.Mode.tracking.rawValue
|
||||
case .common:
|
||||
return RunLoop.Mode.common.rawValue
|
||||
case .none:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
Pods/DynamicBlurView/Sources/DynamicBlurView/UIImage+Blur.swift
generated
Normal file
30
Pods/DynamicBlurView/Sources/DynamicBlurView/UIImage+Blur.swift
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// UIImage+Blur.swift
|
||||
// DynamicBlurView
|
||||
//
|
||||
// Created by Kyohei Ito on 2017/08/11.
|
||||
// Copyright © 2017年 kyohei_ito. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public extension UIImage {
|
||||
func blurred(radius: CGFloat, iterations: Int, ratio: CGFloat, blendColor color: UIColor?, blendMode mode: CGBlendMode) -> UIImage? {
|
||||
guard let cgImage = cgImage else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if cgImage.area <= 0 || radius <= 0 {
|
||||
return self
|
||||
}
|
||||
|
||||
var boxSize = UInt32(radius * scale * ratio)
|
||||
if boxSize % 2 == 0 {
|
||||
boxSize += 1
|
||||
}
|
||||
|
||||
return cgImage.blurred(with: boxSize, iterations: iterations, blendColor: color, blendMode: mode).map {
|
||||
UIImage(cgImage: $0, scale: scale, orientation: imageOrientation)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user