Skip to content

Instantly share code, notes, and snippets.

@yannxou
yannxou / View+BindingSync.swift
Last active July 16, 2024 04:25
SwiftUI: Synchronize bindings
import SwiftUI
extension View {
/// Synchronizes the bindings so changes in any of them are propagated to the other.
///
/// The following example shows how to synchronize a Published property in a view model with a Binding used for presenting a sheet:
/// ```
/// class ViewModel: ObservableObject {
/// @Published var isPresented = false
@yannxou
yannxou / PassDownFocusState.swift
Created January 20, 2023 14:28
Pass FocusState property to child views
// source: https://developer.apple.com/forums/thread/682448
struct Parent: View {
@FocusState var focusedField: UUID?
var body: some View {
VStack {
Child(focusedField: _focusedField)
}
}
@yannxou
yannxou / UIDevice+CatalystOptimized.swift
Created January 14, 2023 14:34
Swift: Check if app running as Catalyst with 'Optimized for mac' setting enabled
// Credit: https://steipete.com/posts/forbidden-controls-in-catalyst-mac-idiom/
extension UIDevice {
/// Checks if we run in Mac Catalyst Optimized For Mac Idiom
var isCatalystMacIdiom: Bool {
if #available(iOS 14, *) {
return UIDevice.current.userInterfaceIdiom == .mac
} else {
return false
}
@yannxou
yannxou / iOS-Simulator-add-files.md
Last active September 5, 2024 09:11
Add files to iOS simulator

How to add files to the iOS simulator

Tested with macOS Ventura and xcode 14.

Files can be added by:

A. Drag & drop the file to the iOS simulator

This is the easy way but image/video files are always added to the Photos app. Other kind of files like PDF are added to the Files app.

@yannxou
yannxou / Array+Appending.swift
Created December 9, 2022 10:02
Swift Array appending (the functional way)
public extension Array {
/// Adds the elements of a sequence to the end of the array and returns a copy of it.
///
/// This example creates a new array containing the elements of a
/// `Range<Int>` instance added to an array of integers
///
/// let array = [1, 2, 3, 4, 5]
/// let numbers = array.appending(contentsOf: 10...15)
/// print(numbers)
@yannxou
yannxou / MarkdownLinkView.swift
Created December 5, 2022 11:04
Handle link tap in a SwiftUI Markdown Text
import SwiftUI
public struct MarkdownLinkView: View {
@State private var url: URL?
public var body: some View {
VStack(spacing: 20) {
Text("""
**Plain text**:
[This is a tappable link](https://www.google.com)
@yannxou
yannxou / AbletonLinkDownbeatSync.rb
Created November 30, 2022 12:59
Sonic Pi snippet for Ableton Link downbeat sync
# Credits: https://in-thread.sonic-pi.net/t/demo-of-experimental-ableton-link-with-sonic-pi/5869/28
# Call beat_fix with desired quantum just before defining your loops
use_bpm :link
sched_time = 0.5
$latency = 0 + sched_time*1000.00
def beat_fix(quantum=4)
diff = @tau_api.link_current_time_and_beat(false)[1] % quantum
x = ((quantum-diff) + 0 - rt($latency/1000.0)) % quantum
@yannxou
yannxou / XCTAssertCollection.swift
Last active November 24, 2022 17:48
XCTAssert helpers for Collections
import XCTest
func XCTAssertEmpty<T>(_ expression: @autoclosure () throws -> T, _ message: @autoclosure () -> String = "", file: StaticString = #filePath, line: UInt = #line) where T : Collection {
XCTAssertTrue(try expression().isEmpty, message(), file: file, line: line)
}
func XCTAssertNotEmpty<T>(_ expression: @autoclosure () throws -> T, _ message: @autoclosure () -> String = "", file: StaticString = #filePath, line: UInt = #line) where T : Collection {
XCTAssertFalse(try expression().isEmpty, message(), file: file, line: line)
}
@yannxou
yannxou / CancellableTestPlayground.swift
Created June 22, 2022 12:12
CancellableTestPlayground #Swift #Combine
// Playground to showcase AnyCancellable instances are not automatically released upon completion if they're stored with the `store` function
import Combine
class LongLivedObject {
private(set) var bag = Set<AnyCancellable>()
func callCombineOperation() {
[1,2,3].publisher.sink {
print("completed: \($0)")
} receiveValue: {
@yannxou
yannxou / ForEachIndexed.swift
Created March 23, 2022 11:53
ForEachIndexed #SwiftUI
// Credits: https://onmyway133.com/posts/how-to-use-foreach-with-indices-in-swiftui/
import SwiftUI
func ForEachWithIndex<Data: RandomAccessCollection, Content: View>(
_ data: Data,
@ViewBuilder content: @escaping (Data.Index, Data.Element) -> Content)
-> some View where Data.Element: Identifiable, Data.Element: Hashable {
ForEach(Array(zip(data.indices, data)), id: \.1) { index, element in
content(index, element)