Skip to content

Instantly share code, notes, and snippets.

View jamesrochabrun's full-sized avatar
🇵🇪

James Rochabrun jamesrochabrun

🇵🇪
View GitHub Profile
@jamesrochabrun
jamesrochabrun / CombineAPI.Swift
Created July 23, 2020 01:08
Generic nertworking layer using Combine.
// 1
protocol CombineAPI {
var session: URLSession { get }
func execute<T>(_ request: URLRequest, decodingType: T.Type, queue: DispatchQueue, retries: Int) -> AnyPublisher<T, Error> where T: Decodable
}
// 2
extension CombineAPI {
func execute<T>(_ request: URLRequest,
// 1
@main
struct SwiftUIMoviesApp: App {
// 2
@StateObject private var model = MoviesProvider()
// 3
var body: some Scene {
WindowGroup {
// 4
@jamesrochabrun
jamesrochabrun / GenericList.swift
Created July 23, 2020 00:34
GenericList using Swift UI.
// 1
struct GenericList<Element, RowContent: View>: View where Element: Identifiable {
// 2
private let items: [Element]
private let rowContent: (Element) -> RowContent
// 3
public init(_ items: [Element], @ViewBuilder rowContent: @escaping (Element) -> RowContent) {
self.items = items
import UIKit
class Vc: UIViewController {
var top: CGFloat? { 8 }
}
let viewController = Vc()
let a: CGFloat = 1.0
let b: CGFloat = 2.0
let result = (viewController as? Vc)?.top ?? a < b ? 10 : 15
class FrameTransitionAnimator: NSObject {
enum OverlayType {
case dim
case blur(style: UIBlurEffect.Style)
}
enum DimTransitionMode: Int {
case present, dismiss
/// 1
protocol DisplayModeUpdatable {
func displayModeWillChangeTo(_ displayMode: UISplitViewController.DisplayMode)
func displayModeDidChangeTo(_ displayMode: UISplitViewController.DisplayMode)
}
////
@objc func togglePrefferDisplayModeExecutingCompletion(_ executing: Bool = true) {
UIView.animate(withDuration: 0.3, animations: {
self.preferredDisplayMode = self.displayMode == .allVisible ? .primaryHidden : .allVisible
/// 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) }
}