Skip to content

Instantly share code, notes, and snippets.

View jamesrochabrun's full-sized avatar
🇵🇪

James Rochabrun jamesrochabrun

🇵🇪
View GitHub Profile
/// 1
lazy var displayModeCustomButton: Button = {
let button = Button(type: .system, image: SplitViewControllerViewModel.displayModeButtonImageFor(self.displayMode), target: self, selector: #selector(togglePrefferDisplayModeExecutingCompletion))
button.constrainWidth(constant: 44.0)
button.constrainHeight(constant: 44.0)
button.imageEdgeInsets = .init(top: 8.0, left: 8.0, bottom: 8.0, right: 8.0)
return button
}()
// In UserProfileViewController (the master) we need:
// 1
protocol UserProfileFeedSelectionDelegate: AnyObject {
func postSelectedAt(_ indexPath: IndexPath)
}
// 2
weak var delegate: UserProfileFeedSelectionDelegate?
// 3
lazy private var contentDetailViewController: ContentDetailViewcontroller = {
/// 1 convenience init.
convenience init(viewControllers: [UIViewController]) {
self.init()
/// 2 set master and detail, it takes an array of view controllers.
self.viewControllers = viewControllers
/// 3 preferredDisplayMode, it defines the display mode of the split view controller,
/// .allVisible will display both master and detail.
preferredDisplayMode = .allVisible
/// set the delegate to self to allow the `SplitViewController` handle the UISplitViewControllerDelegate methods.
super.delegate = self
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
/// 1 - Set view Controllers using `TabBarViewModel`
/// 2 - This iteration will create a master veiw controller embedded in a navigation controller for each tab.
/// 3 - `inSplitViewControllerIfSupported` is a `UINavigationController` extension method that will embed it in a `UISplitViewController` if supported.
/// we will see the implementation later.
viewControllers = TabBarViewModel.allCases.map { NavigationController(rootViewController: $0.masterViewController).inSplitViewControllerIfSupported(for: $0) }
}
@jamesrochabrun
jamesrochabrun / navigationfadeonscrolling.swift
Created November 9, 2019 23:10
Math to animate Navigation bar on Scrolling
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let safeAreaTop = UIApplication.shared.windows.filter { $0.isKeyWindow }.first?.safeAreaInsets.top ?? 0
let navigationNeededOfset: CGFloat = safeAreaTop// + (navigationController?.navigationBar.frame.height ?? 0)
let offset = scrollView.contentOffset.y + navigationNeededOfset
let alpha = 1 - ((scrollView.contentOffset.y + navigationNeededOfset) / navigationNeededOfset)
// Use the alpha here
navigationController?.navigationBar.backgroundColor = .blue
navigationController?.navigationBar.transform = .init(translationX: 0, y: min(0, -offset))
class AbsoluteFrameAnimator: NSObject {
private var absoluteFrame: CGRect = CGRect.zero
init(duration: CGFloat) {
self.duration = duration
}
private let duration: CGFloat
@jamesrochabrun
jamesrochabrun / CollectionReusable.swift
Created June 24, 2019 15:32
Protocol Oriented Reuse Identifier.
protocol CollectionReusable {}
/// Disclaimer: From Apple UI engineer - its allow to force cast the cell in this method, if it fails its mostly another issue in the implementation.
/// MARK:- UITableView
extension CollectionReusable where Self: UITableViewCell {
@jamesrochabrun
jamesrochabrun / RecursiveEnumerations.swift
Created December 20, 2018 05:48
Recursive enumeration in Swift 4.2
import UIKit
// Helpers
// takes a list and checks if a given predicate is true for every element O(n)
func all<T>(_ xs: [T], predicate: (T) -> Bool) -> Bool {
for x in xs {
if !predicate(x) {
return false
}
@jamesrochabrun
jamesrochabrun / IntFromString.swift
Created November 18, 2018 02:03
Convert a String in to an Integer using a hashmap in Swift 4.2
func convert(_ textValue: String) -> Int{
var total = 0
var valueMap = [
"1" as Character: 1,
"2": 2,
"3": 3,
"4": 4,
"5": 5,
"6": 6,
func fadeHorizontalEdges(in collectionView: UICollectionView, modifier: CGFloat) {
let visibleCells = collectionView.visibleCells
guard !visibleCells.isEmpty else { return }
let firstCell = visibleCells.first!
let lastCell = visibleCells.last!
visibleCells.forEach { $0.alpha = 1 }