Skip to content

Instantly share code, notes, and snippets.

import Foundation
import SwiftUI
// Implemented based on this article:
// https://noahgilmore.com/blog/swiftui-self-sizing-cells
// MARK: - HostingTableViewCell
public final class HostingTableViewCell<Content: View>: UITableViewCell {
private var hostingController = UIHostingController<Content?>(rootView: nil)
final class ExampleViewControllerTests: XCTestCase {
private lazy var viewController: ExampleViewController = {
let viewController = ExampleViewController(customView: self.mockCustomView,
presenter: self.mockPresenter)
}()
private let mockCustomView = MockExampleCustomView()
private let mockPresenter = MockExamplePresenter()
func testViewWillAppear() {
final class MockExampleCustomView: CustomViewProtocol {
var didCallRenderData: Bool = false
var dataToBeRender: String?
var didCallRenderLoading: Bool = false
func render(data: String) {
dataToBeRender = data
didCallRenderData = true
}
typealias CustomViewDelegate = UITableViewDelegate & UITableViewDataSource
protocol CustomViewProtocol where Self: UIView {
func render(data: String)
func renderLoadingState()
}
final class ExampleViewController: UIViewController {
private let customView: CustomViewProtocol
private let presenter: ExamplePresenter
protocol ExamplePresenter {
func fetchData()
}
// Delegate that notifies the ViewController, so ViewController will conform to this protocol
protocol PresenterDelegate: AnyObject {
func didFetch(data: String)
}
protocol ButtonDelegate: AnyObject {
func buttonDidTouched(data: String)
}
extension ExampleViewController: ButtonDelegate {
func buttonDidTouched(data: String) {
let nextScene = NextViewController(data: data)
self.navigationController?.pushViewController(nextScene, animated: true)
}
}
protocol NextCustomViewProtocol where Self: UIView {}
final class DefaultNextCustomView: UIView, NextCustomViewProtocol {
override init(frame: CGRect = .zero) {
super.init(frame: frame)
// setup here
}
required init?(coder: NSCoder) {
fatalError()
extension UIColor {
static let mainColor: UIColor = UIColor(red: 0.3, green: 0.6, blue: 0.6, alpha: 1)
static let backgroundColor: UIColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
}
extension UIFont {
static let mainFont: UIFont = UIFont(name: "helvetica", size: 14)!
static let titleFont: UIFont = UIFont(name: "helvetica", size: 22)!
}
private func configureHorizontalStack() {
redView.addSubview(horizontalStack)
// Cartography method to declared constraints
let constraints = [
horizontalStack.leadingAnchor.constraint(equalTo: redView.leadingAnchor, constant: 30),
horizontalStack.trailingAnchor.constraint(equalTo: redView.trailingAnchor, constant: -30),
horizontalStack.topAnchor.constraint(equalTo: redView.topAnchor, constant: 25),
horizontalStack.bottomAnchor.constraint(equalTo: redView.bottomAnchor, constant: -25)
]
NSLayoutConstraint.activate(constraints)
private func configureHorizontalStack() {
redView.addSubview(horizontalStack)
// Cartography method to declared constraints
constrain(horizontalStack, redView) { view, superview in
view.leading == superview.leading + 30
view.trailing == superview.trailing - 30
view.top == superview.top + 25
view.bottom == superview.bottom - 25
}
}