diff --git a/Classes/Editor/EditorView.swift b/Classes/Editor/EditorView.swift index 5c380b354..2116b23c5 100644 --- a/Classes/Editor/EditorView.swift +++ b/Classes/Editor/EditorView.swift @@ -136,6 +136,11 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega weak var playerView: MediaPlayerView? + var exportSize: CGSize { + let exportView = playerView ?? self + return CGSize(width: exportView.bounds.width * exportView.contentScaleFactor, height: exportView.bounds.height * exportView.contentScaleFactor) + } + private let mainActionMode: MainActionMode private let confirmButton = UIButton() private let closeButton = UIButton() @@ -190,10 +195,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega private lazy var drawingCanvasConstraints: FullViewConstraints = { return FullViewConstraints( view: drawingCanvas, - top: drawingCanvas.topAnchor.constraint(equalTo: topAnchor), - bottom: drawingCanvas.bottomAnchor.constraint(equalTo: bottomAnchor), - leading: drawingCanvas.leadingAnchor.constraint(equalTo: leadingAnchor), - trailing: drawingCanvas.trailingAnchor.constraint(equalTo: trailingAnchor) + top: drawingCanvas.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor), + bottom: drawingCanvas.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor), + leading: drawingCanvas.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor), + trailing: drawingCanvas.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor) ) }() @@ -202,10 +207,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega private lazy var movableViewCanvasConstraints = { return FullViewConstraints( view: movableViewCanvas, - top: movableViewCanvas.topAnchor.constraint(equalTo: topAnchor), - bottom: movableViewCanvas.bottomAnchor.constraint(equalTo: bottomAnchor), - leading: movableViewCanvas.leadingAnchor.constraint(equalTo: leadingAnchor), - trailing: movableViewCanvas.trailingAnchor.constraint(equalTo: trailingAnchor) + top: movableViewCanvas.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor), + bottom: movableViewCanvas.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor), + leading: movableViewCanvas.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor), + trailing: movableViewCanvas.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor) ) }() @@ -225,6 +230,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega weak var delegate: EditorViewDelegate? private var mediaContentMode: UIView.ContentMode + private var aspectRatio: CGFloat? @available(*, unavailable, message: "use init() instead") required public init?(coder aDecoder: NSCoder) { @@ -242,6 +248,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega showQuickPostButton: Bool, showBlogSwitcher: Bool, confirmAtTop: Bool, + aspectRatio: CGFloat?, quickBlogSelectorCoordinator: KanvasQuickBlogSelectorCoordinating?, tagCollection: UIView?, metalContext: MetalContext?, @@ -258,6 +265,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega self.showQuickPostButton = showQuickPostButton self.showBlogSwitcher = showBlogSwitcher self.confirmAtTop = confirmAtTop + self.aspectRatio = aspectRatio self.quickBlogSelectorCoordinator = quickBlogSelectorCoordinator self.tagCollection = tagCollection self.metalContext = metalContext @@ -330,7 +338,35 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega private func setupPlayer() { let playerView = MediaPlayerView(metalContext: metalContext, mediaContentMode: mediaContentMode) playerView.delegate = self - playerView.add(into: self) + + if let aspectRatio = aspectRatio { + playerView.layer.masksToBounds = true + playerView.layer.cornerRadius = 12 + playerView.translatesAutoresizingMaskIntoConstraints = false + self.addSubview(playerView) + + let bottomConstraint: NSLayoutConstraint + let topConstraint: NSLayoutConstraint + if Device.belongsToIPhoneXGroup { + bottomConstraint = playerView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor) + topConstraint = playerView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor) + } else { + bottomConstraint = playerView.bottomAnchor.constraint(equalTo: bottomAnchor) + topConstraint = playerView.topAnchor.constraint(equalTo: topAnchor) + } + NSLayoutConstraint.activate([ + playerView.centerXAnchor.constraint(equalTo: centerXAnchor), + playerView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor), + playerView.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor), + playerView.widthAnchor.constraint(equalTo: playerView.heightAnchor, multiplier: aspectRatio, constant: 0), + topConstraint, + bottomConstraint, + playerView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor) + ]) + } else { + playerView.add(into: self) + } + self.playerView = playerView } @@ -523,7 +559,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega let verticalPositioning: [NSLayoutConstraint] if confirmAtTop { - verticalPositioning = [collectionContainer.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)] + verticalPositioning = [collectionContainer.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -KanvasEditorDesign.shared.editorViewButtonBottomMargin)] } else { verticalPositioning = [collectionContainer.centerYAnchor.constraint(equalTo: confirmOrPostButton().centerYAnchor)] } @@ -563,10 +599,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega addSubview(textMenuContainer) NSLayoutConstraint.activate([ - textMenuContainer.leadingAnchor.constraint(equalTo: leadingAnchor), - textMenuContainer.trailingAnchor.constraint(equalTo: trailingAnchor), - textMenuContainer.topAnchor.constraint(equalTo: topAnchor), - textMenuContainer.bottomAnchor.constraint(equalTo: bottomAnchor) + textMenuContainer.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor), + textMenuContainer.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor), + textMenuContainer.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor), + textMenuContainer.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor) ]) } @@ -578,10 +614,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega addSubview(drawingMenuContainer) drawingMenuContainer.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - drawingMenuContainer.leadingAnchor.constraint(equalTo: leadingAnchor), - drawingMenuContainer.trailingAnchor.constraint(equalTo: trailingAnchor), - drawingMenuContainer.topAnchor.constraint(equalTo: topAnchor), - drawingMenuContainer.bottomAnchor.constraint(equalTo: bottomAnchor) + drawingMenuContainer.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor), + drawingMenuContainer.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor), + drawingMenuContainer.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor), + drawingMenuContainer.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor) ]) } diff --git a/Classes/Editor/EditorViewController.swift b/Classes/Editor/EditorViewController.swift index a89440169..40bce8786 100644 --- a/Classes/Editor/EditorViewController.swift +++ b/Classes/Editor/EditorViewController.swift @@ -241,6 +241,7 @@ public final class EditorViewController: UIViewController, MediaPlayerController showQuickPostButton: settings.showQuickPostButtonInEditor, showBlogSwitcher: settings.showBlogSwitcherInEditor, confirmAtTop: settings.features.editorConfirmAtTop, + aspectRatio: settings.aspectRatio, quickBlogSelectorCoordinator: quickBlogSelectorCoordinator, tagCollection: tagCollection, metalContext: metalContext, @@ -812,7 +813,8 @@ public final class EditorViewController: UIViewController, MediaPlayerController } private var exportSize: CGSize? { - return settings.features.scaleMediaToFill ? CGSize(width: editorView.frame.width * editorView.contentScaleFactor, height: editorView.frame.height * editorView.contentScaleFactor) : nil + let exportSize = editorView.exportSize + return settings.features.scaleMediaToFill ? exportSize : nil } private func createFinalGIF(segments: [CameraSegment], mediaInfo: MediaInfo, archive: Data, exportAction: KanvasExportAction) { diff --git a/Classes/Editor/Text/EditorTextController.swift b/Classes/Editor/Text/EditorTextController.swift index eb3f7afc6..153548b50 100644 --- a/Classes/Editor/Text/EditorTextController.swift +++ b/Classes/Editor/Text/EditorTextController.swift @@ -269,7 +269,12 @@ final class EditorTextController: UIViewController, EditorTextViewDelegate, Colo @objc func keyboardWillShow(notification: NSNotification) { if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue { let keyboardRectangle = keyboardFrame.cgRectValue - textView.moveToolsUp(distance: keyboardRectangle.height) + + let bottom = CGPoint(x: view.frame.minX, y: view.frame.maxY) + let difference = keyboardRectangle.maxY - view.convert(bottom, to: nil).y + + let heightDiff = keyboardRectangle.height - difference + textView.moveToolsUp(distance: heightDiff) } } diff --git a/Classes/Settings/CameraSettings.swift b/Classes/Settings/CameraSettings.swift index 0b38e3ce3..ead7f7290 100644 --- a/Classes/Settings/CameraSettings.swift +++ b/Classes/Settings/CameraSettings.swift @@ -312,6 +312,9 @@ public struct CameraFeatures { /// The Font Selector button uses the currently selected font for its label public var fontSelectorUsesFont: Bool = DefaultCameraSettings.fontFamilyUsesFont + /// The aspect ratio to pin the Editor View to + public var aspectRatio: CGFloat? = nil + override public init() { } } diff --git a/Kanvas.podspec b/Kanvas.podspec index 3761eb2e7..9afc5235b 100644 --- a/Kanvas.podspec +++ b/Kanvas.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = "Kanvas" - spec.version = "1.2.5" + spec.version = "1.2.6" spec.summary = "A custom camera built for iOS." spec.homepage = "https://github.com/tumblr/kanvas-ios" spec.license = "MPLv2" diff --git a/KanvasExample/KanvasExampleTests/Editor/EditorViewTests.swift b/KanvasExample/KanvasExampleTests/Editor/EditorViewTests.swift index 4861947f4..9039df9eb 100644 --- a/KanvasExample/KanvasExampleTests/Editor/EditorViewTests.swift +++ b/KanvasExample/KanvasExampleTests/Editor/EditorViewTests.swift @@ -32,6 +32,7 @@ final class EditorViewTests: FBSnapshotTestCase { showQuickPostButton: false, showBlogSwitcher: false, confirmAtTop: false, + aspectRatio: nil, quickBlogSelectorCoordinator: nil, tagCollection: nil, metalContext: nil, diff --git a/KanvasExample/Podfile.lock b/KanvasExample/Podfile.lock index 11ecfdb6e..c2725dd07 100644 --- a/KanvasExample/Podfile.lock +++ b/KanvasExample/Podfile.lock @@ -4,7 +4,7 @@ PODS: - FBSnapshotTestCase/Core (2.1.4) - FBSnapshotTestCase/SwiftSupport (2.1.4): - FBSnapshotTestCase/Core - - Kanvas (1.2.3) + - Kanvas (1.2.6) DEPENDENCIES: - FBSnapshotTestCase (= 2.1.4) @@ -20,7 +20,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a - Kanvas: 97860c54ea07119c533a80d951ee8c1b39d8f386 + Kanvas: 828033a062a8df8bd73e6efd1a09ac438ead4b41 PODFILE CHECKSUM: 14b28dd726149c0d01dba9154d5bb095d9ba6a18