Skip to content

Commit bc3dff5

Browse files
authored
Merge pull request #107 from tumblr/stories/aspect-ratio
Add Aspect Ratio setting to resize + crop media
2 parents f53e7f9 + 7ceaa36 commit bc3dff5

File tree

7 files changed

+70
-23
lines changed

7 files changed

+70
-23
lines changed

Classes/Editor/EditorView.swift

+54-18
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
136136

137137
weak var playerView: MediaPlayerView?
138138

139+
var exportSize: CGSize {
140+
let exportView = playerView ?? self
141+
return CGSize(width: exportView.bounds.width * exportView.contentScaleFactor, height: exportView.bounds.height * exportView.contentScaleFactor)
142+
}
143+
139144
private let mainActionMode: MainActionMode
140145
private let confirmButton = UIButton()
141146
private let closeButton = UIButton()
@@ -190,10 +195,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
190195
private lazy var drawingCanvasConstraints: FullViewConstraints = {
191196
return FullViewConstraints(
192197
view: drawingCanvas,
193-
top: drawingCanvas.topAnchor.constraint(equalTo: topAnchor),
194-
bottom: drawingCanvas.bottomAnchor.constraint(equalTo: bottomAnchor),
195-
leading: drawingCanvas.leadingAnchor.constraint(equalTo: leadingAnchor),
196-
trailing: drawingCanvas.trailingAnchor.constraint(equalTo: trailingAnchor)
198+
top: drawingCanvas.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
199+
bottom: drawingCanvas.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor),
200+
leading: drawingCanvas.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
201+
trailing: drawingCanvas.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor)
197202
)
198203
}()
199204

@@ -202,10 +207,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
202207
private lazy var movableViewCanvasConstraints = {
203208
return FullViewConstraints(
204209
view: movableViewCanvas,
205-
top: movableViewCanvas.topAnchor.constraint(equalTo: topAnchor),
206-
bottom: movableViewCanvas.bottomAnchor.constraint(equalTo: bottomAnchor),
207-
leading: movableViewCanvas.leadingAnchor.constraint(equalTo: leadingAnchor),
208-
trailing: movableViewCanvas.trailingAnchor.constraint(equalTo: trailingAnchor)
210+
top: movableViewCanvas.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
211+
bottom: movableViewCanvas.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor),
212+
leading: movableViewCanvas.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
213+
trailing: movableViewCanvas.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor)
209214
)
210215
}()
211216

@@ -225,6 +230,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
225230

226231
weak var delegate: EditorViewDelegate?
227232
private var mediaContentMode: UIView.ContentMode
233+
private var aspectRatio: CGFloat?
228234

229235
@available(*, unavailable, message: "use init() instead")
230236
required public init?(coder aDecoder: NSCoder) {
@@ -242,6 +248,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
242248
showQuickPostButton: Bool,
243249
showBlogSwitcher: Bool,
244250
confirmAtTop: Bool,
251+
aspectRatio: CGFloat?,
245252
quickBlogSelectorCoordinator: KanvasQuickBlogSelectorCoordinating?,
246253
tagCollection: UIView?,
247254
metalContext: MetalContext?,
@@ -258,6 +265,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
258265
self.showQuickPostButton = showQuickPostButton
259266
self.showBlogSwitcher = showBlogSwitcher
260267
self.confirmAtTop = confirmAtTop
268+
self.aspectRatio = aspectRatio
261269
self.quickBlogSelectorCoordinator = quickBlogSelectorCoordinator
262270
self.tagCollection = tagCollection
263271
self.metalContext = metalContext
@@ -330,7 +338,35 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
330338
private func setupPlayer() {
331339
let playerView = MediaPlayerView(metalContext: metalContext, mediaContentMode: mediaContentMode)
332340
playerView.delegate = self
333-
playerView.add(into: self)
341+
342+
if let aspectRatio = aspectRatio {
343+
playerView.layer.masksToBounds = true
344+
playerView.layer.cornerRadius = 12
345+
playerView.translatesAutoresizingMaskIntoConstraints = false
346+
self.addSubview(playerView)
347+
348+
let bottomConstraint: NSLayoutConstraint
349+
let topConstraint: NSLayoutConstraint
350+
if Device.belongsToIPhoneXGroup {
351+
bottomConstraint = playerView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
352+
topConstraint = playerView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor)
353+
} else {
354+
bottomConstraint = playerView.bottomAnchor.constraint(equalTo: bottomAnchor)
355+
topConstraint = playerView.topAnchor.constraint(equalTo: topAnchor)
356+
}
357+
NSLayoutConstraint.activate([
358+
playerView.centerXAnchor.constraint(equalTo: centerXAnchor),
359+
playerView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor),
360+
playerView.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor),
361+
playerView.widthAnchor.constraint(equalTo: playerView.heightAnchor, multiplier: aspectRatio, constant: 0),
362+
topConstraint,
363+
bottomConstraint,
364+
playerView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor)
365+
])
366+
} else {
367+
playerView.add(into: self)
368+
}
369+
334370
self.playerView = playerView
335371
}
336372

@@ -523,7 +559,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
523559

524560
let verticalPositioning: [NSLayoutConstraint]
525561
if confirmAtTop {
526-
verticalPositioning = [collectionContainer.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)]
562+
verticalPositioning = [collectionContainer.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -KanvasEditorDesign.shared.editorViewButtonBottomMargin)]
527563
} else {
528564
verticalPositioning = [collectionContainer.centerYAnchor.constraint(equalTo: confirmOrPostButton().centerYAnchor)]
529565
}
@@ -563,10 +599,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
563599

