NeumorphicUIKit

3.2.1

Soft neumorphic shadows for any UIKit view: palette-agnostic, automatic light/dark, iOS 15+
A-bv/NeumorphicUIKit

What's New

3.2.1

2026-07-02T16:09:40Z
  • Added a demo GIF to the README showing the raised look, the button press, and the automatic light/dark switch.
  • Documented that the automatic light/dark switch needs a dynamic palette, and corrected doc comments that still described dark mode as iOS 17+ only.
  • README polish: CI status badge, current install version, and a resize snippet that compiles where it's pasted.
  • CI now treats Swift warnings as errors.
  • Broadened the tests (settle cancellation, full press recolour, geometry, safe no-ops on unstyled views) and removed a timing-flaky test.

NeumorphicUIKit

CI Swift Package Manager Platform Swift License

Add a soft, "raised" neumorphic look to any UIKit view — cards, buttons, any control — using your own colors.

NeumorphicUIKit demo: a raised card and a button that presses, with an automatic light/dark switch

What it does

  • Styles any UIView, including buttons and other controls.
  • Uses the colors you give it, so it matches your app.
  • Keeps itself correct when the user switches between light and dark mode.
  • Has a pressed look for buttons.

Requirements

iOS 15+ · Swift 5.9

Installation

In Xcode: File → Add Package Dependencies…, then paste:

https://github.com/A-bv/NeumorphicUIKit

Or add it to Package.swift:

.package(url: "https://github.com/A-bv/NeumorphicUIKit", from: "3.2.1")

Usage

Set your colors once, when the app starts (for example in the app delegate):

Neumorphism.configure(NeumorphicColors(
    surface: .myBackground,   // the view's own color
    darkShadow: .myDarkShadow, // the darker edge
    lightShadow: .myLightShadow, // the lighter edge
    bottom: .myBottom))       // used for the pressed look

Then style any view:

card.neumorphism(cornerRadius: 16)

That's it. The view keeps its look correct when the user switches between light and dark mode — you don't have to do anything else.

For that automatic light/dark switch to show, pass dynamic UIColors — ones with light and dark variants (UIColor { $0.userInterfaceStyle == .dark ? … : … } or a color set in your asset catalog) — to configure.

Buttons

Add the pressed look by forwarding a button's touch events:

button.neumorphism(cornerRadius: 16)
button.addTarget(self, action: #selector(down), for: .touchDown)
button.addTarget(self, action: #selector(up), for: [.touchUpInside, .touchUpOutside, .touchCancel])
@objc func down(_ sender: UIView) { sender.pressDown() }
@objc func up(_ sender: UIView)   { sender.pressUp(settle: true) }

Views that change size

The look is built at the view's current size. If a view resizes — an Auto Layout view, or a button whose title grows — keep the look matched to it. From the view controller that owns it:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    card.resizeNeumorphicShadows()
}

Description

  • Swift Tools 5.9.0
View More Packages from this Author

Dependencies

  • None
Last updated: Sun Jul 12 2026 06:09:04 GMT-0900 (Hawaii-Aleutian Daylight Time)