Yarden Eitan de5d200599
[Shapes] Move shapes from components/private to components/ (#6495)
This is the first part of the migration of moving the Shape libraries away from the private/ folder.

Tracking bug, progress and more details can be found here: #6494 

"Because Shapes and ShapeLibrary have been used in production and are an integral part of the shape scheme and theming. Moreover, with to stop the confusion of clients that the library should not be imported as it is under private, we want to migrate the Shape libs to be under components/ instead of components/private.

The migration will be a 7 step migration to not break clients internally.

1. move the folders to the new directory.
2. Make the old component's BUILD and Podspec targets depend on the new component (and nothing else).
3. Delete all implementation files from the old component.
4. Replace the contents of the old component's headers with import statements to the new component's header. If the new component has headers that match the old component's, then the new component's headers will need to be named uniquely for a period of time to allow clients to migrate over.
5. Once all clients have migrated from the old component, delete the old component. This is a breaking change.
6. If you had to create temporary header names in the new component, then in a separate release add the new headers that you want the new component to use. Move the content of the old headers into the new headers and replace the old headers with an import of the new headers. Migrate clients to the desired headers.
7. Once all clients have moved off of the old headers, delete the old headers.

Passes bazel build and pod build locally.
2019-01-28 17:51:27 -05:00
..

Shapes Core

This library consists of several classes that are often used together to implement Shape behavior on a component. Concretely, to create a shape object, you'll need to create an object that implements the MDCShapeGenerating protocol. MDCShapeGenerating only has one method, (CGPath *)pathForSize:(CGSize)size that returns the shapes CGPath for the expected size.

Our components support shapes by providing a property called id<MDCShapeGenerating> shapeGenerator and applies the provided shape to the component.


Overview

Listed below are classes that can be used to create an object that implements the MDCShapeGenerating protocol.

MDCPathGenerator

At the core there is MDCPathGenerator, which provides helper methods for building a CGPath. By providing a start point and end point, and using its different APIs to draw lines/curves between points, a CGPath is created.

MDCShapedShadowLayer

An MDCShapedShadowLayer class is used as the main layer class of the component's view instead of MDCShadowLayer to allow shapes to work well with shadows, borders, and background color.

The same way we override the layer in our components with MDCShadowLayer to achieve a shadow, we instead use MDCShapedShadowLayer like so:

@interface Component ()
@property(nonatomic, readonly, strong) MDCShapedShadowLayer *layer;
@end

@implementation Component

@dynamic layer;

+ (Class)layerClass {
  return [MDCShapedShadowLayer class];
}
@end

MDCShapedView

MDCShapedView is a base UIView that incorporates MDCShapedShadowLayer, a shapeGenerator object, and elevation, to provide a minimal view that has full shape support. This can be used as a building block for components that need shape support.

MDCCornerTreatment and MDCEdgeTreatment

MDCCornerTreatment and MDCEdgeTreatment are both classes that provide a modular approach for defining specifically the CGPath for a specific edge or corner.

MDCRectangleShapeGenerator

The last class in the Shapes Core library is MDCRectangleShapeGenerator. It is a shapeGenerator on its own (meaning it implements MDCShapeGenerating), and generates a CGPath but allows good customization as part of its implementation. It allows to set each of its corners and edges by using its MDCCornerTreatments and MDCEdgeTreatment. With this class we can basically build any Shape we want.

Usage

You'll typically create an MDCRectangleShapeGenerator instance that you set your component with. Components that support the shape system will have a id<MDCShapeGenerating> shapeGenerator property as part of their API. By setting the shapeGenerator property with your MDCRectangleShapeGenerator, you will provide the defined shape to your component.

Swift

let card = MDCCard()
let shapeGenerator = MDCRectangleShapeGenerator()
card.shapeGenerator = MDCRectangleShapeGenerator()

Objective-C

MDCCard *card = [[MDCCard alloc] init];
MDCRectangleShapeGenerator *shapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
card.shapeGenerator = shapeGenerator;