Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2023-07-15 17:12:24 +02:00
commit affb0129ab
7 changed files with 137 additions and 56 deletions

View File

@ -362,6 +362,7 @@ private final class ChatListContainerItemNode: ASDisplayNode {
private var canReportPeer: Bool = false private var canReportPeer: Bool = false
private(set) var validLayout: (size: CGSize, insets: UIEdgeInsets, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, storiesInset: CGFloat)? private(set) var validLayout: (size: CGSize, insets: UIEdgeInsets, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, storiesInset: CGFloat)?
private var scrollingOffset: (navigationHeight: CGFloat, offset: CGFloat)?
init(context: AccountContext, controller: ChatListControllerImpl?, location: ChatListControllerLocation, filter: ChatListFilter?, chatListMode: ChatListNodeMode, previewing: Bool, isInlineMode: Bool, controlsHistoryPreload: Bool, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, becameEmpty: @escaping (ChatListFilter?) -> Void, emptyAction: @escaping (ChatListFilter?) -> Void, secondaryEmptyAction: @escaping () -> Void, openArchiveSettings: @escaping () -> Void, autoSetReady: Bool) { init(context: AccountContext, controller: ChatListControllerImpl?, location: ChatListControllerLocation, filter: ChatListFilter?, chatListMode: ChatListNodeMode, previewing: Bool, isInlineMode: Bool, controlsHistoryPreload: Bool, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, becameEmpty: @escaping (ChatListFilter?) -> Void, emptyAction: @escaping (ChatListFilter?) -> Void, secondaryEmptyAction: @escaping () -> Void, openArchiveSettings: @escaping () -> Void, autoSetReady: Bool) {
self.context = context self.context = context
@ -454,9 +455,13 @@ private final class ChatListContainerItemNode: ASDisplayNode {
strongSelf.emptyNode = emptyNode strongSelf.emptyNode = emptyNode
strongSelf.listNode.addSubnode(emptyNode) strongSelf.listNode.addSubnode(emptyNode)
if let (size, insets, _, _, _, _, _) = strongSelf.validLayout { if let (size, insets, _, _, _, _, _) = strongSelf.validLayout {
let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: size.width, height: size.height - insets.top - insets.bottom)) let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))
emptyNode.frame = emptyNodeFrame emptyNode.frame = emptyNodeFrame
emptyNode.updateLayout(size: emptyNodeFrame.size, transition: .immediate) emptyNode.updateLayout(size: size, insets: insets, transition: .immediate)
if let scrollingOffset = strongSelf.scrollingOffset {
emptyNode.updateScrollingOffset(navigationHeight: scrollingOffset.navigationHeight, offset: scrollingOffset.offset, transition: .immediate)
}
} }
emptyNode.alpha = 0.0 emptyNode.alpha = 0.0
transition.updateAlpha(node: emptyNode, alpha: 1.0) transition.updateAlpha(node: emptyNode, alpha: 1.0)
@ -736,13 +741,25 @@ private final class ChatListContainerItemNode: ASDisplayNode {
self.listNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: visualNavigationHeight + additionalTopInset, originalTopInset: originalNavigationHeight + additionalTopInset, storiesInset: storiesInset, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction) self.listNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: visualNavigationHeight + additionalTopInset, originalTopInset: originalNavigationHeight + additionalTopInset, storiesInset: storiesInset, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction)
if let emptyNode = self.emptyNode { if let emptyNode = self.emptyNode {
let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: listInsets.top), size: CGSize(width: size.width, height: size.height - listInsets.top - listInsets.bottom)) let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))
transition.updateFrame(node: emptyNode, frame: emptyNodeFrame) transition.updateFrame(node: emptyNode, frame: emptyNodeFrame)
emptyNode.updateLayout(size: emptyNodeFrame.size, transition: transition) emptyNode.updateLayout(size: emptyNodeFrame.size, insets: listInsets, transition: transition)
if let scrollingOffset = self.scrollingOffset {
emptyNode.updateScrollingOffset(navigationHeight: scrollingOffset.navigationHeight, offset: scrollingOffset.offset, transition: transition)
}
} }
self.layoutAdditionalPanels(transition: transition) self.layoutAdditionalPanels(transition: transition)
} }
func updateScrollingOffset(navigationHeight: CGFloat, offset: CGFloat, transition: ContainedViewLayoutTransition) {
self.scrollingOffset = (navigationHeight, offset)
if let emptyNode = self.emptyNode {
emptyNode.updateScrollingOffset(navigationHeight: navigationHeight, offset: offset, transition: transition)
}
}
} }
public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate { public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
@ -804,6 +821,8 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
private var disableItemNodeOperationsWhileAnimating: Bool = false private var disableItemNodeOperationsWhileAnimating: Bool = false
private var validLayout: (layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, storiesInset: CGFloat)? private var validLayout: (layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, storiesInset: CGFloat)?
private var scrollingOffset: (navigationHeight: CGFloat, offset: CGFloat)?
private var enableAdjacentFilterLoading: Bool = false private var enableAdjacentFilterLoading: Bool = false
private var panRecognizer: InteractiveTransitionGestureRecognizer? private var panRecognizer: InteractiveTransitionGestureRecognizer?
@ -1551,6 +1570,9 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
transition.animatePositionAdditive(node: itemNode, offset: CGPoint(x: -offset, y: 0.0)) transition.animatePositionAdditive(node: itemNode, offset: CGPoint(x: -offset, y: 0.0))
itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, storiesInset: storiesInset, transition: .immediate) itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, storiesInset: storiesInset, transition: .immediate)
if let scrollingOffset = strongSelf.scrollingOffset {
itemNode.updateScrollingOffset(navigationHeight: scrollingOffset.navigationHeight, offset: scrollingOffset.offset, transition: .immediate)
}
strongSelf.selectedId = id strongSelf.selectedId = id
if let currentItemNode = strongSelf.currentItemNodeValue { if let currentItemNode = strongSelf.currentItemNodeValue {
@ -1568,12 +1590,23 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
if let (layout, _, visualNavigationHeight, originalNavigationHeight, _, insets, _, _, inlineNavigationLocation, inlineNavigationTransitionFraction, storiesInset) = self.validLayout { if let (layout, _, visualNavigationHeight, originalNavigationHeight, _, insets, _, _, inlineNavigationLocation, inlineNavigationTransitionFraction, storiesInset) = self.validLayout {
itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, storiesInset: storiesInset, transition: .immediate) itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, storiesInset: storiesInset, transition: .immediate)
if let scrollingOffset = self.scrollingOffset {
itemNode.updateScrollingOffset(navigationHeight: scrollingOffset.navigationHeight, offset: scrollingOffset.offset, transition: .immediate)
}
return return
} }
} }
} }
} }
func updateScrollingOffset(navigationHeight: CGFloat, offset: CGFloat, transition: ContainedViewLayoutTransition) {
self.scrollingOffset = (navigationHeight, offset)
for (_, itemNode) in self.itemNodes {
itemNode.updateScrollingOffset(navigationHeight: navigationHeight, offset: offset, transition: transition)
}
}
public func update(layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, storiesInset: CGFloat, transition: ContainedViewLayoutTransition) { public func update(layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, storiesInset: CGFloat, transition: ContainedViewLayoutTransition) {
self.validLayout = (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction, storiesInset) self.validLayout = (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction, storiesInset)
@ -1647,6 +1680,9 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
} }
itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: itemInlineNavigationTransitionFraction, storiesInset: storiesInset, transition: nodeTransition) itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: itemInlineNavigationTransitionFraction, storiesInset: storiesInset, transition: nodeTransition)
if let scrollingOffset = self.scrollingOffset {
itemNode.updateScrollingOffset(navigationHeight: scrollingOffset.navigationHeight, offset: scrollingOffset.offset, transition: nodeTransition)
}
if wasAdded, case .animated = transition { if wasAdded, case .animated = transition {
animateSlidingIds.append(id) animateSlidingIds.append(id)
@ -2041,6 +2077,9 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
} else { } else {
mainOffset = navigationHeight mainOffset = navigationHeight
} }
self.mainContainerNode.updateScrollingOffset(navigationHeight: navigationHeight, offset: mainOffset, transition: transition)
mainOffset = min(mainOffset, ChatListNavigationBar.searchScrollHeight) mainOffset = min(mainOffset, ChatListNavigationBar.searchScrollHeight)
if abs(mainOffset) < 0.1 { if abs(mainOffset) < 0.1 {
mainOffset = 0.0 mainOffset = 0.0
@ -2354,11 +2393,6 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
guard let containerLayout = self.containerLayout else { guard let containerLayout = self.containerLayout else {
return return
} }
let _ = containerLayout
if let inlineStackContainerNode = self.inlineStackContainerNode {
let _ = inlineStackContainerNode
}
self.updateNavigationScrolling(navigationHeight: containerLayout.navigationBarHeight, transition: self.tempNavigationScrollingTransition ?? .immediate) self.updateNavigationScrolling(navigationHeight: containerLayout.navigationBarHeight, transition: self.tempNavigationScrollingTransition ?? .immediate)
} }

