Files
OrderScheduling/Pods/SwiftEntryKit/Source/Infra/EKEntryView.swift
DDIsFriend f0e8a1709d initial
2023-08-18 17:28:57 +08:00

183 lines
5.9 KiB
Swift

//
// EKEntryView.swift
// SwiftEntryKit
//
// Created by Daniel Huri on 4/15/18.
// Copyright (c) 2018 huri000@gmail.com. All rights reserved.
//
import UIKit
class EKEntryView: EKStyleView {
struct Content {
var viewController: UIViewController!
var view: UIView!
var attributes: EKAttributes
init(viewController: UIViewController, attributes: EKAttributes) {
self.viewController = viewController
self.view = viewController.view
self.attributes = attributes
}
init(view: UIView, attributes: EKAttributes) {
self.view = view
self.attributes = attributes
}
}
// MARK: Props
/** Background view */
private var backgroundView: EKBackgroundView!
/** The content - contains the view, view controller, attributes */
var content: Content
private lazy var contentView: UIView = {
return UIView()
}()
var attributes: EKAttributes {
return content.attributes
}
private lazy var contentContainerView: EKStyleView = {
let contentContainerView = EKStyleView()
self.addSubview(contentContainerView)
contentContainerView.layoutToSuperview(axis: .vertically)
contentContainerView.layoutToSuperview(axis: .horizontally)
contentContainerView.clipsToBounds = true
return contentContainerView
}()
// MARK: Setup
init(newEntry content: Content) {
self.content = content
super.init(frame: UIScreen.main.bounds)
setupContentView()
applyDropShadow()
applyBackgroundToContentView()
applyFrameStyle()
adjustInnerContentAppearanceIfNeeded()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
applyFrameStyle()
}
func transform(to view: UIView) {
let previousView = content.view
content.view = view
view.layoutIfNeeded()
let previousHeight = set(.height, of: frame.height, priority: .must)
let nextHeight = set(.height, of: view.frame.height, priority: .defaultLow)
SwiftEntryKit.layoutIfNeeded()
UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [.beginFromCurrentState, .layoutSubviews], animations: {
previousHeight.priority = .defaultLow
nextHeight.priority = .must
previousView!.alpha = 0
SwiftEntryKit.layoutIfNeeded()
}, completion: { (finished) in
view.alpha = 0
previousView!.removeFromSuperview()
self.removeConstraints([previousHeight, nextHeight])
self.setupContentView()
UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [.curveEaseOut], animations: {
view.alpha = 1
}, completion: nil)
})
}
private func setupContentView() {
contentView.addSubview(content.view)
content.view.layoutToSuperview(axis: .horizontally)
content.view.layoutToSuperview(axis: .vertically)
contentContainerView.addSubview(contentView)
contentView.fillSuperview()
contentView.layoutToSuperview(axis: .vertically)
contentView.layoutToSuperview(axis: .horizontally)
}
// Complementary logic for issue #117
private func adjustInnerContentAppearanceIfNeeded() {
guard let view = content.view as? EntryAppearanceDescriptor else {
return
}
view.bottomCornerRadius = attributes.roundCorners.cornerValues?.radius ?? 0
}
// Apply round corners
private func applyFrameStyle() {
backgroundView.applyFrameStyle(roundCorners: attributes.roundCorners, border: attributes.border)
}
// Apply drop shadow
private func applyDropShadow() {
switch attributes.shadow {
case .active(with: let value):
applyDropShadow(withOffset: value.offset,
opacity: value.opacity,
radius: value.radius,
color: value.color.color(for: traitCollection, mode: attributes.displayMode))
case .none:
removeDropShadow()
}
}
// Apply background
private func applyBackgroundToContentView() {
let attributes = content.attributes
let backgroundView = EKBackgroundView()
backgroundView.style = .init(background: attributes.entryBackground,
displayMode: attributes.displayMode)
switch attributes.positionConstraints.safeArea {
case .empty(fillSafeArea: let fillSafeArea) where fillSafeArea: // Safe area filled with color
insertSubview(backgroundView, at: 0)
backgroundView.layoutToSuperview(axis: .horizontally)
var topInset: CGFloat = 0
var bottomInset: CGFloat = 0
switch attributes.position {
case .top:
topInset = -EKWindowProvider.safeAreaInsets.top
case .bottom, .center:
bottomInset = EKWindowProvider.safeAreaInsets.bottom
}
backgroundView.layoutToSuperview(.top, offset: topInset)
backgroundView.layoutToSuperview(.bottom, offset: bottomInset)
default: // Float case or a Toast with unfilled safe area
contentView.insertSubview(backgroundView, at: 0)
backgroundView.fillSuperview()
}
self.backgroundView = backgroundView
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
applyDropShadow()
}
}