mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Swift
		
	
| // Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
 | |
| 
 | |
| import SwiftUI
 | |
| import UIKit
 | |
| import SessionUtilitiesKit
 | |
| 
 | |
| struct ViewControllerHolder {
 | |
|     weak var value: UIViewController?
 | |
| }
 | |
| 
 | |
| struct ViewControllerKey: EnvironmentKey {
 | |
|     static var defaultValue: ViewControllerHolder {
 | |
|         return ViewControllerHolder(value: Singleton.appContext.mainWindow?.rootViewController)
 | |
|     }
 | |
| }
 | |
| 
 | |
| extension EnvironmentValues {
 | |
|     public var viewController: UIViewController? {
 | |
|         get { return self[ViewControllerKey.self].value }
 | |
|         set { self[ViewControllerKey.self].value = newValue }
 | |
|     }
 | |
| }
 | |
| 
 | |
| public struct UIView_SwiftUI: UIViewRepresentable {
 | |
|     public typealias UIViewType = UIView
 | |
|     
 | |
|     private let view: UIView
 | |
|     
 | |
|     public init(view: UIView) {
 | |
|         self.view = view
 | |
|     }
 | |
|     
 | |
|     public func makeUIView(context: Context) -> UIView {
 | |
|         return self.view
 | |
|     }
 | |
|     
 | |
|     public func updateUIView(_ uiView: UIView, context: Context) {
 | |
|         uiView.layoutIfNeeded()
 | |
|     }
 | |
| }
 | |
| 
 | |
| // MARK: MaxWidthEqualizer
 | |
| /// PreferenceKey to report the max width of the view.
 | |
| struct MaxWidthPreferenceKey: PreferenceKey {
 | |
|     static var defaultValue: CGFloat = 0.0
 | |
| 
 | |
|     // We `reduce` to just take the max value from all values reported.
 | |
|     static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
 | |
|         value = max(value, nextValue())
 | |
|     }
 | |
|     
 | |
| }
 | |
| 
 | |
| /// Convenience view modifier that observe its size, and notify the value back to parent view via `MaxWidthPreferenceKey`.
 | |
| public struct MaxWidthNotify: ViewModifier {
 | |
|     
 | |
|     /// We embed a transparent background view, to the current view to get the size via `GeometryReader`.
 | |
|     /// The `MaxWidthPreferenceKey` will be reported, when the frame of this view is updated.
 | |
|     private var sizeView: some View {
 | |
|         GeometryReader { geometry in
 | |
|             Color.clear.preference(key: MaxWidthPreferenceKey.self, value: geometry.frame(in: .global).size.width)
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     public func body(content: Content) -> some View {
 | |
|         content.background(sizeView)
 | |
|     }
 | |
|     
 | |
| }
 | |
| 
 | |
| /// Convenience modifier to use in the parent view to observe `MaxWidthPreferenceKey` from children, and bind the value to `$width`.
 | |
| public struct MaxWidthEqualizer: ViewModifier {
 | |
|     @Binding var width: CGFloat?
 | |
|     
 | |
|     public static var notify: MaxWidthNotify {
 | |
|         MaxWidthNotify()
 | |
|     }
 | |
|     
 | |
|     public init(width: Binding<CGFloat?>) {
 | |
|         self._width = width
 | |
|     }
 | |
|     
 | |
|     public func body(content: Content) -> some View {
 | |
|         content.onPreferenceChange(MaxWidthPreferenceKey.self) { value in
 | |
|             let oldWidth: CGFloat = width ?? 0
 | |
|             if value > oldWidth {
 | |
|                 width = value
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |