Minimize use of implicitly unwrapped optionals in code.
And mark `init(coder:)` as unavailable.
This commit is contained in:
parent
09048dad07
commit
45db3a963e
@ -562,7 +562,7 @@ private class TitleView: UIView {
|
||||
|
||||
private let label = UILabel()
|
||||
private let iconView = UIImageView()
|
||||
private var stackView: UIStackView!
|
||||
private let stackView: UIStackView
|
||||
|
||||
// Returns same font as UIBarButtonItem uses.
|
||||
private func titleLabelFont() -> UIFont {
|
||||
@ -573,18 +573,10 @@ private class TitleView: UIView {
|
||||
// MARK: - Initializers
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
stackView = UIStackView(arrangedSubviews: [label, iconView])
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
stackView.axis = .horizontal
|
||||
stackView.alignment = .center
|
||||
stackView.spacing = 5
|
||||
@ -605,6 +597,11 @@ private class TitleView: UIView {
|
||||
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(titleTapped)))
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(frame:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
override func tintColorDidChange() {
|
||||
super.tintColorDidChange()
|
||||
label.textColor = tintColor
|
||||
|
||||
@ -40,8 +40,8 @@ class CameraCaptureControl: UIView {
|
||||
private static let shutterButtonDefaultSize: CGFloat = 72
|
||||
private static let shutterButtonRecordingSize: CGFloat = 122
|
||||
|
||||
private var outerCircleSizeConstraint: NSLayoutConstraint!
|
||||
private var innerCircleSizeConstraint: NSLayoutConstraint!
|
||||
private let outerCircleSizeConstraint: NSLayoutConstraint
|
||||
private let innerCircleSizeConstraint: NSLayoutConstraint
|
||||
private var slidingCircleHPositionConstraint: NSLayoutConstraint!
|
||||
private var slidingCircleVPositionConstraint: NSLayoutConstraint!
|
||||
|
||||
@ -67,23 +67,13 @@ class CameraCaptureControl: UIView {
|
||||
|
||||
weak var delegate: CameraCaptureControlDelegate?
|
||||
|
||||
convenience init(axis: NSLayoutConstraint.Axis) {
|
||||
self.init(frame: CGRect(origin: .zero, size: CameraCaptureControl.intrinsicContentSize(forAxis: axis)))
|
||||
required init(axis: NSLayoutConstraint.Axis) {
|
||||
innerCircleSizeConstraint = shutterButtonInnerCircle.autoSetDimension(.width, toSize: CameraCaptureControl.shutterButtonDefaultSize)
|
||||
outerCircleSizeConstraint = shutterButtonOuterCircle.autoSetDimension(.width, toSize: CameraCaptureControl.shutterButtonDefaultSize)
|
||||
|
||||
super.init(frame: CGRect(origin: .zero, size: CameraCaptureControl.intrinsicContentSize(forAxis: axis)))
|
||||
|
||||
self.axis = axis
|
||||
reactivateConstraintsForCurrentAxis()
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
|
||||
// Round Shutter Button
|
||||
addLayoutGuide(shutterButtonLayoutGuide)
|
||||
@ -104,11 +94,9 @@ class CameraCaptureControl: UIView {
|
||||
addSubview(shutterButtonOuterCircle)
|
||||
shutterButtonOuterCircle.centerXAnchor.constraint(equalTo: shutterButtonLayoutGuide.centerXAnchor).isActive = true
|
||||
shutterButtonOuterCircle.centerYAnchor.constraint(equalTo: shutterButtonLayoutGuide.centerYAnchor).isActive = true
|
||||
outerCircleSizeConstraint = shutterButtonOuterCircle.autoSetDimension(.width, toSize: CameraCaptureControl.shutterButtonDefaultSize)
|
||||
shutterButtonOuterCircle.autoPin(toAspectRatio: 1)
|
||||
|
||||
addSubview(shutterButtonInnerCircle)
|
||||
innerCircleSizeConstraint = shutterButtonInnerCircle.autoSetDimension(.width, toSize: CameraCaptureControl.shutterButtonDefaultSize)
|
||||
shutterButtonInnerCircle.autoPin(toAspectRatio: 1)
|
||||
shutterButtonInnerCircle.isUserInteractionEnabled = false
|
||||
shutterButtonInnerCircle.backgroundColor = .clear
|
||||
@ -119,13 +107,18 @@ class CameraCaptureControl: UIView {
|
||||
|
||||
// The long press handles both the tap and the hold interaction, as well as the animation
|
||||
// the presents as the user begins to hold (and the button begins to grow prior to recording)
|
||||
longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
|
||||
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
|
||||
longPressGesture.minimumPressDuration = 0
|
||||
shutterButtonOuterCircle.addGestureRecognizer(longPressGesture)
|
||||
|
||||
reactivateConstraintsForCurrentAxis()
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(axis:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
// MARK: - UI State
|
||||
|
||||
enum State {
|
||||
@ -154,12 +147,13 @@ class CameraCaptureControl: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
func setState(_ state: State, animationDuration: TimeInterval = 0) {
|
||||
func setState(_ state: State, isRecordingWithLongPress: Bool = false, animationDuration: TimeInterval = 0) {
|
||||
guard _internalState != state else { return }
|
||||
|
||||
Logger.debug("New state: \(_internalState) -> \(state)")
|
||||
|
||||
_internalState = state
|
||||
self.isRecordingWithLongPress = isRecordingWithLongPress
|
||||
if animationDuration > 0 {
|
||||
UIView.animate(withDuration: animationDuration,
|
||||
delay: 0,
|
||||
@ -190,12 +184,11 @@ class CameraCaptureControl: UIView {
|
||||
|
||||
case .recording:
|
||||
prepareRecordingControlsIfNecessary()
|
||||
let recordingWithLongPress = longPressGesture.state != .possible
|
||||
let sliderProgress = recordingWithLongPress ? sliderTrackingProgress : 0
|
||||
let sliderProgress = isRecordingWithLongPress ? sliderTrackingProgress : 0
|
||||
// element visibility
|
||||
stopButton.isHidden = sliderProgress == 0
|
||||
slidingCircleView.isHidden = sliderProgress == 0
|
||||
lockIconView.isHidden = !recordingWithLongPress
|
||||
lockIconView.isHidden = !isRecordingWithLongPress
|
||||
lockIconView.setState(sliderProgress > 0.5 ? .locking : .unlocked, animated: true)
|
||||
shutterButtonInnerCircle.backgroundColor = .ows_white
|
||||
// element sizes
|
||||
@ -307,7 +300,7 @@ class CameraCaptureControl: UIView {
|
||||
|
||||
// MARK: - Gestures
|
||||
|
||||
private var longPressGesture: UILongPressGestureRecognizer!
|
||||
private var isRecordingWithLongPress = false
|
||||
private static let longPressDurationThreshold = 0.5
|
||||
private static let minDistanceBeforeActivatingLockSlider: CGFloat = 30
|
||||
private var initialTouchLocation: CGPoint?
|
||||
@ -340,7 +333,7 @@ class CameraCaptureControl: UIView {
|
||||
) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.setState(.recording, animationDuration: 0.4)
|
||||
self.setState(.recording, isRecordingWithLongPress: true, animationDuration: 0.4)
|
||||
|
||||
self.delegate?.cameraCaptureControlDidRequestStartVideoRecording(self)
|
||||
}
|
||||
@ -471,10 +464,10 @@ class CameraCaptureControl: UIView {
|
||||
|
||||
private class LockView: UIView {
|
||||
|
||||
private var imageViewLock = UIImageView(image: UIImage(named: "media-composer-lock-outline-24"))
|
||||
private var blurBackgroundView = CircleBlurView(effect: UIBlurEffect(style: .dark))
|
||||
private var whiteBackgroundView = CircleView()
|
||||
private var whiteCircleView = CircleView()
|
||||
private let imageViewLock = UIImageView(image: UIImage(named: "media-composer-lock-outline-24"))
|
||||
private let blurBackgroundView = CircleBlurView(effect: UIBlurEffect(style: .dark))
|
||||
private let whiteBackgroundView = CircleView()
|
||||
private let whiteCircleView = CircleView()
|
||||
|
||||
enum State {
|
||||
case unlocked
|
||||
@ -531,15 +524,7 @@ private class LockView: UIView {
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
isUserInteractionEnabled = false
|
||||
|
||||
addSubview(blurBackgroundView)
|
||||
@ -562,6 +547,11 @@ private class LockView: UIView {
|
||||
updateAppearance()
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(frame:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
CGSize(width: CameraCaptureControl.recordingLockControlSize, height: CameraCaptureControl.recordingLockControlSize)
|
||||
}
|
||||
@ -621,7 +611,11 @@ class CameraOverlayButton: UIButton, UserInterfaceStyleOverride {
|
||||
}
|
||||
}
|
||||
|
||||
private var backgroundView: UIVisualEffectView!
|
||||
private let backgroundView: CircleBlurView = {
|
||||
let view = CircleBlurView(effect: UIBlurEffect(style: .regular))
|
||||
view.isUserInteractionEnabled = false
|
||||
return view
|
||||
}()
|
||||
|
||||
private static let visibleButtonSize: CGFloat = 36 // both height and width
|
||||
private static let defaultInset: CGFloat = 4
|
||||
@ -632,32 +626,28 @@ class CameraOverlayButton: UIButton, UserInterfaceStyleOverride {
|
||||
}
|
||||
}
|
||||
|
||||
convenience init(image: UIImage?, userInterfaceStyleOverride: UIUserInterfaceStyle = .unspecified) {
|
||||
self.init(frame: CGRect(origin: .zero, size: .square(Self.visibleButtonSize + 2*Self.defaultInset)))
|
||||
required init(image: UIImage?, userInterfaceStyleOverride: UIUserInterfaceStyle = .unspecified) {
|
||||
super.init(frame: CGRect(origin: .zero, size: .square(Self.visibleButtonSize + 2*Self.defaultInset)))
|
||||
|
||||
self.userInterfaceStyleOverride = userInterfaceStyleOverride
|
||||
|
||||
layoutMargins = contentInsets
|
||||
|
||||
addSubview(backgroundView)
|
||||
backgroundView.autoPinEdgesToSuperviewMargins()
|
||||
|
||||
setImage(image, for: .normal)
|
||||
updateStyle()
|
||||
}
|
||||
|
||||
private override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
@available(*, unavailable, message: "Use init(image:userInterfaceStyleOverride:) instead")
|
||||
override init(frame: CGRect) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(image:userInterfaceStyleOverride:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
layoutMargins = contentInsets
|
||||
|
||||
backgroundView = CircleBlurView(effect: UIBlurEffect(style: CameraOverlayButton.blurEffectStyle(for: effectiveUserInterfaceStyle)))
|
||||
backgroundView.isUserInteractionEnabled = false
|
||||
addSubview(backgroundView)
|
||||
backgroundView.autoPinEdgesToSuperviewMargins()
|
||||
|
||||
updateStyle()
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
@ -700,14 +690,8 @@ class MediaDoneButton: UIButton, UserInterfaceStyleOverride {
|
||||
}
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
private static var font: UIFont {
|
||||
return UIFont.ows_dynamicTypeSubheadline.ows_monospaced
|
||||
}
|
||||
|
||||
private let numberFormatter: NumberFormatter = {
|
||||
@ -720,22 +704,38 @@ class MediaDoneButton: UIButton, UserInterfaceStyleOverride {
|
||||
let label = UILabel()
|
||||
label.textColor = .ows_white
|
||||
label.textAlignment = .center
|
||||
label.font = .ows_dynamicTypeSubheadline.ows_monospaced
|
||||
label.font = MediaDoneButton.font
|
||||
return label
|
||||
}()
|
||||
private var pillView: PillView!
|
||||
private var blurBackgroundView: UIVisualEffectView!
|
||||
private var chevronImageView: UIImageView!
|
||||
private var dimmerView: UIView!
|
||||
|
||||
private func commonInit() {
|
||||
pillView = PillView(frame: bounds)
|
||||
private let pillView: PillView = {
|
||||
let pillView = PillView(frame: .zero)
|
||||
pillView.isUserInteractionEnabled = false
|
||||
pillView.layoutMargins = UIEdgeInsets(hMargin: 8, vMargin: 7)
|
||||
return pillView
|
||||
}()
|
||||
private let blurBackgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
|
||||
private let chevronImageView: UIImageView = {
|
||||
let image: UIImage?
|
||||
if #available(iOS 13, *) {
|
||||
image = CurrentAppContext().isRTL ? UIImage(systemName: "chevron.backward") : UIImage(systemName: "chevron.right")
|
||||
} else {
|
||||
image = CurrentAppContext().isRTL ? UIImage(named: "chevron-left-20") : UIImage(named: "chevron-right-20")
|
||||
}
|
||||
let chevronImageView = UIImageView(image: image!.withRenderingMode(.alwaysTemplate))
|
||||
chevronImageView.contentMode = .center
|
||||
if #available(iOS 13, *) {
|
||||
chevronImageView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(pointSize: MediaDoneButton.font.pointSize)
|
||||
}
|
||||
return chevronImageView
|
||||
}()
|
||||
private var dimmerView: UIView?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
addSubview(pillView)
|
||||
pillView.autoPinEdgesToSuperviewEdges()
|
||||
|
||||
blurBackgroundView = UIVisualEffectView(effect: UIBlurEffect(style: MediaDoneButton.blurEffectStyle(for: effectiveUserInterfaceStyle)))
|
||||
pillView.addSubview(blurBackgroundView)
|
||||
blurBackgroundView.autoPinEdgesToSuperviewEdges()
|
||||
|
||||
@ -745,18 +745,6 @@ class MediaDoneButton: UIButton, UserInterfaceStyleOverride {
|
||||
blueBadgeView.addSubview(textLabel)
|
||||
textLabel.autoPinEdgesToSuperviewMargins()
|
||||
|
||||
let image: UIImage?
|
||||
if #available(iOS 13, *) {
|
||||
image = CurrentAppContext().isRTL ? UIImage(systemName: "chevron.backward") : UIImage(systemName: "chevron.right")
|
||||
} else {
|
||||
image = CurrentAppContext().isRTL ? UIImage(named: "chevron-left-20") : UIImage(named: "chevron-right-20")
|
||||
}
|
||||
chevronImageView = UIImageView(image: image!.withRenderingMode(.alwaysTemplate))
|
||||
chevronImageView.contentMode = .center
|
||||
if #available(iOS 13, *) {
|
||||
chevronImageView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(pointSize: textLabel.font.pointSize)
|
||||
}
|
||||
|
||||
let hStack = UIStackView(arrangedSubviews: [blueBadgeView, chevronImageView])
|
||||
hStack.spacing = 6
|
||||
pillView.addSubview(hStack)
|
||||
@ -765,6 +753,11 @@ class MediaDoneButton: UIButton, UserInterfaceStyleOverride {
|
||||
updateStyle()
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(frame:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
if traitCollection.preferredContentSizeCategory != previousTraitCollection?.preferredContentSizeCategory {
|
||||
textLabel.font = .ows_dynamicTypeSubheadline.ows_monospaced
|
||||
@ -781,13 +774,14 @@ class MediaDoneButton: UIButton, UserInterfaceStyleOverride {
|
||||
didSet {
|
||||
if isHighlighted {
|
||||
if dimmerView == nil {
|
||||
dimmerView = UIView(frame: bounds)
|
||||
let dimmerView = UIView(frame: bounds)
|
||||
dimmerView.isUserInteractionEnabled = false
|
||||
dimmerView.backgroundColor = .ows_black
|
||||
pillView.addSubview(dimmerView)
|
||||
dimmerView.autoPinEdgesToSuperviewEdges()
|
||||
self.dimmerView = dimmerView
|
||||
}
|
||||
dimmerView.alpha = 0.5
|
||||
dimmerView?.alpha = 0.5
|
||||
} else if let dimmerView = dimmerView {
|
||||
dimmerView.alpha = 0
|
||||
}
|
||||
|
||||
@ -707,45 +707,38 @@ private struct ButtonImages {
|
||||
}
|
||||
|
||||
private class TopBar: UIView {
|
||||
private(set) var closeButton: CameraOverlayButton!
|
||||
let closeButton = CameraOverlayButton(image: ButtonImages.close, userInterfaceStyleOverride: .dark)
|
||||
|
||||
private var cameraControlsContainerView: UIView!
|
||||
private(set) var flashModeButton: CameraOverlayButton!
|
||||
private(set) var batchModeButton: CameraOverlayButton!
|
||||
private let cameraControlsContainerView: UIStackView
|
||||
let flashModeButton = CameraOverlayButton(image: ButtonImages.flashAuto, userInterfaceStyleOverride: .dark)
|
||||
let batchModeButton = CameraOverlayButton(image: ButtonImages.flashAuto, userInterfaceStyleOverride: .dark)
|
||||
|
||||
private(set) var recordingTimerView: RecordingTimerView!
|
||||
let recordingTimerView = RecordingTimerView(frame: .zero)
|
||||
|
||||
override init(frame: CGRect) {
|
||||
cameraControlsContainerView = UIStackView(arrangedSubviews: [ batchModeButton, flashModeButton ])
|
||||
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
layoutMargins = UIEdgeInsets(hMargin: 8, vMargin: 4)
|
||||
|
||||
closeButton = CameraOverlayButton(image: ButtonImages.close, userInterfaceStyleOverride: .dark)
|
||||
addSubview(closeButton)
|
||||
closeButton.autoPinHeightToSuperviewMargins()
|
||||
closeButton.autoPinLeadingToSuperviewMargin()
|
||||
|
||||
recordingTimerView = RecordingTimerView(frame: .zero)
|
||||
addSubview(recordingTimerView)
|
||||
recordingTimerView.autoPinHeightToSuperview(withMargin: 8)
|
||||
recordingTimerView.autoHCenterInSuperview()
|
||||
|
||||
flashModeButton = CameraOverlayButton(image: ButtonImages.flashAuto, userInterfaceStyleOverride: .dark)
|
||||
batchModeButton = CameraOverlayButton(image: ButtonImages.batchModeOff, userInterfaceStyleOverride: .dark)
|
||||
let stackView = UIStackView(arrangedSubviews: [ batchModeButton, flashModeButton ])
|
||||
stackView.spacing = 16
|
||||
addSubview(stackView)
|
||||
stackView.autoPinHeightToSuperviewMargins()
|
||||
stackView.autoPinTrailingToSuperviewMargin()
|
||||
cameraControlsContainerView = stackView
|
||||
cameraControlsContainerView.spacing = 16
|
||||
addSubview(cameraControlsContainerView)
|
||||
cameraControlsContainerView.autoPinHeightToSuperviewMargins()
|
||||
cameraControlsContainerView.autoPinTrailingToSuperviewMargin()
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(frame:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
// MARK: - Mode
|
||||
@ -760,12 +753,12 @@ private class TopBar: UIView {
|
||||
case .cameraControls:
|
||||
closeButton.isHidden = false
|
||||
cameraControlsContainerView.isHidden = false
|
||||
recordingTimerView?.isHidden = true
|
||||
recordingTimerView.isHidden = true
|
||||
|
||||
case .closeButton:
|
||||
closeButton.isHidden = false
|
||||
cameraControlsContainerView.isHidden = true
|
||||
recordingTimerView?.isHidden = true
|
||||
recordingTimerView.isHidden = true
|
||||
|
||||
case .videoRecording:
|
||||
closeButton.isHidden = true
|
||||
@ -793,47 +786,36 @@ private class BottomBar: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
private(set) var photoLibraryButton: MediaPickerThumbnailButton!
|
||||
private(set) var switchCameraButton: CameraOverlayButton!
|
||||
let photoLibraryButton = MediaPickerThumbnailButton(frame: .zero)
|
||||
let switchCameraButton = CameraOverlayButton(image: ButtonImages.switchCamera, userInterfaceStyleOverride: .dark)
|
||||
let controlButtonsLayoutGuide = UILayoutGuide() // area encompassing Photo Library and Switch Camera buttons.
|
||||
|
||||
private(set) var captureControl: CameraCaptureControl!
|
||||
let captureControl = CameraCaptureControl(axis: .horizontal)
|
||||
var shutterButtonLayoutGuide: UILayoutGuide {
|
||||
captureControl.shutterButtonLayoutGuide
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
layoutMargins = UIEdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 14)
|
||||
|
||||
addLayoutGuide(controlButtonsLayoutGuide)
|
||||
addConstraints([ controlButtonsLayoutGuide.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
|
||||
controlButtonsLayoutGuide.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor) ])
|
||||
|
||||
photoLibraryButton = MediaPickerThumbnailButton(frame: CGRect(origin: .zero, size: .square(bounds.height)))
|
||||
photoLibraryButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(photoLibraryButton)
|
||||
addConstraints([ photoLibraryButton.leadingAnchor.constraint(equalTo: controlButtonsLayoutGuide.leadingAnchor),
|
||||
photoLibraryButton.centerYAnchor.constraint(equalTo: controlButtonsLayoutGuide.centerYAnchor),
|
||||
photoLibraryButton.topAnchor.constraint(greaterThanOrEqualTo: controlButtonsLayoutGuide.topAnchor) ])
|
||||
|
||||
switchCameraButton = CameraOverlayButton(image: ButtonImages.switchCamera, userInterfaceStyleOverride: .dark)
|
||||
switchCameraButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(switchCameraButton)
|
||||
addConstraints([ switchCameraButton.trailingAnchor.constraint(equalTo: controlButtonsLayoutGuide.trailingAnchor),
|
||||
switchCameraButton.topAnchor.constraint(greaterThanOrEqualTo: controlButtonsLayoutGuide.topAnchor),
|
||||
switchCameraButton.centerYAnchor.constraint(equalTo: controlButtonsLayoutGuide.centerYAnchor) ])
|
||||
|
||||
captureControl = CameraCaptureControl(axis: .horizontal)
|
||||
captureControl.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(captureControl)
|
||||
captureControl.autoPinTopToSuperviewMargin()
|
||||
@ -849,6 +831,11 @@ private class BottomBar: UIView {
|
||||
updateCompactHeightLayoutConstraints()
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(frame:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
private func updateCompactHeightLayoutConstraints() {
|
||||
if isCompactHeightLayout {
|
||||
removeConstraints(regularHeightLayoutConstraints)
|
||||
@ -869,49 +856,41 @@ private class SideBar: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
private var cameraControlsContainerView: UIView!
|
||||
private(set) var flashModeButton: CameraOverlayButton!
|
||||
private(set) var batchModeButton: CameraOverlayButton!
|
||||
private(set) var switchCameraButton: CameraOverlayButton!
|
||||
private let cameraControlsContainerView: UIStackView
|
||||
let flashModeButton = CameraOverlayButton(image: ButtonImages.flashAuto, userInterfaceStyleOverride: .dark)
|
||||
let batchModeButton = CameraOverlayButton(image: ButtonImages.batchModeOff, userInterfaceStyleOverride: .dark)
|
||||
let switchCameraButton = CameraOverlayButton(image: ButtonImages.switchCamera, userInterfaceStyleOverride: .dark)
|
||||
|
||||
private(set) var photoLibraryButton: MediaPickerThumbnailButton!
|
||||
let photoLibraryButton = MediaPickerThumbnailButton(frame: .zero)
|
||||
|
||||
private(set) var cameraCaptureControl = CameraCaptureControl(axis: .vertical)
|
||||
|
||||
override init(frame: CGRect) {
|
||||
cameraControlsContainerView = UIStackView(arrangedSubviews: [ batchModeButton, flashModeButton, switchCameraButton ])
|
||||
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
layoutMargins = UIEdgeInsets(margin: 8)
|
||||
|
||||
flashModeButton = CameraOverlayButton(image: ButtonImages.flashAuto, userInterfaceStyleOverride: .dark)
|
||||
switchCameraButton = CameraOverlayButton(image: ButtonImages.switchCamera, userInterfaceStyleOverride: .dark)
|
||||
batchModeButton = CameraOverlayButton(image: ButtonImages.batchModeOff, userInterfaceStyleOverride: .dark)
|
||||
let stackView = UIStackView(arrangedSubviews: [ batchModeButton, flashModeButton, switchCameraButton ])
|
||||
stackView.spacing = 16
|
||||
stackView.axis = .vertical
|
||||
addSubview(stackView)
|
||||
stackView.autoPinWidthToSuperviewMargins()
|
||||
stackView.autoPinTopToSuperviewMargin()
|
||||
cameraControlsContainerView = stackView
|
||||
cameraControlsContainerView.spacing = 16
|
||||
cameraControlsContainerView.axis = .vertical
|
||||
addSubview(cameraControlsContainerView)
|
||||
cameraControlsContainerView.autoPinWidthToSuperviewMargins()
|
||||
cameraControlsContainerView.autoPinTopToSuperviewMargin()
|
||||
|
||||
addSubview(cameraCaptureControl)
|
||||
cameraCaptureControl.autoHCenterInSuperview()
|
||||
cameraCaptureControl.shutterButtonLayoutGuide.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 36).isActive = true
|
||||
cameraCaptureControl.shutterButtonLayoutGuide.topAnchor.constraint(equalTo: cameraControlsContainerView.bottomAnchor, constant: 36).isActive = true
|
||||
|
||||
photoLibraryButton = MediaPickerThumbnailButton(frame: CGRect(origin: .zero, size: .square(bounds.height)))
|
||||
addSubview(photoLibraryButton)
|
||||
photoLibraryButton.autoHCenterInSuperview()
|
||||
photoLibraryButton.topAnchor.constraint(equalTo: cameraCaptureControl.shutterButtonLayoutGuide.bottomAnchor, constant: 36).isActive = true
|
||||
photoLibraryButton.bottomAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(frame:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1114,8 +1093,9 @@ class CapturePreviewView: UIView {
|
||||
layer.addSublayer(previewLayer)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
@available(*, unavailable, message: "Use init(session:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1123,15 +1103,7 @@ private class RecordingTimerView: PillView {
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
layoutMargins = UIEdgeInsets(hMargin: 16, vMargin: 0)
|
||||
|
||||
let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
|
||||
@ -1148,9 +1120,14 @@ private class RecordingTimerView: PillView {
|
||||
updateView()
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "Use init(frame:) instead")
|
||||
required init?(coder: NSCoder) {
|
||||
notImplemented()
|
||||
}
|
||||
|
||||
// MARK: - Subviews
|
||||
|
||||
private lazy var label: UILabel = {
|
||||
private let label: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFont.ows_monospacedDigitFont(withSize: 20)
|
||||
label.textAlignment = .center
|
||||
|
||||
Loading…
Reference in New Issue
Block a user