mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
526 lines
23 KiB
Swift
526 lines
23 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import Display
|
|
import ComponentFlow
|
|
import AccountContext
|
|
import TelegramCore
|
|
import TelegramPresentationData
|
|
import AnimationCache
|
|
import MultiAnimationRenderer
|
|
|
|
final class GroupHeaderLayer: UIView {
|
|
override static var layerClass: AnyClass {
|
|
return PassthroughLayer.self
|
|
}
|
|
|
|
private let actionPressed: () -> Void
|
|
private let performItemAction: (EmojiPagerContentComponent.Item, UIView, CGRect, CALayer) -> Void
|
|
|
|
private let textLayer: SimpleLayer
|
|
private let tintTextLayer: SimpleLayer
|
|
|
|
private var subtitleLayer: SimpleLayer?
|
|
private var tintSubtitleLayer: SimpleLayer?
|
|
private var lockIconLayer: SimpleLayer?
|
|
private var tintLockIconLayer: SimpleLayer?
|
|
private var badgeLayer: SimpleLayer?
|
|
private var tintBadgeLayer: SimpleLayer?
|
|
private(set) var clearIconLayer: SimpleLayer?
|
|
private var tintClearIconLayer: SimpleLayer?
|
|
private var separatorLayer: SimpleLayer?
|
|
private var tintSeparatorLayer: SimpleLayer?
|
|
private var actionButton: GroupHeaderActionButton?
|
|
|
|
private var groupEmbeddedView: GroupEmbeddedView?
|
|
|
|
private var theme: PresentationTheme?
|
|
|
|
private var currentTextLayout: (string: String, color: UIColor, constrainedWidth: CGFloat, size: CGSize)?
|
|
private var currentSubtitleLayout: (string: String, color: UIColor, constrainedWidth: CGFloat, size: CGSize)?
|
|
|
|
let tintContentLayer: SimpleLayer
|
|
|
|
init(actionPressed: @escaping () -> Void, performItemAction: @escaping (EmojiPagerContentComponent.Item, UIView, CGRect, CALayer) -> Void) {
|
|
self.actionPressed = actionPressed
|
|
self.performItemAction = performItemAction
|
|
|
|
self.textLayer = SimpleLayer()
|
|
self.tintTextLayer = SimpleLayer()
|
|
|
|
self.tintContentLayer = SimpleLayer()
|
|
|
|
super.init(frame: CGRect())
|
|
|
|
self.layer.addSublayer(self.textLayer)
|
|
self.tintContentLayer.addSublayer(self.tintTextLayer)
|
|
|
|
(self.layer as? PassthroughLayer)?.mirrorLayer = self.tintContentLayer
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func update(
|
|
context: AccountContext,
|
|
theme: PresentationTheme,
|
|
forceNeedsVibrancy: Bool,
|
|
layoutType: EmojiPagerContentComponent.ItemLayoutType,
|
|
hasTopSeparator: Bool,
|
|
actionButtonTitle: String?,
|
|
actionButtonIsCompact: Bool,
|
|
title: String,
|
|
subtitle: String?,
|
|
badge: String?,
|
|
isPremiumLocked: Bool,
|
|
hasClear: Bool,
|
|
embeddedItems: [EmojiPagerContentComponent.Item]?,
|
|
isStickers: Bool,
|
|
constrainedSize: CGSize,
|
|
insets: UIEdgeInsets,
|
|
cache: AnimationCache,
|
|
renderer: MultiAnimationRenderer,
|
|
attemptSynchronousLoad: Bool
|
|
) -> (size: CGSize, centralContentWidth: CGFloat) {
|
|
var themeUpdated = false
|
|
if self.theme !== theme {
|
|
self.theme = theme
|
|
themeUpdated = true
|
|
}
|
|
|
|
let needsVibrancy = !theme.overallDarkAppearance || forceNeedsVibrancy
|
|
|
|
let textOffsetY: CGFloat
|
|
if hasTopSeparator {
|
|
textOffsetY = 9.0
|
|
} else {
|
|
textOffsetY = 0.0
|
|
}
|
|
|
|
let subtitleColor: UIColor
|
|
if theme.overallDarkAppearance && forceNeedsVibrancy {
|
|
subtitleColor = theme.chat.inputMediaPanel.panelContentVibrantOverlayColor.withMultipliedAlpha(0.2)
|
|
} else {
|
|
subtitleColor = theme.chat.inputMediaPanel.panelContentVibrantOverlayColor
|
|
}
|
|
|
|
let color: UIColor
|
|
let needsTintText: Bool
|
|
if subtitle != nil {
|
|
color = theme.chat.inputPanel.primaryTextColor
|
|
needsTintText = false
|
|
} else {
|
|
color = subtitleColor
|
|
needsTintText = true
|
|
}
|
|
|
|
let titleHorizontalOffset: CGFloat
|
|
if isPremiumLocked {
|
|
titleHorizontalOffset = 10.0 + 2.0
|
|
} else {
|
|
titleHorizontalOffset = 0.0
|
|
}
|
|
|
|
var actionButtonSize: CGSize?
|
|
if let actionButtonTitle = actionButtonTitle {
|
|
let actionButton: GroupHeaderActionButton
|
|
if let current = self.actionButton {
|
|
actionButton = current
|
|
} else {
|
|
actionButton = GroupHeaderActionButton(pressed: self.actionPressed)
|
|
self.actionButton = actionButton
|
|
self.addSubview(actionButton)
|
|
self.tintContentLayer.addSublayer(actionButton.tintContainerLayer)
|
|
}
|
|
|
|
actionButtonSize = actionButton.update(theme: theme, title: actionButtonTitle, compact: actionButtonIsCompact)
|
|
} else {
|
|
if let actionButton = self.actionButton {
|
|
self.actionButton = nil
|
|
actionButton.removeFromSuperview()
|
|
}
|
|
}
|
|
|
|
var clearSize: CGSize = .zero
|
|
var clearWidth: CGFloat = 0.0
|
|
if hasClear {
|
|
var updateImage = themeUpdated
|
|
|
|
let clearIconLayer: SimpleLayer
|
|
if let current = self.clearIconLayer {
|
|
clearIconLayer = current
|
|
} else {
|
|
updateImage = true
|
|
clearIconLayer = SimpleLayer()
|
|
self.clearIconLayer = clearIconLayer
|
|
self.layer.addSublayer(clearIconLayer)
|
|
}
|
|
let tintClearIconLayer: SimpleLayer
|
|
if let current = self.tintClearIconLayer {
|
|
tintClearIconLayer = current
|
|
} else {
|
|
updateImage = true
|
|
tintClearIconLayer = SimpleLayer()
|
|
self.tintClearIconLayer = tintClearIconLayer
|
|
self.tintContentLayer.addSublayer(tintClearIconLayer)
|
|
}
|
|
|
|
tintClearIconLayer.isHidden = !needsVibrancy
|
|
|
|
clearSize = clearIconLayer.bounds.size
|
|
if updateImage, let image = PresentationResourcesChat.chatInputMediaPanelGridDismissImage(theme, color: subtitleColor) {
|
|
clearSize = image.size
|
|
clearIconLayer.contents = image.cgImage
|
|
}
|
|
if updateImage, let image = PresentationResourcesChat.chatInputMediaPanelGridDismissImage(theme, color: .white) {
|
|
tintClearIconLayer.contents = image.cgImage
|
|
}
|
|
|
|
tintClearIconLayer.frame = clearIconLayer.frame
|
|
clearWidth = 4.0 + clearSize.width
|
|
} else {
|
|
if let clearIconLayer = self.clearIconLayer {
|
|
self.clearIconLayer = nil
|
|
clearIconLayer.removeFromSuperlayer()
|
|
}
|
|
if let tintClearIconLayer = self.tintClearIconLayer {
|
|
self.tintClearIconLayer = nil
|
|
tintClearIconLayer.removeFromSuperlayer()
|
|
}
|
|
}
|
|
|
|
var textConstrainedWidth = constrainedSize.width - titleHorizontalOffset - 10.0
|
|
if let actionButtonSize = actionButtonSize {
|
|
if actionButtonIsCompact {
|
|
textConstrainedWidth -= actionButtonSize.width * 2.0 + 10.0
|
|
} else {
|
|
textConstrainedWidth -= actionButtonSize.width + 10.0
|
|
}
|
|
}
|
|
if clearWidth > 0.0 {
|
|
textConstrainedWidth -= clearWidth + 8.0
|
|
}
|
|
|
|
let textSize: CGSize
|
|
if let currentTextLayout = self.currentTextLayout, currentTextLayout.string == title, currentTextLayout.color == color, currentTextLayout.constrainedWidth == textConstrainedWidth {
|
|
textSize = currentTextLayout.size
|
|
} else {
|
|
let font: UIFont
|
|
let stringValue: String
|
|
if subtitle == nil {
|
|
font = Font.medium(13.0)
|
|
stringValue = title.uppercased()
|
|
} else {
|
|
font = Font.semibold(16.0)
|
|
stringValue = title
|
|
}
|
|
let string = NSAttributedString(string: stringValue, font: font, textColor: color)
|
|
let whiteString = NSAttributedString(string: stringValue, font: font, textColor: .white)
|
|
let stringBounds = string.boundingRect(with: CGSize(width: textConstrainedWidth, height: 18.0), options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
|
textSize = CGSize(width: ceil(stringBounds.width), height: ceil(stringBounds.height))
|
|
self.textLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
UIGraphicsPushContext(context)
|
|
|
|
//string.draw(in: stringBounds)
|
|
string.draw(with: stringBounds, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
|
|
|
UIGraphicsPopContext()
|
|
})?.cgImage
|
|
self.tintTextLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
UIGraphicsPushContext(context)
|
|
|
|
//whiteString.draw(in: stringBounds)
|
|
whiteString.draw(with: stringBounds, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
|
|
|
UIGraphicsPopContext()
|
|
})?.cgImage
|
|
self.tintTextLayer.isHidden = !needsVibrancy
|
|
self.currentTextLayout = (title, color, textConstrainedWidth, textSize)
|
|
}
|
|
|
|
var badgeSize: CGSize = .zero
|
|
if let badge {
|
|
func generateBadgeImage(color: UIColor) -> UIImage? {
|
|
let string = NSAttributedString(string: badge, font: Font.semibold(11.0), textColor: .white)
|
|
let stringBounds = string.boundingRect(with: CGSize(width: 120, height: 18.0), options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
|
|
|
let badgeSize = CGSize(width: stringBounds.width + 8.0, height: 16.0)
|
|
return generateImage(badgeSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
|
|
context.setFillColor(color.cgColor)
|
|
context.addPath(UIBezierPath(roundedRect: CGRect(origin: .zero, size: badgeSize), cornerRadius: badgeSize.height / 2.0).cgPath)
|
|
context.fillPath()
|
|
|
|
context.setBlendMode(.clear)
|
|
|
|
UIGraphicsPushContext(context)
|
|
|
|
string.draw(with: CGRect(origin: CGPoint(x: floorToScreenPixels((badgeSize.width - stringBounds.size.width) / 2.0), y: floorToScreenPixels((badgeSize.height - stringBounds.size.height) / 2.0)), size: stringBounds.size), options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
|
|
|
UIGraphicsPopContext()
|
|
})
|
|
}
|
|
|
|
let badgeLayer: SimpleLayer
|
|
if let current = self.badgeLayer {
|
|
badgeLayer = current
|
|
} else {
|
|
badgeLayer = SimpleLayer()
|
|
self.badgeLayer = badgeLayer
|
|
self.layer.addSublayer(badgeLayer)
|
|
|
|
if let image = generateBadgeImage(color: color.withMultipliedAlpha(0.66)) {
|
|
badgeLayer.contents = image.cgImage
|
|
badgeLayer.bounds = CGRect(origin: .zero, size: image.size)
|
|
}
|
|
}
|
|
badgeSize = badgeLayer.bounds.size
|
|
|
|
let tintBadgeLayer: SimpleLayer
|
|
if let current = self.tintBadgeLayer {
|
|
tintBadgeLayer = current
|
|
} else {
|
|
tintBadgeLayer = SimpleLayer()
|
|
self.tintBadgeLayer = tintBadgeLayer
|
|
self.tintContentLayer.addSublayer(tintBadgeLayer)
|
|
|
|
if let image = generateBadgeImage(color: .white) {
|
|
tintBadgeLayer.contents = image.cgImage
|
|
}
|
|
}
|
|
} else {
|
|
if let badgeLayer = self.badgeLayer {
|
|
self.badgeLayer = nil
|
|
badgeLayer.removeFromSuperlayer()
|
|
}
|
|
if let tintBadgeLayer = self.tintBadgeLayer {
|
|
self.tintBadgeLayer = nil
|
|
tintBadgeLayer.removeFromSuperlayer()
|
|
}
|
|
}
|
|
|
|
let textFrame: CGRect
|
|
if subtitle == nil {
|
|
textFrame = CGRect(origin: CGPoint(x: titleHorizontalOffset + floor((constrainedSize.width - titleHorizontalOffset - (textSize.width + badgeSize.width)) / 2.0), y: textOffsetY), size: textSize)
|
|
} else {
|
|
textFrame = CGRect(origin: CGPoint(x: titleHorizontalOffset, y: textOffsetY), size: textSize)
|
|
}
|
|
self.textLayer.frame = textFrame
|
|
self.tintTextLayer.frame = textFrame
|
|
self.tintTextLayer.isHidden = !needsTintText
|
|
|
|
if let badgeLayer = self.badgeLayer, let tintBadgeLayer = self.tintBadgeLayer {
|
|
badgeLayer.frame = CGRect(origin: CGPoint(x: textFrame.maxX + 4.0, y: 0.0), size: badgeLayer.frame.size)
|
|
tintBadgeLayer.frame = badgeLayer.frame
|
|
}
|
|
|
|
if isPremiumLocked {
|
|
let lockIconLayer: SimpleLayer
|
|
if let current = self.lockIconLayer {
|
|
lockIconLayer = current
|
|
} else {
|
|
lockIconLayer = SimpleLayer()
|
|
self.lockIconLayer = lockIconLayer
|
|
self.layer.addSublayer(lockIconLayer)
|
|
}
|
|
if let image = PresentationResourcesChat.chatEntityKeyboardLock(theme, color: color) {
|
|
let imageSize = image.size
|
|
lockIconLayer.contents = image.cgImage
|
|
lockIconLayer.frame = CGRect(origin: CGPoint(x: textFrame.minX - imageSize.width - 3.0, y: 2.0 + UIScreenPixel), size: imageSize)
|
|
} else {
|
|
lockIconLayer.contents = nil
|
|
}
|
|
|
|
let tintLockIconLayer: SimpleLayer
|
|
if let current = self.tintLockIconLayer {
|
|
tintLockIconLayer = current
|
|
} else {
|
|
tintLockIconLayer = SimpleLayer()
|
|
self.tintLockIconLayer = tintLockIconLayer
|
|
self.tintContentLayer.addSublayer(tintLockIconLayer)
|
|
}
|
|
if let image = PresentationResourcesChat.chatEntityKeyboardLock(theme, color: .white) {
|
|
tintLockIconLayer.contents = image.cgImage
|
|
tintLockIconLayer.frame = lockIconLayer.frame
|
|
tintLockIconLayer.isHidden = !needsVibrancy
|
|
} else {
|
|
tintLockIconLayer.contents = nil
|
|
}
|
|
} else {
|
|
if let lockIconLayer = self.lockIconLayer {
|
|
self.lockIconLayer = nil
|
|
lockIconLayer.removeFromSuperlayer()
|
|
}
|
|
if let tintLockIconLayer = self.tintLockIconLayer {
|
|
self.tintLockIconLayer = nil
|
|
tintLockIconLayer.removeFromSuperlayer()
|
|
}
|
|
}
|
|
|
|
let subtitleSize: CGSize
|
|
if let subtitle = subtitle {
|
|
var updateSubtitleContents: UIImage?
|
|
var updateTintSubtitleContents: UIImage?
|
|
if let currentSubtitleLayout = self.currentSubtitleLayout, currentSubtitleLayout.string == subtitle, currentSubtitleLayout.color == subtitleColor, currentSubtitleLayout.constrainedWidth == textConstrainedWidth {
|
|
subtitleSize = currentSubtitleLayout.size
|
|
} else {
|
|
let string = NSAttributedString(string: subtitle, font: Font.regular(15.0), textColor: subtitleColor)
|
|
let whiteString = NSAttributedString(string: subtitle, font: Font.regular(15.0), textColor: .white)
|
|
let stringBounds = string.boundingRect(with: CGSize(width: textConstrainedWidth, height: 100.0), options: .usesLineFragmentOrigin, context: nil)
|
|
subtitleSize = CGSize(width: ceil(stringBounds.width), height: ceil(stringBounds.height))
|
|
updateSubtitleContents = generateImage(subtitleSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
UIGraphicsPushContext(context)
|
|
|
|
string.draw(in: stringBounds)
|
|
|
|
UIGraphicsPopContext()
|
|
})
|
|
updateTintSubtitleContents = generateImage(subtitleSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
UIGraphicsPushContext(context)
|
|
|
|
whiteString.draw(in: stringBounds)
|
|
|
|
UIGraphicsPopContext()
|
|
})
|
|
self.currentSubtitleLayout = (subtitle, subtitleColor, textConstrainedWidth, subtitleSize)
|
|
}
|
|
|
|
let subtitleLayer: SimpleLayer
|
|
if let current = self.subtitleLayer {
|
|
subtitleLayer = current
|
|
} else {
|
|
subtitleLayer = SimpleLayer()
|
|
self.subtitleLayer = subtitleLayer
|
|
self.layer.addSublayer(subtitleLayer)
|
|
}
|
|
|
|
if let updateSubtitleContents = updateSubtitleContents {
|
|
subtitleLayer.contents = updateSubtitleContents.cgImage
|
|
}
|
|
|
|
let tintSubtitleLayer: SimpleLayer
|
|
if let current = self.tintSubtitleLayer {
|
|
tintSubtitleLayer = current
|
|
} else {
|
|
tintSubtitleLayer = SimpleLayer()
|
|
self.tintSubtitleLayer = tintSubtitleLayer
|
|
self.tintContentLayer.addSublayer(tintSubtitleLayer)
|
|
}
|
|
tintSubtitleLayer.isHidden = !needsVibrancy
|
|
|
|
if let updateTintSubtitleContents = updateTintSubtitleContents {
|
|
tintSubtitleLayer.contents = updateTintSubtitleContents.cgImage
|
|
}
|
|
|
|
let subtitleFrame = CGRect(origin: CGPoint(x: 0.0, y: textFrame.maxY + 1.0), size: subtitleSize)
|
|
subtitleLayer.frame = subtitleFrame
|
|
tintSubtitleLayer.frame = subtitleFrame
|
|
} else {
|
|
subtitleSize = CGSize()
|
|
if let subtitleLayer = self.subtitleLayer {
|
|
self.subtitleLayer = nil
|
|
subtitleLayer.removeFromSuperlayer()
|
|
}
|
|
if let tintSubtitleLayer = self.tintSubtitleLayer {
|
|
self.tintSubtitleLayer = nil
|
|
tintSubtitleLayer.removeFromSuperlayer()
|
|
}
|
|
}
|
|
|
|
self.clearIconLayer?.frame = CGRect(origin: CGPoint(x: constrainedSize.width - clearSize.width, y: floorToScreenPixels((textSize.height - clearSize.height) / 2.0)), size: clearSize)
|
|
|
|
var size: CGSize
|
|
size = CGSize(width: constrainedSize.width, height: constrainedSize.height)
|
|
|
|
if let embeddedItems = embeddedItems {
|
|
let groupEmbeddedView: GroupEmbeddedView
|
|
if let current = self.groupEmbeddedView {
|
|
groupEmbeddedView = current
|
|
} else {
|
|
groupEmbeddedView = GroupEmbeddedView(performItemAction: self.performItemAction)
|
|
self.groupEmbeddedView = groupEmbeddedView
|
|
self.addSubview(groupEmbeddedView)
|
|
}
|
|
|
|
let groupEmbeddedViewSize = CGSize(width: constrainedSize.width + insets.left + insets.right, height: 36.0)
|
|
groupEmbeddedView.frame = CGRect(origin: CGPoint(x: -insets.left, y: size.height - groupEmbeddedViewSize.height), size: groupEmbeddedViewSize)
|
|
groupEmbeddedView.update(
|
|
context: context,
|
|
theme: theme,
|
|
insets: insets,
|
|
size: groupEmbeddedViewSize,
|
|
items: embeddedItems,
|
|
isStickers: isStickers,
|
|
cache: cache,
|
|
renderer: renderer,
|
|
attemptSynchronousLoad: attemptSynchronousLoad
|
|
)
|
|
} else {
|
|
if let groupEmbeddedView = self.groupEmbeddedView {
|
|
self.groupEmbeddedView = nil
|
|
groupEmbeddedView.removeFromSuperview()
|
|
}
|
|
}
|
|
|
|
if let actionButtonSize = actionButtonSize, let actionButton = self.actionButton {
|
|
let actionButtonFrame = CGRect(origin: CGPoint(x: size.width - actionButtonSize.width, y: textFrame.minY + (actionButtonIsCompact ? 0.0 : 3.0)), size: actionButtonSize)
|
|
actionButton.bounds = CGRect(origin: CGPoint(), size: actionButtonFrame.size)
|
|
actionButton.center = actionButtonFrame.center
|
|
}
|
|
|
|
if hasTopSeparator {
|
|
let separatorLayer: SimpleLayer
|
|
if let current = self.separatorLayer {
|
|
separatorLayer = current
|
|
} else {
|
|
separatorLayer = SimpleLayer()
|
|
self.separatorLayer = separatorLayer
|
|
self.layer.addSublayer(separatorLayer)
|
|
}
|
|
separatorLayer.backgroundColor = subtitleColor.cgColor
|
|
separatorLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: UIScreenPixel))
|
|
|
|
let tintSeparatorLayer: SimpleLayer
|
|
if let current = self.tintSeparatorLayer {
|
|
tintSeparatorLayer = current
|
|
} else {
|
|
tintSeparatorLayer = SimpleLayer()
|
|
self.tintSeparatorLayer = tintSeparatorLayer
|
|
self.tintContentLayer.addSublayer(tintSeparatorLayer)
|
|
}
|
|
tintSeparatorLayer.backgroundColor = UIColor.white.cgColor
|
|
tintSeparatorLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: UIScreenPixel))
|
|
|
|
tintSeparatorLayer.isHidden = !needsVibrancy
|
|
} else {
|
|
if let separatorLayer = self.separatorLayer {
|
|
self.separatorLayer = separatorLayer
|
|
separatorLayer.removeFromSuperlayer()
|
|
}
|
|
if let tintSeparatorLayer = self.tintSeparatorLayer {
|
|
self.tintSeparatorLayer = tintSeparatorLayer
|
|
tintSeparatorLayer.removeFromSuperlayer()
|
|
}
|
|
}
|
|
|
|
return (size, titleHorizontalOffset + textSize.width + clearWidth)
|
|
}
|
|
|
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
return super.hitTest(point, with: event)
|
|
}
|
|
|
|
func tapGesture(point: CGPoint) -> Bool {
|
|
if let groupEmbeddedView = self.groupEmbeddedView {
|
|
return groupEmbeddedView.tapGesture(point: self.convert(point, to: groupEmbeddedView))
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|