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.
		
		
		
		
		
			
		
			
	
	
		
			179 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Swift
		
	
		
		
			
		
	
	
			179 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Swift
		
	
| 
											7 years ago
										 | // | ||
| 
											7 years ago
										 | //  Copyright (c) 2019 Open Whisper Systems. All rights reserved. | ||
| 
											7 years ago
										 | // | ||
|  | 
 | ||
|  | public protocol CaptionContainerViewDelegate: class { | ||
|  |     func captionContainerViewDidUpdateText(_ captionContainerView: CaptionContainerView) | ||
|  | } | ||
|  | 
 | ||
|  | public class CaptionContainerView: UIView { | ||
|  | 
 | ||
|  |     weak var delegate: CaptionContainerViewDelegate? | ||
|  | 
 | ||
|  |     var currentText: String? { | ||
|  |         get { return currentCaptionView.text } | ||
|  |         set { | ||
|  |             currentCaptionView.text = newValue | ||
|  |             delegate?.captionContainerViewDidUpdateText(self) | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     var pendingText: String? { | ||
|  |         get { return pendingCaptionView.text } | ||
|  |         set { | ||
|  |             pendingCaptionView.text = newValue | ||
|  |             delegate?.captionContainerViewDidUpdateText(self) | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     func updatePagerTransition(ratioComplete: CGFloat) { | ||
| 
											5 years ago
										 |         if let currentText = self.currentText, currentText.count > 0 { | ||
| 
											7 years ago
										 |             currentCaptionView.alpha = 1 - ratioComplete | ||
|  |         } else { | ||
|  |             currentCaptionView.alpha = 0 | ||
|  |         } | ||
|  | 
 | ||
| 
											5 years ago
										 |         if let pendingText = self.pendingText, pendingText.count > 0 { | ||
| 
											7 years ago
										 |             pendingCaptionView.alpha = ratioComplete | ||
|  |         } else { | ||
|  |             pendingCaptionView.alpha = 0 | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     func completePagerTransition() { | ||
|  |         updatePagerTransition(ratioComplete: 1) | ||
|  | 
 | ||
|  |         // promote "pending" to "current" caption view. | ||
|  |         let oldCaptionView = self.currentCaptionView | ||
|  |         self.currentCaptionView = self.pendingCaptionView | ||
|  |         self.pendingCaptionView = oldCaptionView | ||
|  |         self.pendingText = nil | ||
| 
											5 years ago
										 |         self.currentCaptionView.alpha = 1 | ||
|  |         self.pendingCaptionView.alpha = 0 | ||
| 
											7 years ago
										 |     } | ||
|  | 
 | ||
|  |     // MARK: Initializers | ||
|  | 
 | ||
|  |     override init(frame: CGRect) { | ||
|  |         super.init(frame: frame) | ||
|  | 
 | ||
|  |         setContentHuggingHigh() | ||
|  |         setCompressionResistanceHigh() | ||
|  | 
 | ||
|  |         addSubview(currentCaptionView) | ||
|  |         currentCaptionView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top) | ||
|  |         currentCaptionView.autoPinEdge(toSuperviewEdge: .top, withInset: 0, relation: .greaterThanOrEqual) | ||
|  | 
 | ||
|  |         pendingCaptionView.alpha = 0 | ||
|  |         addSubview(pendingCaptionView) | ||
|  |         pendingCaptionView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top) | ||
|  |         pendingCaptionView.autoPinEdge(toSuperviewEdge: .top, withInset: 0, relation: .greaterThanOrEqual) | ||
|  |     } | ||
|  | 
 | ||
| 
											7 years ago
										 |     public required init?(coder aDecoder: NSCoder) { | ||
| 
											7 years ago
										 |         fatalError("init(coder:) has not been implemented") | ||
|  |     } | ||
|  | 
 | ||
|  |     // MARK: Subviews | ||
|  | 
 | ||
|  |     private var pendingCaptionView: CaptionView = CaptionView() | ||
|  |     private var currentCaptionView: CaptionView = CaptionView() | ||
|  | } | ||
|  | 
 | ||
|  | private class CaptionView: UIView { | ||
|  | 
 | ||
|  |     var text: String? { | ||
|  |         get { return textView.text } | ||
|  | 
 | ||
|  |         set { | ||
|  |             if let captionText = newValue, captionText.count > 0 { | ||
|  |                 textView.text = captionText | ||
|  |             } else { | ||
|  |                 textView.text = nil | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     // MARK: Subviews | ||
|  | 
 | ||
|  |     let textView: CaptionTextView = { | ||
|  |         let textView = CaptionTextView() | ||
|  | 
 | ||
|  |         textView.font = UIFont.ows_dynamicTypeBody | ||
| 
											6 years ago
										 |         textView.textColor = Colors.text | ||
| 
											7 years ago
										 |         textView.backgroundColor = .clear | ||
|  |         textView.isEditable = false | ||
|  |         textView.isSelectable = false | ||
|  | 
 | ||
|  |         return textView | ||
|  |     }() | ||
|  | 
 | ||
|  |     let scrollFadeView = GradientView(from: .clear, to: .black) | ||
|  | 
 | ||
|  |     // MARK: Initializers | ||
|  | 
 | ||
|  |     override init(frame: CGRect) { | ||
|  |         super.init(frame: frame) | ||
|  | 
 | ||
|  |         addSubview(textView) | ||
|  |         textView.autoPinEdgesToSuperviewMargins() | ||
|  | 
 | ||
|  |         addSubview(scrollFadeView) | ||
|  |         scrollFadeView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top) | ||
|  |         scrollFadeView.autoSetDimension(.height, toSize: 20) | ||
|  |     } | ||
|  | 
 | ||
|  |     required init?(coder aDecoder: NSCoder) { | ||
|  |         fatalError("init(coder:) has not been implemented") | ||
|  |     } | ||
|  | 
 | ||
|  |     // MARK: UIView overrides | ||
|  | 
 | ||
|  |     override func layoutSubviews() { | ||
|  |         super.layoutSubviews() | ||
|  |         scrollFadeView.isHidden = !textView.doesContentNeedScroll | ||
|  |     } | ||
|  | 
 | ||
|  |     // MARK: - | ||
|  | 
 | ||
|  |     class CaptionTextView: UITextView { | ||
|  | 
 | ||
|  |         var kMaxHeight: CGFloat = ScaleFromIPhone5(200) | ||
|  | 
 | ||
|  |         override var text: String! { | ||
|  |             didSet { | ||
|  |                 invalidateIntrinsicContentSize() | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         override var font: UIFont? { | ||
|  |             didSet { | ||
|  |                 invalidateIntrinsicContentSize() | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         var doesContentNeedScroll: Bool { | ||
|  |             return self.bounds.height == kMaxHeight | ||
|  |         } | ||
|  | 
 | ||
|  |         override func layoutSubviews() { | ||
|  |             super.layoutSubviews() | ||
|  | 
 | ||
|  |             // Enable/disable scrolling depending on wether we've clipped | ||
|  |             // content in `intrinsicContentSize` | ||
| 
											7 years ago
										 |             isScrollEnabled = doesContentNeedScroll | ||
| 
											7 years ago
										 |         } | ||
|  | 
 | ||
|  |         override var intrinsicContentSize: CGSize { | ||
|  |             var size = super.intrinsicContentSize | ||
|  | 
 | ||
| 
											7 years ago
										 |             if size.height == UIView.noIntrinsicMetric { | ||
| 
											7 years ago
										 |                 size.height = layoutManager.usedRect(for: textContainer).height + textContainerInset.top + textContainerInset.bottom | ||
|  |             } | ||
|  |             size.height = min(kMaxHeight, size.height) | ||
|  | 
 | ||
|  |             return size | ||
|  |         } | ||
|  |     } | ||
|  | } |