hmhv

Soft-UI(Neumorphism)をSwiftで作って見る

2020-02-08

1. Soft-UI(Neumorphism)とは

New skeuomorphismというUI designの新しいトレンドっぽい
Soft-UI(Neumorphism)

2. コード実装

基本凸を表示するためにOuter Shadowを2つ、凹を表示するためにInner Shadowを2つ作って実装

Outer Shadow

Outer ShadowはCAShapeLayerでcornerRadiusに合わせたpathで影を作る
shadowColorとshadowOffsetを逆にして2つ作る

lightOuterShadowLayer = {
    let shadowLayer = createOuterShadowLayer(shadowColor: lightShadowColor, shadowOffset: shadowOffset.inverse)
    layer.addSublayer(shadowLayer)
    return shadowLayer
}()
darkOuterShadowLayer.path = createOuterShadowPath()

darkOuterShadowLayer = {
    let shadowLayer = createOuterShadowLayer(shadowColor: darkShadowColor, shadowOffset: shadowOffset)
    layer.addSublayer(shadowLayer)
    return shadowLayer
}()
lightOuterShadowLayer.path = createOuterShadowPath()


func createOuterShadowLayer(shadowColor: CGColor, shadowOffset: CGSize) -> CAShapeLayer {
    let layer = CAShapeLayer()
    layer.backgroundColor = UIColor.clear.cgColor
    layer.fillColor = mainColor
    layer.shadowColor = shadowColor
    layer.shadowOffset = shadowOffset
    layer.shadowOpacity = shadowOpacity
    layer.shadowRadius = shadowRadius
    return layer
}

func createOuterShadowPath() -> CGPath {
    return UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
}

Inner Shadow

Inner ShadowもCAShapeLayerでcornerRadiusに合わせたpathとより大きいpathを合わせて影を作りmaskで外側には表示されないようにする
shadowColorとshadowOffsetを逆にして2つ作る


darkInnerShadowLayer = {
    let shadowLayer = createInnerShadowLayer(shadowColor: darkShadowColor, shadowOffset: shadowOffset)
    layer.addSublayer(shadowLayer)
    shadowLayer.isHidden = true
    return shadowLayer
}()
darkInnerShadowLayer.path = createInnerShadowPath()
darkInnerShadowLayer.mask = createInnerShadowMask()

lightInnerShadowLayer = {
    let shadowLayer = createInnerShadowLayer(shadowColor: lightShadowColor, shadowOffset: shadowOffset.inverse)
    layer.addSublayer(shadowLayer)
    shadowLayer.isHidden = true
    return shadowLayer
}()
lightInnerShadowLayer.path = createInnerShadowPath()
lightInnerShadowLayer.mask = createInnerShadowMask()

func createInnerShadowLayer(shadowColor: CGColor, shadowOffset: CGSize) -> CAShapeLayer {
    let layer = CAShapeLayer()
    layer.backgroundColor = UIColor.clear.cgColor
    layer.fillColor = mainColor
    layer.shadowColor = shadowColor
    layer.shadowOffset = shadowOffset
    layer.shadowOpacity = shadowOpacity
    layer.shadowRadius = shadowRadius
    layer.fillRule = .evenOdd
    return layer
}

func createInnerShadowPath() -> CGPath {
    let path = UIBezierPath(roundedRect: bounds.insetBy(dx: -100, dy: -100), cornerRadius: cornerRadius)
    path.append(UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius))
    return path.cgPath
}

func createInnerShadowMask() -> CALayer {
    let layer = CAShapeLayer()
    layer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
    return layer
}

Example

全ソースコードはこちらに
https://github.com/hmhv/SoftUIView

参考

https://neumorphism.io/#55b9f3