564600
addSubview(textMenuContainer)
565601
NSLayoutConstraint.activate([
566-
textMenuContainer.leadingAnchor.constraint(equalTo: leadingAnchor),
567-
textMenuContainer.trailingAnchor.constraint(equalTo: trailingAnchor),
568-
textMenuContainer.topAnchor.constraint(equalTo: topAnchor),
569-
textMenuContainer.bottomAnchor.constraint(equalTo: bottomAnchor)
602+
textMenuContainer.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
603+
textMenuContainer.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor),
604+
textMenuContainer.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
605+
textMenuContainer.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor)
570606
])
571607
}
572608

@@ -578,10 +614,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
578614
addSubview(drawingMenuContainer)
579615
drawingMenuContainer.translatesAutoresizingMaskIntoConstraints = false
580616
NSLayoutConstraint.activate([
581-
drawingMenuContainer.leadingAnchor.constraint(equalTo: leadingAnchor),
582-
drawingMenuContainer.trailingAnchor.constraint(equalTo: trailingAnchor),
583-
drawingMenuContainer.topAnchor.constraint(equalTo: topAnchor),
584-
drawingMenuContainer.bottomAnchor.constraint(equalTo: bottomAnchor)
617+
drawingMenuContainer.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
618+
drawingMenuContainer.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor),
619+
drawingMenuContainer.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
620+
drawingMenuContainer.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor)
585621
])
586622
}
587623

Classes/Editor/EditorViewController.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ public final class EditorViewController: UIViewController, MediaPlayerController
241241
showQuickPostButton: settings.showQuickPostButtonInEditor,
242242
showBlogSwitcher: settings.showBlogSwitcherInEditor,
243243
confirmAtTop: settings.features.editorConfirmAtTop,
244+
aspectRatio: settings.aspectRatio,
244245
quickBlogSelectorCoordinator: quickBlogSelectorCoordinator,
245246
tagCollection: tagCollection,
246247
metalContext: metalContext,
@@ -812,7 +813,8 @@ public final class EditorViewController: UIViewController, MediaPlayerController
812813
}
813814

814815
private var exportSize: CGSize? {
815-
return settings.features.scaleMediaToFill ? CGSize(width: editorView.frame.width * editorView.contentScaleFactor, height: editorView.frame.height * editorView.contentScaleFactor) : nil
816+
let exportSize = editorView.exportSize
817+
return settings.features.scaleMediaToFill ? exportSize : nil
816818
}
817819

818820
private func createFinalGIF(segments: [CameraSegment], mediaInfo: MediaInfo, archive: Data, exportAction: KanvasExportAction) {

Classes/Editor/Text/EditorTextController.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,12 @@ final class EditorTextController: UIViewController, EditorTextViewDelegate, Colo
269269
@objc func keyboardWillShow(notification: NSNotification) {
270270
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
271271
let keyboardRectangle = keyboardFrame.cgRectValue
272-
textView.moveToolsUp(distance: keyboardRectangle.height)
272+
273+
let bottom = CGPoint(x: view.frame.minX, y: view.frame.maxY)
274+
let difference = keyboardRectangle.maxY - view.convert(bottom, to: nil).y
275+
276+
let heightDiff = keyboardRectangle.height - difference
277+
textView.moveToolsUp(distance: heightDiff)
273278
}
274279
}
275280

Classes/Settings/CameraSettings.swift

+3
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ public struct CameraFeatures {
312312
/// The Font Selector button uses the currently selected font for its label
313313
public var fontSelectorUsesFont: Bool = DefaultCameraSettings.fontFamilyUsesFont
314314

315+
/// The aspect ratio to pin the Editor View to
316+
public var aspectRatio: CGFloat? = nil
317+
315318
override public init() { }
316319

317320
}

Kanvas.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |spec|
22
spec.name = "Kanvas"
3-
spec.version = "1.2.5"
3+
spec.version = "1.2.6"
44
spec.summary = "A custom camera built for iOS."
55
spec.homepage = "https://github.com/tumblr/kanvas-ios"
66
spec.license = "MPLv2"

KanvasExample/KanvasExampleTests/Editor/EditorViewTests.swift

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ final class EditorViewTests: FBSnapshotTestCase {
3232
showQuickPostButton: false,
3333
showBlogSwitcher: false,
3434
confirmAtTop: false,
35+
aspectRatio: nil,
3536
quickBlogSelectorCoordinator: nil,
3637
tagCollection: nil,
3738
metalContext: nil,

KanvasExample/Podfile.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ PODS:
44
- FBSnapshotTestCase/Core (2.1.4)
55
- FBSnapshotTestCase/SwiftSupport (2.1.4):
66
- FBSnapshotTestCase/Core
7-
- Kanvas (1.2.3)
7+
- Kanvas (1.2.6)
88

99
DEPENDENCIES:
1010
- FBSnapshotTestCase (= 2.1.4)
@@ -20,7 +20,7 @@ EXTERNAL SOURCES:
2020

2121
SPEC CHECKSUMS:
2222
FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a
23-
Kanvas: 97860c54ea07119c533a80d951ee8c1b39d8f386
23+
Kanvas: 828033a062a8df8bd73e6efd1a09ac438ead4b41
2424

2525
PODFILE CHECKSUM: 14b28dd726149c0d01dba9154d5bb095d9ba6a18
2626

0 commit comments

Comments
 (0)