mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
8fd19d35bb
commit
c178c19f88
@ -0,0 +1,105 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class CropScrollView: UIScrollView, UIScrollViewDelegate {
|
||||||
|
private var contentView: UIView?
|
||||||
|
|
||||||
|
public var updated: (CGPoint, CGFloat) -> Void = { _, _ in }
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.backgroundColor = .clear
|
||||||
|
self.showsVerticalScrollIndicator = false
|
||||||
|
self.showsHorizontalScrollIndicator = false
|
||||||
|
self.contentInsetAdjustmentBehavior = .never
|
||||||
|
|
||||||
|
self.clipsToBounds = false
|
||||||
|
self.bouncesZoom = true
|
||||||
|
self.delegate = self
|
||||||
|
self.decelerationRate = .fast
|
||||||
|
|
||||||
|
let transparentView = UIView(frame: bounds)
|
||||||
|
transparentView.backgroundColor = .clear
|
||||||
|
transparentView.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
self.addSubview(transparentView)
|
||||||
|
self.contentView = transparentView
|
||||||
|
|
||||||
|
self.minimumZoomScale = 1.0
|
||||||
|
self.maximumZoomScale = 4.0
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
guard let contentView = self.contentView else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let boundsSize = bounds.size
|
||||||
|
var frameToCenter = contentView.frame
|
||||||
|
|
||||||
|
if frameToCenter.size.width < boundsSize.width {
|
||||||
|
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2
|
||||||
|
} else {
|
||||||
|
frameToCenter.origin.x = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if frameToCenter.size.height < boundsSize.height {
|
||||||
|
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2
|
||||||
|
} else {
|
||||||
|
frameToCenter.origin.y = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
contentView.frame = frameToCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
func setContentSize(_ size: CGSize) {
|
||||||
|
self.contentView?.frame = CGRect(origin: .zero, size: size)
|
||||||
|
self.contentSize = size
|
||||||
|
|
||||||
|
self.zoom(to: CGRect(origin: CGPoint(x: floor((size.width - self.bounds.width) / 2.0), y: floor((size.height - self.bounds.height) / 2.0)), size: self.bounds.size), animated: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func notify() {
|
||||||
|
let currentScale = self.zoomScale
|
||||||
|
let contentOffset = self.contentOffset
|
||||||
|
let centerOffset = CGPoint(
|
||||||
|
x: -1.0 * (contentOffset.x + self.bounds.width / 2.0 - self.contentSize.width / 2.0),
|
||||||
|
y: -1.0 * (contentOffset.y + self.bounds.height / 2.0 - self.contentSize.height / 2.0)
|
||||||
|
)
|
||||||
|
self.updated(centerOffset, currentScale)
|
||||||
|
}
|
||||||
|
|
||||||
|
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
|
||||||
|
return self.contentView
|
||||||
|
}
|
||||||
|
|
||||||
|
func scrollViewDidZoom(_ scrollView: UIScrollView) {
|
||||||
|
self.setNeedsLayout()
|
||||||
|
self.layoutIfNeeded()
|
||||||
|
self.notify()
|
||||||
|
}
|
||||||
|
|
||||||
|
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
|
self.notify()
|
||||||
|
}
|
||||||
|
|
||||||
|
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
|
||||||
|
self.notify()
|
||||||
|
}
|
||||||
|
|
||||||
|
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
||||||
|
if !decelerate {
|
||||||
|
self.notify()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
||||||
|
self.notify()
|
||||||
|
}
|
||||||
|
}
|
@ -2783,6 +2783,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
private let gradientView: UIImageView
|
private let gradientView: UIImageView
|
||||||
private var gradientColorsDisposable: Disposable?
|
private var gradientColorsDisposable: Disposable?
|
||||||
|
|
||||||
|
fileprivate var cropScrollView: CropScrollView?
|
||||||
fileprivate var stickerBackgroundView: UIImageView?
|
fileprivate var stickerBackgroundView: UIImageView?
|
||||||
private var stickerOverlayLayer: SimpleShapeLayer?
|
private var stickerOverlayLayer: SimpleShapeLayer?
|
||||||
private var stickerFrameLayer: SimpleShapeLayer?
|
private var stickerFrameLayer: SimpleShapeLayer?
|
||||||
@ -2799,6 +2800,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
|
|
||||||
var mediaEditor: MediaEditor?
|
var mediaEditor: MediaEditor?
|
||||||
fileprivate var mediaEditorPromise = Promise<MediaEditor?>()
|
fileprivate var mediaEditorPromise = Promise<MediaEditor?>()
|
||||||
|
private var mediaEntityInitialValues: (position: CGPoint, scale: CGFloat, rotation: CGFloat)?
|
||||||
|
|
||||||
let ciContext = CIContext(options: [.workingColorSpace : NSNull()])
|
let ciContext = CIContext(options: [.workingColorSpace : NSNull()])
|
||||||
|
|
||||||
@ -2967,6 +2969,17 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
let stickerBackgroundView = UIImageView()
|
let stickerBackgroundView = UIImageView()
|
||||||
self.stickerBackgroundView = stickerBackgroundView
|
self.stickerBackgroundView = stickerBackgroundView
|
||||||
self.previewContainerView.addSubview(stickerBackgroundView)
|
self.previewContainerView.addSubview(stickerBackgroundView)
|
||||||
|
|
||||||
|
let cropScrollView = CropScrollView(frame: .zero)
|
||||||
|
cropScrollView.updated = { [weak self] position, scale in
|
||||||
|
guard let self, let mediaEntityView = self.entitiesView.getView(where: { $0 is DrawingMediaEntityView }) as? DrawingMediaEntityView, let mediaEntity = mediaEntityView.entity as? DrawingMediaEntity, let (initialPosition, initialScale, _) = self.mediaEntityInitialValues else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mediaEntity.position = initialPosition.offsetBy(dx: position.x * initialScale, dy: position.y * initialScale)
|
||||||
|
mediaEntity.scale = initialScale * scale
|
||||||
|
mediaEntityView.update(animated: false)
|
||||||
|
}
|
||||||
|
self.cropScrollView = cropScrollView
|
||||||
case .coverEditor:
|
case .coverEditor:
|
||||||
let stickerBackgroundView = UIImageView()
|
let stickerBackgroundView = UIImageView()
|
||||||
self.stickerBackgroundView = stickerBackgroundView
|
self.stickerBackgroundView = stickerBackgroundView
|
||||||
@ -3199,6 +3212,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
let initialPosition = mediaEntity.position
|
let initialPosition = mediaEntity.position
|
||||||
let initialScale = mediaEntity.scale
|
let initialScale = mediaEntity.scale
|
||||||
let initialRotation = mediaEntity.rotation
|
let initialRotation = mediaEntity.rotation
|
||||||
|
self.mediaEntityInitialValues = (initialPosition, initialScale, initialRotation)
|
||||||
|
|
||||||
if isFromCamera && mediaDimensions.width > mediaDimensions.height {
|
if isFromCamera && mediaDimensions.width > mediaDimensions.height {
|
||||||
mediaEntity.scale = storyDimensions.height / fittedSize.height
|
mediaEntity.scale = storyDimensions.height / fittedSize.height
|
||||||
@ -5916,14 +5930,21 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
transition.setFrame(view: self.selectionContainerView, frame: CGRect(origin: .zero, size: previewFrame.size))
|
transition.setFrame(view: self.selectionContainerView, frame: CGRect(origin: .zero, size: previewFrame.size))
|
||||||
|
|
||||||
if let stickerBackgroundView = self.stickerBackgroundView, let stickerOverlayLayer = self.stickerOverlayLayer, let stickerFrameLayer = self.stickerFrameLayer {
|
if let stickerBackgroundView = self.stickerBackgroundView, let stickerOverlayLayer = self.stickerOverlayLayer, let stickerFrameLayer = self.stickerFrameLayer {
|
||||||
var stickerFrameFraction: CGFloat = 1.0
|
let stickerFrameFraction: CGFloat
|
||||||
if case .avatarEditor = controller.mode {
|
switch controller.mode {
|
||||||
|
case .avatarEditor, .stickerEditor:
|
||||||
stickerFrameFraction = 0.97
|
stickerFrameFraction = 0.97
|
||||||
|
default:
|
||||||
|
stickerFrameFraction = 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let stickerFrameWidth = floorToScreenPixels(previewSize.width * stickerFrameFraction)
|
let stickerFrameWidth = floorToScreenPixels(previewSize.width * stickerFrameFraction)
|
||||||
stickerOverlayLayer.frame = CGRect(origin: .zero, size: previewSize)
|
stickerOverlayLayer.frame = CGRect(origin: .zero, size: previewSize)
|
||||||
|
|
||||||
let stickerFrameRect = CGRect(origin: CGPoint(x: floorToScreenPixels((previewSize.width - stickerFrameWidth) / 2.0), y: floorToScreenPixels((previewSize.height - stickerFrameWidth) / 2.0)), size: CGSize(width: stickerFrameWidth, height: stickerFrameWidth))
|
let stickerFrameRect = CGRect(
|
||||||
|
origin: CGPoint(x: floorToScreenPixels((previewSize.width - stickerFrameWidth) / 2.0), y: floorToScreenPixels((previewSize.height - stickerFrameWidth) / 2.0)),
|
||||||
|
size: CGSize(width: stickerFrameWidth, height: stickerFrameWidth)
|
||||||
|
)
|
||||||
|
|
||||||
let overlayOuterRect = UIBezierPath(rect: CGRect(origin: .zero, size: previewSize))
|
let overlayOuterRect = UIBezierPath(rect: CGRect(origin: .zero, size: previewSize))
|
||||||
let overlayInnerRect: UIBezierPath
|
let overlayInnerRect: UIBezierPath
|
||||||
@ -5951,6 +5972,19 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
|
|
||||||
transition.setFrame(view: stickerBackgroundView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((previewSize.width - stickerFrameWidth) / 2.0), y: floorToScreenPixels((previewSize.height - stickerFrameWidth) / 2.0)), size: CGSize(width: stickerFrameWidth, height: stickerFrameWidth)))
|
transition.setFrame(view: stickerBackgroundView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((previewSize.width - stickerFrameWidth) / 2.0), y: floorToScreenPixels((previewSize.height - stickerFrameWidth) / 2.0)), size: CGSize(width: stickerFrameWidth, height: stickerFrameWidth)))
|
||||||
stickerBackgroundView.layer.cornerRadius = stickerFrameWidth / 8.0
|
stickerBackgroundView.layer.cornerRadius = stickerFrameWidth / 8.0
|
||||||
|
|
||||||
|
let cropScrollRect = CGSize(width: previewSize.width, height: previewSize.width).centered(around: stickerFrameRect.center)
|
||||||
|
if let cropScrollView = self.cropScrollView {
|
||||||
|
cropScrollView.frame = cropScrollRect
|
||||||
|
if cropScrollView.superview == nil {
|
||||||
|
self.previewContainerView.addSubview(cropScrollView)
|
||||||
|
|
||||||
|
if let dimensions = self.subject?.dimensions {
|
||||||
|
let filledCropSize = dimensions.cgSize.aspectFilled(CGSize(width: previewSize.width, height: previewSize.width))
|
||||||
|
cropScrollView.setContentSize(filledCropSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.interaction?.containerLayoutUpdated(layout: layout, transition: transition)
|
self.interaction?.containerLayoutUpdated(layout: layout, transition: transition)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user