Skip to content

Instantly share code, notes, and snippets.

View natpenguin's full-sized avatar
🐧

Yuji Taniguchi natpenguin

🐧
View GitHub Profile
@natpenguin
natpenguin / SpreadsheetView.swift
Last active February 18, 2023 03:38
A view like spreadsheet in SwiftUI
import SwiftUI
struct SpreadsheetView<ColumnView: View, RowView: View, ContentView: View, Column: Hashable, Row: Hashable>: View {
init(
columns: [Column],
rows: [Row],
columnWidth: CGFloat,
columnHeight: CGFloat,
rowWidth: CGFloat,
rowHeight: CGFloat,
@natpenguin
natpenguin / SizeCompatibleNavigationView.swift
Created July 25, 2022 07:15
Applying child view size to parent view
import SwiftUI
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
struct SizeCompatibleNavigationView<Content: View>: View {
@natpenguin
natpenguin / Firestore+DeclarativeDataFetching.swift
Last active May 9, 2022 00:50
A propertyWrapper for supporting declarative data fetching on SwiftUI with Firebase Cloud Firestore
@propertyWrapper
struct CollectionListener<Document: Codable>: DynamicProperty {
final class FirestoreDocumentsListener {
typealias OnUpdate = ([Document]) -> Void
private var onUpdate: OnUpdate?
private var listenerRegistration: ListenerRegistration?
func listen(path: String, firestore: Firestore, onUpdate: OnUpdate? = nil) {
self.onUpdate = onUpdate
guard listenerRegistration == nil else { return }
@natpenguin
natpenguin / GraphQL+DeclarativeDataFetching.swift
Last active May 5, 2022 15:22
A propertyWrapper for supporting declarative data fetching on SwiftUI with GraphQL(using apollo-ios)
@propertyWrapper
struct Query<Query: GraphQLQuery>: DynamicProperty {
enum NetworkState {
case notFetching
case fetching
case success(Query.Data)
case failure
}
@State var wrappedValue: NetworkState = .notFetching
@natpenguin
natpenguin / ApolloClient+Concurrency.swift
Created February 18, 2022 02:28
A extension of Apollo Client for fetching data with async word
import Foundation
import Apollo
public extension ApolloClient {
func asyncFetch<Q: GraphQLQuery>(query: Q, cachePolicy: CachePolicy, queue: DispatchQueue) async throws -> Q.Data {
try await withCheckedThrowingContinuation({ [weak self] continuation in
guard let self = self else {
continuation.resume(throwing: NSError(domain: "Apollo.NoSelfError", code: -1, userInfo: nil))
return
}
class DeliveryProgressView(context: Context, attributeSet: AttributeSet) : FrameLayout(context, attributeSet) {
private val progressBar: ProgressBar
private val notDeliveredCircleImageView: ImageView
private val deliveringCircleImageView: ImageView
private val deliveredCircleImageView: ImageView
init {
View.inflate(context, R.layout.delivery_progress_view, this)
progressBar = findViewById<ProgressBar>(R.id.progress_bar).apply {
progress = 50
@natpenguin
natpenguin / UINavigationController+Interception.swift
Created September 27, 2020 01:50
To intercept to pushViewController in UINavigationController
extension UINavigationController {
@objc private func myPushViewController(_ viewController: UIViewController, animated: Bool) {
self.myPushViewController(viewController, animated: animated)
}
static func setupInterceptPushViewController() {
guard let m1 = class_getInstanceMethod(UINavigationController.self, #selector(UINavigationController.pushViewController(_:animated:))) else { return }
guard let m2 = class_getInstanceMethod(UINavigationController.self, #selector(UINavigationController.myPushViewController(_:animated:))) else { return }
method_exchangeImplementations(m1, m2)
}
@natpenguin
natpenguin / Combine+Previous.swift
Created September 4, 2020 09:13
An combine operator that pass the stream event with previous stream event
extension Publishers {
struct Previous<Upstream: Publisher>: Publisher {
typealias Output = (Upstream.Output?, Upstream.Output)
typealias Failure = Upstream.Failure
private let upstream: Upstream
init(upstream: Upstream) {
self.upstream = upstream
}
@natpenguin
natpenguin / gifgen.sh
Created January 28, 2020 06:02
Generating gif files from mov or mp4 in directory of Downloads
#!/bin/bash
# This script is going to generate .gif from .MP4 and .mov in the Downloads directory
echo 'Checking tools that are needed in this script...'
# Checking Homebrew for installing ffmpeg
if !(type 'brew' > /dev/null); then
echo 'Installing Homebrew...'
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
if !(type 'brew' > /dev/null); then