Giter VIP home page Giter VIP logo

shapeview's Introduction

ShapeView Build Status Version License Platform

ShapeView support to create a view with the customized shape, shadow and transparent background at the same time.

Installation

ShapeView is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'ShapeView'

Using ShapeView

ShapeView supports the following attributes.

  • path: ShapePath?
  • outerShadow: ShapeShadow
  • innerShadow: ShapeShadow
  • effect: UIVisualEffect?
  • effectAlpha: CGFloat
  • backgroundColor: UIColor?

To create a customized shape, use .custom to draw the shape as the following.

view.path = .custom { [unowned view] in
    let labelHeight = view.frame.height - Const.height
    let radius = labelHeight / 2

    $0.move(to: CGPoint(x: radius, y: 0))
    $0.addArc(
        withCenter: CGPoint(x: view.frame.width - radius, y: radius), 
        radius: radius, 
        startAngle: -.pi / 2, 
        endAngle: .pi / 2, 
        clockwise: true
    )
    $0.addLine(to: CGPoint(x: Const.left + Const.height, y: labelHeight))
    $0.addLine(to: CGPoint(x: Const.left + Const.height / 2, y: view.frame.height))
    $0.addLine(to: CGPoint(x: Const.left, y: labelHeight))
    $0.addArc(
        withCenter: CGPoint(x: radius, y: radius), 
        radius: radius, 
        startAngle: .pi / 2, 
        endAngle: -.pi / 2, 
        clockwise: true
    )
}

Using prepared shapes

In the demo app, a dialog view is created with the code above.

Demo

The following shapes are prepared.

corner(radius: CGFloat, bounds: @escaping GetBounds)
dialog(radius: CGFloat, arrowPosition: DialogArrowPosition, bounds: @escaping GetBounds)
cuteDialog(radius: CGFloat, arrowPosition: CuteDialogArrowPosition, bounds: @escaping GetBounds)
star(vertex: Int, extrusion: CGFloat = 10, bounds: GetBounds)

Here is a demo to create a dialog view.

view.path = .dialog(radius: 10, arrowPosition: .right(center: 50, width: 40, height: 20)) { [unowned self] in
    return self.bounds
}
view.outerShadow = ShapeShadow(
    radius: 10,
    color: .green,
    opacity: 1,
    offset: .zero
)

Multiple shapes

ShapeView supports to add multiple shapes with .multiple() as the following.

view.path = .multiple(
    .hollowCorner(radius: 12, outlineWidth: 2) { [unowned view] in
        view.bounds
    },
    .star(vertex: 5, extrusion: 20) { [unowned view] in
        view.bounds
    },
    .custom { [unowned view] in
        // Add a custom shape here.    
    }
)

Run the demp application to find more.

Using ShapeLayer

We provide ShapeLayer for developers to apply it to your customized view directly.

  • layerPath: ShapePath?
  • var outerShadow: ShapeShadow?
  • var innerShadow: ShapeShadow?
  • effect: UIVisualEffect?
  • effectAlpha: CGFloat
  • var didUpdateLayer: ((CAShapeLayer) -> Void)?
  • var backgroundColor: CGColor?

When the shape layer finish drawing the layer, it calls the didUpdateLayer cloure to notify the parent view. Developers can update the parent view with the first parameter in this closure.

About the Implementation

This part introduces how we implement the ShapeView, skip it if you are not interested.

Necessity to implement by ourselves

It is hard to create a customized shape with shadow and transparent background for UIView using the SDK provided by Apple. We have tried to and shadow into the customized shape layer directly with the following code.

let shapeLayer = CAShapeLayer()
shapeLayer.path = shapePath.cgPath
shapeLayer.shadow = UIColor.green.cgColor
shapeLayer.shadowRadius = 10
shapeLayer.shadowOffset = .zero
shapeLayer.shadowOpacity = 1

ShapeShadow(
    radius: 10,
    color: .green,
    opacity: 1,
    offset: .zero
)
layer.masksToBounds = true
  • Using a mask
layer.mask = shapeLayer

Mask

  • Adding a sublayer
layer.addSublayer(shapeLayer)

Sublayer

Using a mask or adding a sublayer cannot implement the effect shown in our demo screenshoot.

Structure

Shape layers

In the ShapeLayer, we add a shadow layer for the shape and effect, and a container view for storing subviews.. If the developer add subview to the ShapeView by the method addSubview(_ view:), we move it to the container view.

Creating a hollow mask layer

To solve the problems, we need to creare a hollow mask layer by ourselves. Firstly, we create a shadow layer, and insert it to the shapeLayerView.

let shadowLayer = CAShapeLayer()
shadowLayer.path = shapePath.cgPath
if shadowRadius > 0 && shadowColor != .clear {
    shadowLayer.shadowRadius = shadowRadius
    shadowLayer.shadowColor = shadowColor.cgColor
    shadowLayer.shadowOpacity = shadowOpacity
    shadowLayer.shadowOffset = shaowOffset
    shadowLayer.fillColor = shadowColor.cgColor
}
shadowLayerView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
shadowLayerView.layer.insertSublayer(shadowLayer, at: 0)

shapelayer

The shadow layer created by CAShapeLayer is a solid layer. We need to make a cut layer shown as the red area in the following screenshoot, as a mask layer to create a hollow mask layer.

let cutLayer = CAShapeLayer()
cutLayer.path = { () -> UIBezierPath in
    let path = UIBezierPath()
    path.append(shapePath)
    path.append(screenPath)
    path.usesEvenOddFillRule = true
    return path
}().cgPath
cutLayer.fillRule = .evenOdd

cutlayer

The range of the cut layer is outside of the shape's border and inside of the screen's border. After creating the cut layer, we set it as the mask of the shadow layer view.

shadowLayerView.layer.mask = cutLayer

By setting the cut layer for the shadow layer view, we get a hollow shape view with a shadow as the following picture.

hollow-shapelayer

Next, we create a container view above the shadow view, and use the same shape path to create a shape layer as the mask of this container view.

let shapeLayer = CAShapeLayer()
shapeLayer.path = shapePath.cgPath
containerView.layer.mask = shapeLayer

The introduction above shows how to create a outer shadow, the method to create a inner shadow is same as the outer shadow. At last, we get a customized shape view with the transparent background and shadow as shown in the demo screenshot.

Author

lm2343635, [email protected]

License

ShapeView is available under the MIT license. See the LICENSE file for more info.

shapeview's People

Contributors

lm2343635 avatar musharebot avatar shoichikuraoka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

shapeview's Issues

Animation not supported.

Some animations are not supported because there is some UI issue while changing the size of the shape view.

InnerShadow & UIEffectView

UIEffectView should move the bottom of the inner shadow layer.

  • container view
  • inner shadow layer
  • effect view
  • background color layer
  • outer shadow layer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.