Search code examples
iosswift

Is it impossible to create neumorphic soft UI on Swift?


Now, I saw so many design about Neumorphic Soft UI and I have no idea about that for implement on iOS ( swift 4 ). I saw so many tutorial about this but for iOS13+ and SwiftUI only not for swift4 that i want.

If anyone know please help me.

enter image description here


Solution

  • In order to achieve this the Swift 4 code is no different to Swift 5. So you should just be able to use the code from whatever non-SwiftUI tutorials you've found.

    The basics of replicating this though is you need two shadows, one that sits above and to the left of the view, and another that sits below and to the right.

    yourView.layer.masksToBounds = false
    
    let cornerRadius: CGFloat = 15
    let shadowRadius: CGFloat = 2
    
    let darkShadow = CALayer()
    darkShadow.frame = bounds
    darkShadow.backgroundColor = backgroundColor?.cgColor
    darkShadow.shadowColor = UIColor(red: 0.87, green: 0.89, blue: 0.93, alpha: 1.0).cgColor
    darkShadow.cornerRadius = cornerRadius
    darkShadow.shadowOffset = CGSize(width: shadowRadius, height: shadowRadius)
    darkShadow.shadowOpacity = 1
    darkShadow.shadowRadius = shadowRadius
    yourView.layer.insertSublayer(darkShadow, at: 0)
    
    let lightShadow = CALayer()
    lightShadow.frame = bounds
    lightShadow.backgroundColor = backgroundColor?.cgColor
    lightShadow.shadowColor = UIColor.white.cgColor
    lightShadow.cornerRadius = cornerRadius
    lightShadow.shadowOffset = CGSize(width: -shadowRadius, height: -shadowRadius)
    lightShadow.shadowOpacity = 1
    lightShadow.shadowRadius = shadowRadius
    yourView.layer.insertSublayer(lightShadow, at: 0)
    

    There are 3 main things in the above code that are required otherwise the shadows will not render.

    1. The view must set masksToBounds to false—since the shadows will be outside of the bounds
    2. You must assign a backgroundColor to the layers
    3. You must set a shadowOpacity since the default is 0.0—setting 1.0 produces the closest results to your image

    You likely want to have the shadows flip when the view is pressed, for that you simply need to switch the shadowOffsets of both the sublayers.

    lightShadow.shadowOffset = CGSize(width: shadowRadius, height: shadowRadius)
    darkShadow.shadowOffset = CGSize(width: -shadowRadius, height: -shadowRadius)
    

    and when the user stops pressing reset them

    lightShadow.shadowOffset = CGSize(width: -shadowRadius, height: -shadowRadius)
    darkShadow.shadowOffset = CGSize(width: shadowRadius, height: shadowRadius)
    

    For a UIControl you will likely be doing the above in the didSet of an isHighlighted override.