mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Various fixes
This commit is contained in:
@@ -4,40 +4,62 @@ import AsyncDisplayKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import ComponentFlow
|
||||
import MultilineTextComponent
|
||||
import BundleIconComponent
|
||||
import PlainButtonComponent
|
||||
|
||||
private final class WeakController {
|
||||
private weak var _value: MinimizableController?
|
||||
|
||||
public var value: MinimizableController? {
|
||||
return self._value
|
||||
}
|
||||
|
||||
public init(_ value: MinimizableController) {
|
||||
self._value = value
|
||||
}
|
||||
}
|
||||
|
||||
final class MinimizedHeaderNode: ASDisplayNode {
|
||||
var theme: NavigationControllerTheme {
|
||||
didSet {
|
||||
self.minimizedBackgroundNode.backgroundColor = self.theme.navigationBar.opaqueBackgroundColor
|
||||
self.minimizedCloseButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Instant View/Close"), color: self.theme.navigationBar.primaryTextColor), for: .normal)
|
||||
self.backgroundView.backgroundColor = self.theme.navigationBar.opaqueBackgroundColor
|
||||
}
|
||||
}
|
||||
let strings: PresentationStrings
|
||||
|
||||
private let minimizedBackgroundNode: ASDisplayNode
|
||||
private let minimizedTitleNode: ImmediateTextNode
|
||||
private let minimizedCloseButton: HighlightableButtonNode
|
||||
private var minimizedTitleDisposable: Disposable?
|
||||
private let backgroundView = UIView()
|
||||
private var iconView = UIImageView()
|
||||
private let titleLabel = ComponentView<Empty>()
|
||||
private let closeButton = ComponentView<Empty>()
|
||||
private var titleDisposable: Disposable?
|
||||
|
||||
private var _controllers: [Weak<ViewController>] = []
|
||||
var controllers: [ViewController] {
|
||||
private var _controllers: [WeakController] = []
|
||||
var controllers: [MinimizableController] {
|
||||
get {
|
||||
return self._controllers.compactMap { $0.value }
|
||||
}
|
||||
set {
|
||||
if !newValue.isEmpty {
|
||||
if self.controllers.count == 1, let icon = self.controllers.first?.minimizedIcon {
|
||||
self.icon = icon
|
||||
} else {
|
||||
self.icon = nil
|
||||
}
|
||||
|
||||
if newValue.count != self.controllers.count {
|
||||
self._controllers = newValue.map { Weak($0) }
|
||||
self._controllers = newValue.map { WeakController($0) }
|
||||
|
||||
self.minimizedTitleDisposable?.dispose()
|
||||
self.minimizedTitleDisposable = nil
|
||||
self.titleDisposable?.dispose()
|
||||
self.titleDisposable = nil
|
||||
|
||||
var signals: [Signal<String?, NoError>] = []
|
||||
for controller in newValue {
|
||||
signals.append(controller.titleSignal)
|
||||
}
|
||||
|
||||
self.minimizedTitleDisposable = (combineLatest(signals)
|
||||
self.titleDisposable = (combineLatest(signals)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] titles in
|
||||
guard let self else {
|
||||
return
|
||||
@@ -54,8 +76,19 @@ final class MinimizedHeaderNode: ASDisplayNode {
|
||||
})
|
||||
}
|
||||
} else {
|
||||
self.minimizedTitleDisposable?.dispose()
|
||||
self.minimizedTitleDisposable = nil
|
||||
self.icon = nil
|
||||
|
||||
self.titleDisposable?.dispose()
|
||||
self.titleDisposable = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var icon: UIImage? {
|
||||
didSet {
|
||||
self.iconView.image = self.icon
|
||||
if let (size, insets, isExpanded) = self.validLayout {
|
||||
self.update(size: size, insets: insets, isExpanded: isExpanded, transition: .immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,42 +110,32 @@ final class MinimizedHeaderNode: ASDisplayNode {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
|
||||
self.minimizedBackgroundNode = ASDisplayNode()
|
||||
self.minimizedBackgroundNode.cornerRadius = 10.0
|
||||
self.minimizedBackgroundNode.clipsToBounds = true
|
||||
self.minimizedBackgroundNode.backgroundColor = theme.navigationBar.opaqueBackgroundColor
|
||||
self.backgroundView.clipsToBounds = true
|
||||
self.backgroundView.backgroundColor = theme.navigationBar.opaqueBackgroundColor
|
||||
self.backgroundView.layer.cornerRadius = 10.0
|
||||
if #available(iOS 11.0, *) {
|
||||
self.minimizedBackgroundNode.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
self.backgroundView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
}
|
||||
|
||||
self.minimizedTitleNode = ImmediateTextNode()
|
||||
|
||||
self.minimizedCloseButton = HighlightableButtonNode()
|
||||
self.minimizedCloseButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Instant View/Close"), color: self.theme.navigationBar.primaryTextColor), for: .normal)
|
||||
|
||||
self.iconView.clipsToBounds = true
|
||||
self.iconView.layer.cornerRadius = 2.5
|
||||
|
||||
super.init()
|
||||
|
||||
self.clipsToBounds = true
|
||||
|
||||
self.addSubnode(self.minimizedBackgroundNode)
|
||||
self.minimizedBackgroundNode.addSubnode(self.minimizedTitleNode)
|
||||
self.minimizedBackgroundNode.addSubnode(self.minimizedCloseButton)
|
||||
|
||||
self.minimizedCloseButton.addTarget(self, action: #selector(self.closePressed), forControlEvents: .touchUpInside)
|
||||
|
||||
applySmoothRoundedCorners(self.minimizedBackgroundNode.layer)
|
||||
self.view.addSubview(self.backgroundView)
|
||||
self.backgroundView.addSubview(self.iconView)
|
||||
|
||||
applySmoothRoundedCorners(self.backgroundView.layer)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
self.minimizedBackgroundNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.maximizeTapGesture(_:))))
|
||||
self.backgroundView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.maximizeTapGesture(_:))))
|
||||
}
|
||||
|
||||
@objc private func closePressed() {
|
||||
self.requestClose()
|
||||
}
|
||||
|
||||
|
||||
@objc private func maximizeTapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
if case .ended = recognizer.state {
|
||||
let location = recognizer.location(in: self.view)
|
||||
@@ -128,19 +151,74 @@ final class MinimizedHeaderNode: ASDisplayNode {
|
||||
self.validLayout = (size, insets, isExpanded)
|
||||
|
||||
let headerHeight: CGFloat = 44.0
|
||||
let titleSpacing: CGFloat = 4.0
|
||||
var titleSideInset: CGFloat = 56.0
|
||||
if !isExpanded {
|
||||
titleSideInset += insets.left
|
||||
}
|
||||
|
||||
self.minimizedTitleNode.attributedText = NSAttributedString(string: self.title ?? "", font: Font.bold(17.0), textColor: self.theme.navigationBar.primaryTextColor)
|
||||
let iconSize = CGSize(width: 20.0, height: 20.0)
|
||||
|
||||
let titleSize = self.titleLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(text: .plain(NSAttributedString(string: self.title ?? "", font: Font.bold(17.0), textColor: self.theme.navigationBar.primaryTextColor)), horizontalAlignment: .center, maximumNumberOfLines: 1)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: size.width - titleSideInset * 2.0, height: headerHeight)
|
||||
)
|
||||
|
||||
let titleSize = self.minimizedTitleNode.updateLayout(CGSize(width: size.width - titleSideInset * 2.0, height: headerHeight))
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - titleSize.width) / 2.0), y: floorToScreenPixels((headerHeight - titleSize.height) / 2.0)), size: titleSize)
|
||||
self.minimizedTitleNode.bounds = CGRect(origin: .zero, size: titleFrame.size)
|
||||
transition.updatePosition(node: self.minimizedTitleNode, position: titleFrame.center)
|
||||
transition.updateFrame(node: self.minimizedCloseButton, frame: CGRect(origin: CGPoint(x: isExpanded ? 0.0 : insets.left, y: 0.0), size: CGSize(width: 44.0, height: 44.0)))
|
||||
var totalWidth = titleSize.width
|
||||
if isExpanded, let icon = self.icon {
|
||||
self.iconView.image = icon
|
||||
totalWidth += iconSize.width + titleSpacing
|
||||
} else {
|
||||
self.iconView.image = nil
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.minimizedBackgroundNode, frame: CGRect(origin: .zero, size: CGSize(width: size.width, height: 243.0)))
|
||||
let iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - totalWidth) / 2.0), y: floorToScreenPixels((headerHeight - iconSize.height) / 2.0)), size: iconSize)
|
||||
transition.updateFrame(view: self.iconView, frame: iconFrame)
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - totalWidth) / 2.0) + totalWidth - titleSize.width, y: floorToScreenPixels((headerHeight - titleSize.height) / 2.0)), size: titleSize)
|
||||
if let view = self.titleLabel.view {
|
||||
if view.superview == nil {
|
||||
self.backgroundView.addSubview(view)
|
||||
}
|
||||
|
||||
view.bounds = CGRect(origin: .zero, size: titleFrame.size)
|
||||
transition.updatePosition(layer: view.layer, position: titleFrame.center)
|
||||
}
|
||||
|
||||
let _ = self.closeButton.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
PlainButtonComponent(
|
||||
content: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Instant View/Close",
|
||||
tintColor: self.theme.navigationBar.primaryTextColor
|
||||
)
|
||||
),
|
||||
effectAlignment: .center,
|
||||
minSize: CGSize(width: 44.0, height: 44.0),
|
||||
action: { [weak self] in
|
||||
self?.requestClose()
|
||||
},
|
||||
animateScale: false
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 44.0, height: 44.0)
|
||||
)
|
||||
let closeButtonFrame = CGRect(origin: CGPoint(x: isExpanded ? 0.0 : insets.left, y: 0.0), size: CGSize(width: 44.0, height: 44.0))
|
||||
if let view = self.closeButton.view {
|
||||
if view.superview == nil {
|
||||
self.backgroundView.addSubview(view)
|
||||
}
|
||||
|
||||
transition.updateFrame(view: view, frame: closeButtonFrame)
|
||||
}
|
||||
|
||||
transition.updateFrame(view: self.backgroundView, frame: CGRect(origin: .zero, size: CGSize(width: size.width, height: 243.0)))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user