View File

@ -14,6 +14,7 @@ import ComponentFlow
import ArchiveInfoScreen import ArchiveInfoScreen
import ComponentDisplayAdapters import ComponentDisplayAdapters
import SwiftSignalKit import SwiftSignalKit
import ChatListHeaderComponent
final class ChatListEmptyNode: ASDisplayNode { final class ChatListEmptyNode: ASDisplayNode {
enum Subject { enum Subject {
@ -44,7 +45,8 @@ final class ChatListEmptyNode: ASDisplayNode {
private var animationSize: CGSize = CGSize() private var animationSize: CGSize = CGSize()
private var buttonIsHidden: Bool private var buttonIsHidden: Bool
private var validLayout: CGSize? private var validLayout: (size: CGSize, insets: UIEdgeInsets)?
private var scrollingOffset: (navigationHeight: CGFloat, offset: CGFloat)?
private var globalPrivacySettings: GlobalPrivacySettings = .default private var globalPrivacySettings: GlobalPrivacySettings = .default
private var archiveSettingsDisposable: Disposable? private var archiveSettingsDisposable: Disposable?
@ -144,8 +146,8 @@ final class ChatListEmptyNode: ASDisplayNode {
return return
} }
self.globalPrivacySettings = settings self.globalPrivacySettings = settings
if let size = self.validLayout { if let (size, insets) = self.validLayout {
self.updateLayout(size: size, transition: .immediate) self.updateLayout(size: size, insets: insets, transition: .immediate)
} }
}) })
} }
@ -213,8 +215,12 @@ final class ChatListEmptyNode: ASDisplayNode {
self.activityIndicator.type = .custom(theme.list.itemAccentColor, 22.0, 1.0, false) self.activityIndicator.type = .custom(theme.list.itemAccentColor, 22.0, 1.0, false)
if let size = self.validLayout { if let (size, insets) = self.validLayout {
self.updateLayout(size: size, transition: .immediate) self.updateLayout(size: size, insets: insets, transition: .immediate)
if let scrollingOffset = self.scrollingOffset {
self.updateScrollingOffset(navigationHeight: scrollingOffset.navigationHeight, offset: scrollingOffset.offset, transition: .immediate)
}
} }
} }
@ -230,44 +236,8 @@ final class ChatListEmptyNode: ASDisplayNode {
self.activityIndicator.isHidden = !self.isLoading self.activityIndicator.isHidden = !self.isLoading
} }
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) { func updateLayout(size: CGSize, insets: UIEdgeInsets, transition: ContainedViewLayoutTransition) {
self.validLayout = size self.validLayout = (size, insets)
if case .archive = self.subject {
let emptyArchive: ComponentView<Empty>
if let current = self.emptyArchive {
emptyArchive = current
} else {
emptyArchive = ComponentView()
self.emptyArchive = emptyArchive
}
let emptyArchiveSize = emptyArchive.update(
transition: Transition(transition),
component: AnyComponent(ArchiveInfoContentComponent(
theme: self.theme,
strings: self.strings,
settings: self.globalPrivacySettings,
openSettings: { [weak self] in
guard let self else {
return
}
self.openArchiveSettings()
}
)),
environment: {
},
containerSize: CGSize(width: size.width, height: size.height - 41.0)
)
if let emptyArchiveView = emptyArchive.view {
if emptyArchiveView.superview == nil {
self.view.addSubview(emptyArchiveView)
}
transition.updateFrame(view: emptyArchiveView, frame: CGRect(origin: CGPoint(x: floor((size.width - emptyArchiveSize.width) * 0.5), y: 41.0), size: emptyArchiveSize))
}
} else if let emptyArchive = self.emptyArchive {
self.emptyArchive = nil
emptyArchive.view?.removeFromSuperview()
}
let indicatorSize = self.activityIndicator.measure(CGSize(width: 100.0, height: 100.0)) let indicatorSize = self.activityIndicator.measure(CGSize(width: 100.0, height: 100.0))
transition.updateFrame(node: self.activityIndicator, frame: CGRect(origin: CGPoint(x: floor((size.width - indicatorSize.width) / 2.0), y: floor((size.height - indicatorSize.height - 50.0) / 2.0)), size: indicatorSize)) transition.updateFrame(node: self.activityIndicator, frame: CGRect(origin: CGPoint(x: floor((size.width - indicatorSize.width) / 2.0), y: floor((size.height - indicatorSize.height - 50.0) / 2.0)), size: indicatorSize))
@ -330,6 +300,63 @@ final class ChatListEmptyNode: ASDisplayNode {
transition.updateFrame(node: self.buttonNode, frame: buttonFrame) transition.updateFrame(node: self.buttonNode, frame: buttonFrame)
} }
func updateScrollingOffset(navigationHeight: CGFloat, offset: CGFloat, transition: ContainedViewLayoutTransition) {
self.scrollingOffset = (navigationHeight, offset)
guard let (size, _) = self.validLayout else {
return
}
if case .archive = self.subject {
let emptyArchive: ComponentView<Empty>
if let current = self.emptyArchive {
emptyArchive = current
} else {
emptyArchive = ComponentView()
self.emptyArchive = emptyArchive
}
let emptyArchiveSize = emptyArchive.update(
transition: Transition(transition),
component: AnyComponent(ArchiveInfoContentComponent(
theme: self.theme,
strings: self.strings,
settings: self.globalPrivacySettings,
openSettings: { [weak self] in
guard let self else {
return
}
self.openArchiveSettings()
}
)),
environment: {
},
containerSize: CGSize(width: size.width, height: 10000.0)
)
if let emptyArchiveView = emptyArchive.view {
if emptyArchiveView.superview == nil {
self.view.addSubview(emptyArchiveView)
}
let cancelledOutHeight: CGFloat = max(0.0, ChatListNavigationBar.searchScrollHeight - offset)
let visibleNavigationHeight: CGFloat = navigationHeight - ChatListNavigationBar.searchScrollHeight + cancelledOutHeight
let additionalOffset = min(0.0, -offset + ChatListNavigationBar.searchScrollHeight)
var archiveFrame = CGRect(origin: CGPoint(x: 0.0, y: visibleNavigationHeight + floorToScreenPixels((size.height - visibleNavigationHeight - emptyArchiveSize.height - 50.0) * 0.5)), size: emptyArchiveSize)
archiveFrame.origin.y = max(archiveFrame.origin.y, visibleNavigationHeight + 20.0)
if size.height - visibleNavigationHeight - emptyArchiveSize.height - 20.0 < 0.0 {
archiveFrame.origin.y += additionalOffset
}
transition.updateFrame(view: emptyArchiveView, frame: archiveFrame)
}
} else if let emptyArchive = self.emptyArchive {
self.emptyArchive = nil
emptyArchive.view?.removeFromSuperview()
}
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.buttonNode.frame.contains(point) { if self.buttonNode.frame.contains(point) {
return self.buttonNode.view.hitTest(self.view.convert(point, to: self.buttonNode.view), with: event) return self.buttonNode.view.hitTest(self.view.convert(point, to: self.buttonNode.view), with: event)

View File

@ -865,7 +865,7 @@ func chatListNodeEntriesForView(view: EngineChatList, state: ChatListNodeState,
} }
if displayArchiveIntro { if displayArchiveIntro {
result.append(.ArchiveIntro(presentationData: state.presentationData)) //result.append(.ArchiveIntro(presentationData: state.presentationData))
} else if !contacts.isEmpty && !result.contains(where: { entry in } else if !contacts.isEmpty && !result.contains(where: { entry in
if case .PeerEntry = entry { if case .PeerEntry = entry {
return true return true

View File

@ -2,7 +2,7 @@ import Foundation
import Postbox import Postbox
public struct CacheStorageSettings: Codable, Equatable { public struct CacheStorageSettings: Codable, Equatable {
public enum PeerStorageCategory: String, Codable, Hashable { public enum PeerStorageCategory: String, Codable, Hashable, CaseIterable {
case privateChats = "privateChats" case privateChats = "privateChats"
case groups = "groups" case groups = "groups"
case channels = "channels" case channels = "channels"
@ -61,6 +61,11 @@ public struct CacheStorageSettings: Codable, Equatable {
for item in items { for item in items {
categoryStorageTimeout[item.key] = item.value categoryStorageTimeout[item.key] = item.value
} }
for key in PeerStorageCategory.allCases {
if categoryStorageTimeout[key] == nil, let value = CacheStorageSettings.defaultSettings.categoryStorageTimeout[key] {
categoryStorageTimeout[key] = value
}
}
self.categoryStorageTimeout = categoryStorageTimeout self.categoryStorageTimeout = categoryStorageTimeout
} else { } else {
self.categoryStorageTimeout = CacheStorageSettings.defaultSettings.categoryStorageTimeout self.categoryStorageTimeout = CacheStorageSettings.defaultSettings.categoryStorageTimeout

View File

@ -111,14 +111,14 @@ public final class ArchiveInfoContentComponent: Component {
let iconSize: CGFloat = 90.0 let iconSize: CGFloat = 90.0
if self.iconBackground.image == nil { if self.iconBackground.image == nil {
let backgroundColors = component.theme.chatList.pinnedArchiveAvatarColor.backgroundColors.colors let backgroundColors = component.theme.chatList.pinnedArchiveAvatarColor.backgroundColors.colors
let colors: NSArray = [backgroundColors.0.cgColor, backgroundColors.1.cgColor] let colors: NSArray = [backgroundColors.1.cgColor, backgroundColors.0.cgColor]
self.iconBackground.image = generateGradientFilledCircleImage(diameter: iconSize, colors: colors) self.iconBackground.image = generateGradientFilledCircleImage(diameter: iconSize, colors: colors)
} }
let iconBackgroundFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - iconSize) * 0.5), y: contentHeight), size: CGSize(width: iconSize, height: iconSize)) let iconBackgroundFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - iconSize) * 0.5), y: contentHeight), size: CGSize(width: iconSize, height: iconSize))
transition.setFrame(view: self.iconBackground, frame: iconBackgroundFrame) transition.setFrame(view: self.iconBackground, frame: iconBackgroundFrame)
if self.iconForeground.image == nil { if self.iconForeground.image == nil {
self.iconForeground.image = generateTintedImage(image: UIImage(bundleImageName: "Avatar/ArchiveAvatarIcon"), color: .white) self.iconForeground.image = generateTintedImage(image: UIImage(bundleImageName: "Chat List/ArchiveIconLarge"), color: .white)
} }
if let image = self.iconForeground.image { if let image = self.iconForeground.image {
transition.setFrame(view: self.iconForeground, frame: CGRect(origin: CGPoint(x: iconBackgroundFrame.minX + floor((iconBackgroundFrame.width - image.size.width) * 0.5), y: iconBackgroundFrame.minY + floor((iconBackgroundFrame.height - image.size.height) * 0.5)), size: image.size)) transition.setFrame(view: self.iconForeground, frame: CGRect(origin: CGPoint(x: iconBackgroundFrame.minX + floor((iconBackgroundFrame.width - image.size.width) * 0.5), y: iconBackgroundFrame.minY + floor((iconBackgroundFrame.height - image.size.height) * 0.5)), size: image.size))

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "Union.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,3 @@
<svg width="39" height="38" viewBox="0 0 39 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.490471 2.70704C0 3.66965 0 4.92976 0 7.45V9.25H39V7.45C39 4.92976 39 3.66965 38.5095 2.70704C38.0781 1.86031 37.3897 1.1719 36.543 0.740471C35.5804 0.25 34.3202 0.25 31.8 0.25H7.2C4.67976 0.25 3.41965 0.25 2.45704 0.740471C1.61031 1.1719 0.921901 1.86031 0.490471 2.70704ZM1.5 10.75H37.5V30.55C37.5 33.0702 37.5 34.3304 37.0095 35.293C36.5781 36.1397 35.8897 36.8281 35.043 37.2595C34.0804 37.75 32.8202 37.75 30.3 37.75H8.7C6.17976 37.75 4.91965 37.75 3.95704 37.2595C3.11031 36.8281 2.4219 36.1397 1.99047 35.293C1.5 34.3304 1.5 33.0702 1.5 30.55V10.75ZM12 16.75C12 15.9216 12.6716 15.25 13.5 15.25H25.5C26.3284 15.25 27 15.9216 27 16.75C27 17.5784 26.3284 18.25 25.5 18.25H13.5C12.6716 18.25 12 17.5784 12 16.75Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 887 B