daily pastebin goal
47%
SHARE
TWEET

Untitled

a guest Jul 12th, 2018 59 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Foundation
  2.  
  3. final class ConcealingTitleView: UIView {
  4.     private let label = UILabel()
  5.     private var contentOffset: CGFloat = 0 {
  6.         didSet {
  7.             label.frame.origin.y = titleVerticalPositionAdjusted(by: contentOffset)
  8.         }
  9.     }
  10.     var text: String = "" {
  11.         didSet {
  12.             label.text = text
  13.             label.textColor = UIColor.white
  14.             label.font = UIFont.systemFont(ofSize: 17.0, weight: .semibold)
  15.             setNeedsLayout()
  16.         }
  17.     }
  18.    
  19.     // MARK: Initializers
  20.    
  21.     override init(frame: CGRect) {
  22.         super.init(frame: frame)
  23.        
  24.         addSubview(label)
  25.         clipsToBounds = true
  26.         isUserInteractionEnabled = false
  27.     }
  28.    
  29.     required init?(coder aDecoder: NSCoder) {
  30.         fatalError("init(coder:) has not been implemented")
  31.     }
  32.    
  33.     // MARK: View lifecycle
  34.    
  35.     override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
  36.         super.traitCollectionDidChange(previousTraitCollection)
  37.         sizeToFit()
  38.     }
  39.    
  40.     override func sizeThatFits(_ size: CGSize) -> CGSize {
  41.         if #available(iOS 11.0, *) {
  42.             return super.sizeThatFits(size)
  43.         } else {
  44.             let height = (typedSuperview() as? UINavigationBar)?.bounds.height ?? 0.0
  45.             let labelSize = label.sizeThatFits(CGSize(width: size.width, height: height))
  46.             return CGSize(width: min(labelSize.width, size.width), height: height)
  47.         }
  48.     }
  49.    
  50.     private func layoutSubviews_10() {
  51.         guard let navBar = typedSuperview() as? UINavigationBar else { return }
  52.         let center = convert(navBar.center, from: navBar)
  53.         let size = label.sizeThatFits(bounds.size)
  54.         let x = max(bounds.minX, center.x - size.width * 0.5)
  55.         let y: CGFloat
  56.        
  57.         if contentOffset == 0 {
  58.             y = bounds.maxY
  59.         } else {
  60.             y = titleVerticalPositionAdjusted(by: contentOffset)
  61.         }
  62.        
  63.         label.frame = CGRect(x: x, y: y, width: min(size.width, bounds.width), height: size.height)
  64.     }
  65.    
  66.     private func layoutSubviews_11() {
  67.         let size = label.sizeThatFits(bounds.size)
  68.         let x: CGFloat
  69.         let y: CGFloat
  70.        
  71.         x = bounds.midX - size.width * 0.5
  72.        
  73.         if contentOffset == 0 {
  74.             y = bounds.maxY
  75.         } else {
  76.             y = titleVerticalPositionAdjusted(by: contentOffset)
  77.         }
  78.        
  79.         label.frame = CGRect(x: x, y: y, width: size.width, height: size.height)
  80.     }
  81.    
  82.     override func layoutSubviews() {
  83.         super.layoutSubviews()
  84.        
  85.         if #available(iOS 11.0, *) {
  86.             layoutSubviews_11()
  87.         } else {
  88.             layoutSubviews_10()
  89.         }
  90.     }
  91.    
  92.     // MARK:
  93.    
  94.     /// Using the UIScrollViewDelegate it moves the inner UILabel to move up and down following the scroll offset.
  95.     ///
  96.     /// - Parameters:
  97.     ///   - scrollView: The scroll-view object in which the scrolling occurred.
  98.     ///   - threshold: The minimum distance that must be scrolled before the title view will begin scrolling up into view
  99.     func scrollViewDidScroll(_ scrollView: UIScrollView, threshold: CGFloat = 0) {
  100.         contentOffset = scrollView.contentOffset.y - threshold
  101.     }
  102.    
  103.     // MARK: Private
  104.    
  105.     private func titleVerticalPositionAdjusted(by yOffset: CGFloat) -> CGFloat {
  106.         let midY = bounds.midY - label.bounds.height * 0.5
  107.         return max(bounds.maxY - yOffset, midY).rounded()
  108.     }
  109. }
  110.  
  111. private extension UIView {
  112.     func typedSuperview<T: UIView>() -> T? {
  113.         var parent = superview
  114.        
  115.         while parent != nil {
  116.             if let view = parent as? T {
  117.                 return view
  118.             } else {
  119.                 parent = parent?.superview
  120.             }
  121.         }
  122.        
  123.         return nil
  124.     }
  125. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top