Skip to content

Instantly share code, notes, and snippets.

View simonbs's full-sized avatar
🐼

Simon B. Støvring simonbs

🐼
View GitHub Profile
@simonbs
simonbs / KeyboardAvoidingView.swift
Created January 24, 2022 21:29
Avoid undocked keyboard at bottom.
// Sample code made in response to this tweet:
// https://twitter.com/stroughtonsmith/status/1485719749673820163
final class MainView: UIView {
private let textView: UITextView = {
let this = UITextView()
this.translatesAutoresizingMaskIntoConstraints = false
this.text = "I'm a text view"
this.font = .preferredFont(forTextStyle: .body)
this.textColor = .label
@simonbs
simonbs / Unleashed.js
Created October 13, 2021 06:36
Scriptable widget that counts down to Apple's Unleashed event on October 18th
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: blue; icon-glyph: apple-alt;
const TITLE = ""
const DATE = "2021-10-18T17:00:00Z"
const BG_IMG_URL = "https://i.ibb.co/YQ09XTW/background.png"
const TITLE_IMG_URL = "https://i.ibb.co/qYH3Y9w/text.png"
const TITLE_IMG_SIZE = new Size(155, 25)
const LINK = "https://www.youtube.com/watch?v=exM1uajp--A"
@simonbs
simonbs / ToolbarController.swift
Created July 23, 2021 06:22
Enable/disable a toolbar item in a Catalyst app.
final class ToolbarController, NSObject, NSToolbarDelegate {
var isBackButtonEnabled = false {
didSet {
if isBackButtonEnabled != oldValue {
reloadBackItem()
}
}
}
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
@simonbs
simonbs / Tour de France Profile.js
Created July 13, 2021 14:37
Scriptable script showing a profile of the current Tour de France stage
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: yellow; icon-glyph: bicycle;
let stages = await loadStages()
let stage = findStage(stages)
if (stage == null) {
let widget = createTournamentOverWidget()
await widget.presentMedium()
} else {
let stageDetails = await loadStageDetails(stage.id)
@simonbs
simonbs / Today's Pollen Count.js
Last active July 17, 2022 17:35
Shows the current pollen counts. Pulls data from a Danish provider and only works in Denmark.
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-green; icon-glyph: tree;
const STATION_VIBORG = "49"
const STATION_CPH = "48"
const IDS = {
BIRCH: "7",
MUGWORT: "31",
ALDER: "1",
ELM: "4",
@simonbs
simonbs / childForStatusBarStyle.swift
Last active September 25, 2023 14:49
It seems that -childForStatusBarStyle: isn’t called on a UIViewController that is presented from a SwiftUI view using UIViewControllerRepresentable. Or am I doing something wrong? I came up with this *ugly* workaround that swizzles -childForStatusBarStyle: to return an associated object when present and uses the default implementation as fallback.
// We'll store a UIViewController as an associated object and don't want to store a strong reference to it.
private final class WeakBoxedValue<T: AnyObject>: NSObject {
private(set) weak var value: T?
init(_ value: T?) {
self.value = value
}
}
// Use associated objects to a UIViewController that should determine the status bar appearance.
@simonbs
simonbs / UserDefault.swift
Last active March 3, 2024 11:38
Property wrapper that stores values in UserDefaults and works with SwiftUI and Combine.
/**
* I needed a property wrapper that fulfilled the following four requirements:
*
* 1. Values are stored in UserDefaults.
* 2. Properties using the property wrapper can be used with SwiftUI.
* 3. The property wrapper exposes a Publisher to be used with Combine.
* 4. The publisher is only called when the value is updated and not
* when_any_ value stored in UserDefaults is updated.
*
* First I tried using SwiftUI's builtin @AppStorage property wrapper
@simonbs
simonbs / Indie App Santa.js
Last active December 2, 2020 20:46
Indie App Santa
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: red; icon-glyph: calendar-alt;
let data = await loadData()
let app = data.today[0]
let widget = null
if (config.runsInWidget) {
if (config.widgetFamily == "small") {
widget = await createSmallWidget(app)
} else {
@simonbs
simonbs / One More Thing.js
Last active February 17, 2024 11:04
Countdown to Apple's "One More Thing" event on November 10th, 2020
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-purple; icon-glyph: apple-alt;
const TITLE = "One More Thing"
const DATE = "2020-11-10T17:00:00Z"
const IMG_URL = "https://i.ibb.co/f2SN2Wb/bg.png"
let widget = await createWidget()
if (config.runsInWidget) {
Script.setWidget(widget)
@simonbs
simonbs / Animals of the Day.js
Created November 1, 2020 13:05
Shows an image of an animal
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: purple; icon-glyph: paw;
let pandaURL = "https://c402277.ssl.cf1.rackcdn.com/photos/7749/images/story_full_width/HI_204718.jpg?1414503137"
let slothURL = "https://c402277.ssl.cf1.rackcdn.com/photos/6518/images/story_full_width/iStock_000011145477Large_mini_%281%29.jpg?1394632882"
let redPandaURL = "https://c402277.ssl.cf1.rackcdn.com/photos/8036/images/story_full_width/WEB_279173.jpg?1418412345"
let pandaImg = await getImage(pandaURL)
let slothImg = await getImage(slothURL)
let redPandaImg = await getImage(redPandaURL)