Skip to content

Instantly share code, notes, and snippets.

View marcpalmer's full-sized avatar
💭
Busy working on Concepts app, and Captionista

Marc Palmer marcpalmer

💭
Busy working on Concepts app, and Captionista
View GitHub Profile
@marcpalmer
marcpalmer / DebugMetrics.swift
Created July 6, 2020 23:45
Helper for rendering metrics of SwiftUI views in debugging
// Created by Marc Palmer on 13/02/2020.
//
// Usage: Add .debugMetrics(.yellow) or similar to any view
import Foundation
import SwiftUI
/// Renders the width and height of a view
struct DebugMetricsModifier: ViewModifier {
let colour: Color
@marcpalmer
marcpalmer / ScrollViewSnapIssue.swift
Last active October 22, 2023 06:19
Updated to correct problem with subscription being new every time state changes, fixed scrollTo so it works
import Combine
import SwiftUI
struct SnapPointPreferenceData {
let frame: Anchor<CGRect>
}
struct SnapPointPreferenceKey: PreferenceKey {
typealias Value = SnapPointPreferenceData?
@marcpalmer
marcpalmer / ExtendedScrollView.swift
Created March 5, 2020 21:20
Work in progress UIScrollView-alike in SwiftUI
//
// ContentView.swift
// ExtendedScrolView
//
// Created by Marc Palmer on 05/03/2020.
// Copyright © 2020 Montana Floss Co. Ltd. All rights reserved.
//
import SwiftUI
@marcpalmer
marcpalmer / TypealiasDefaultingInSubProtocol_TypeAliasNaturalApproach.swift
Created May 17, 2019 09:38
Example of sub-protocol typealias defaulting which results in compiler warning to use protocol constraints
import Foundation
// ****************************************************************************************
//
// Example of trying to supply a default type for an associated type in a sub-protocol
// and helper functions that use this default type in an extention on that sub-protocol.
// The natural way to achieve this by defining the typealias in the sub-protocol produces
// a compiler warning and fix-it suggesting use of protocol constraint.
//
// This approach: typealias
@marcpalmer
marcpalmer / TypealiasDefaultingInSubProtocol_AssociatedTypeRestatingApproach.swift
Last active May 17, 2019 09:38
Example of trying to avoid sub-protocol typealias defaulting compiler warning using associatedtype to re-state the type
import Foundation
// ****************************************************************************************
//
// Example of trying to supply a default type for an associated type in a sub-protocol
// and helper functions that use this default type in an extention on that sub-protocol.
// The natural way to achieve this by defining the typealias in the sub-protocol produces
// a compiler warning and fix-it suggesting use of protocol constraint.
//
// This approach: Re-stating the associated type as a more specific type
@marcpalmer
marcpalmer / TyoeSafeBuilders.swift
Last active January 2, 2019 21:11
Trying to find a way to make typesafe builders constrained on a Self type
//
// Paste this code into a playground to see the compiler error and have a shot at a solution.
// All suggestions gratefully received. This is really an exercise in seeing if there is a way to lock down
// intermediary command "binding" types to only those that relate to the same kind of Robot as the CommandBuilder expects.
//
// There is a compiler error when we try to add the actual binding to the builder:
//
// Collaborator with Constrained Self Conformance.playground:63:21: error: cannot convert
// value of type 'CommandBinding<MetalMickey, DanceCommand>' to expected argument type 'CommandBinding<_, _>'
// builder.add(dance)
@marcpalmer
marcpalmer / Flint-Subfeature-Iteration-Invoke-Example.swift
Last active August 13, 2018 15:16
An example of how you might iterate over a bunch of discrete features that provide similar functionality, such as photo filters
// Demo of iterating over subfeatures that all have a similar action and possibly performing that action.
/// Type-eraser for the action type so we can perform it irresepective of action type
struct AnyConditionalActionBinding<InputType, PresenterType> {
let _perform: (_ input: InputType, _ presenter: PresenterType) -> Bool
init<FeatureType, ActionType>(_ actionBinding: ConditionalActionBinding<FeatureType, ActionType>) where ActionType.InputType == InputType, ActionType.PresenterType == PresenterType {
_perform = { (_ input: InputType, _ presenter: PresenterType) -> Bool in
if let request = actionBinding.request() {
request.perform(input: input, presenter: presenter)
@marcpalmer
marcpalmer / .bash_profile
Last active May 30, 2018 11:05
Change your macOS bash prompt to include Xcode version and git branch + status
#
# Author: Marc Palmer
# Twitter: https://twitter.com/marcpalmerdev
# Blog: https://marcpalmer.net
#
# This is a .bash_profile file that you can write to your home directory to give
# you a custom shell prompt that will include the git branch and status of your
# current working dir as well as the current Xcode version.
#
# This is really handy when you're running multiple Xcode versions on your machine and have to run
@marcpalmer
marcpalmer / flint-conditional-conformance-6.swift
Created April 27, 2018 16:20
Flint conditional conformance blog part 6
noInputAction.perform(using: somePresenter)
noPresenterAction.perform(with: someInput)
noPresenterNoInputAction.perform()
@marcpalmer
marcpalmer / flint-conditional-conformance-5.swift
Created April 27, 2018 16:19
Flint conditional conformance blog part 5
extension StaticActionBinding where ActionType.PresenterType == NoPresenter {
public func perform(with input: ActionType.InputType,
completion: ((ActionOutcome) -> ())? = nil) {
}
}
extension StaticActionBinding where ActionType.InputType == NoInput {
public func perform(using presenter: ActionType.PresenterType,
completion: ((ActionOutcome) -> ())? = nil) {