Skip to content

Instantly share code, notes, and snippets.

@ramzesenok
Created March 30, 2025 21:18
Show Gist options
  • Select an option

  • Save ramzesenok/bb4820d8e10e2546c388762bf45d27a2 to your computer and use it in GitHub Desktop.

Select an option

Save ramzesenok/bb4820d8e10e2546c388762bf45d27a2 to your computer and use it in GitHub Desktop.
SwiftUI Extensions for Podlodka Presentation
// MARK: - Misc
extension View {
@ViewBuilder
func debugBorder() -> some View {
#if DEBUG
self.border(Color.random())
#else
self
#endif
}
func fullWidth(alignment: Alignment = .center) -> some View {
self.frame(maxWidth: .infinity, alignment: alignment)
}
func frame(squareSide: CGFloat?, alignment: Alignment = .center) -> some View {
self.frame(width: squareSide, height: squareSide, alignment: alignment)
}
func asAnyView() -> AnyView {
AnyView(self)
}
func modify<Content>(@ViewBuilder _ transform: (Self) -> Content) -> Content {
transform(self)
}
@ViewBuilder
func `if`<Content: View>(_ condition: Bool, @ViewBuilder transform: (Self) -> Content) -> some View {
if condition {
transform(self)
} else {
self
}
}
@ViewBuilder
func iflet<Value>(_ value: Value?, @ViewBuilder transform: (Value, Self) -> some View) -> some View {
if let value {
transform(value, self)
} else {
self
}
}
}
extension Color {
static func random() -> Color {
Color(
red: Double.random(in: 0...1),
green: Double.random(in: 0...1),
blue: Double.random(in: 0...1)
)
}
var sui: Color { Color(self) }
}
extension UIFont {
var sui: Font { Font(self) }
}
// MARK: - On First Appear
private struct OnFirstAppearModifier: ViewModifier {
@State private var didPerform = false
let action: (() -> Void)?
func body(content: Content) -> some View {
content.onAppear {
if !didPerform {
didPerform = true
action?()
}
}
}
}
extension View {
func onFirstAppear(perform action: (() -> Void)? = nil) -> some View {
modifier(OnFirstAppearModifier(action: action))
}
}
// MARK: - Read size
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
extension View {
func readSize(onChange: @escaping (CGSize) -> Void) -> some View {
self.background(
GeometryReader { proxy in
Color.clear.preference(key: SizePreferenceKey.self, value: proxy.size)
}
)
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
}
func readSize(andUpdate value: Binding<CGSize>) -> some View {
self.readSize { size in
value.wrappedValue = size
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment