forked from euwars/browser-ios
-
Notifications
You must be signed in to change notification settings - Fork 1
/
UIViewExtensions.swift
94 lines (80 loc) · 3.19 KB
/
UIViewExtensions.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Foundation
extension UIView {
/**
* Takes a screenshot of the view with the given size.
*/
func screenshot(_ size: CGSize, offset: CGPoint? = nil, quality: CGFloat = 1) -> UIImage? {
assert(0...1 ~= quality)
let offset = offset ?? CGPoint(x: 0, y: 0)
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale * quality)
drawHierarchy(in: CGRect(origin: offset, size: frame.size), afterScreenUpdates: false)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
/**
* Takes a screenshot of the view with the given aspect ratio.
* An aspect ratio of 0 means capture the entire view.
*/
func screenshot(_ aspectRatio: CGFloat = 0, offset: CGPoint? = nil, quality: CGFloat = 1) -> UIImage? {
assert(aspectRatio >= 0)
var size: CGSize
if aspectRatio > 0 {
size = CGSize()
let viewAspectRatio = frame.width / frame.height
if viewAspectRatio > aspectRatio {
size.height = frame.height
size.width = size.height * aspectRatio
} else {
size.width = frame.width
size.height = size.width / aspectRatio
}
} else {
size = frame.size
}
return screenshot(size, offset: offset, quality: quality)
}
/*
* Performs a deep copy of the view. Does not copy constraints.
*/
func clone() -> UIView {
let data = NSKeyedArchiver.archivedData(withRootObject: self)
return NSKeyedUnarchiver.unarchiveObject(with: data) as! UIView
}
/**
* rounds the requested corners of a view with the provided radius
*/
func addRoundedCorners(_ cornersToRound: UIRectCorner, cornerRadius: CGSize, color: UIColor) {
let rect = bounds
let maskPath = UIBezierPath(roundedRect: rect, byRoundingCorners: cornersToRound, cornerRadii: cornerRadius)
// Create the shape layer and set its path
let maskLayer = CAShapeLayer()
maskLayer.frame = rect
maskLayer.path = maskPath.cgPath
let roundedLayer = CALayer()
roundedLayer.backgroundColor = color.cgColor
roundedLayer.frame = rect
roundedLayer.mask = maskLayer
layer.insertSublayer(roundedLayer, at: 0)
backgroundColor = UIColor.clear
}
/**
This allows us to find the view in a current view hierarchy that is currently the first responder
*/
static func findSubViewWithFirstResponder(_ view: UIView) -> UIView? {
let subviews = view.subviews
if subviews.count == 0 {
return nil
}
for subview: UIView in subviews {
if subview.isFirstResponder {
return subview
}
return findSubViewWithFirstResponder(subview)
}
return nil
}
}