iPhone skew a CALayer

2019-05-04 01:04发布

问题:

I'm a beginner and I am doing some exercises to familiarize myself with CALayer ...

I just want to know how to "incline" (or skew) a CALayer 45° angle ?

Thank you.

回答1:

You could do this but you would have to mess with the layer's transform property, which is a struct CATransform3D. You're going to have to do some vector math to do this, as you . See the compute_transform_matrix(...) function from this answer for more details.

You'll want to do something like this:

CGRect r = layer.bounds;
layer.transform = compute_transform_matrix(r.origin.x,    r.origin.y,                 r.size.width,                 r.size.height,
                                           r.size.height, r.origin.y,                 r.size.width + r.size.height, r.origin.y,
                                           r.origin.x,    r.origin.y + r.size.height, r.size.width,                 r.origin.y );

Check my math on this. It should be right.



回答2:

CALayers have a property, affineTransform that takes a CAAffineTransform. That documentation explicitly notes that:

Scaling, rotation, and translation are the most commonly used manipulations supported by affine transforms, but skewing is also possible.

(emphasis mine, obviously)

There's no built in helper to construct a skew transform, but you could do something like (untested):

CGAffineTransform CGAffineTransformMakeSkew(CGFloat skewAmount)
{
    CGAffineTransform skewTransform = CGAffineTransformIdentity;
    skewTransform.b = skewAmount;
    return skewTransform;
}

Then, for a skew such that things that were verticals stand at 45 degrees to the horizontal you'd use:

layer.affineTransform = CGAffineTransformMakeSkew(1.0f);


回答3:

CALayers can be transformed using matrix operations. The skew transformation is represented by the following matrix

So if you want to do a skew transformation along the x axis you can use the following sample.

CALayer* layer = [CALayer layer];
layer.frame = CGRectMake(50,50,50,50);
layer.backgroundColor = [UIColor blueColor].CGColor;
[self.window.layer addSublayer:layer];

float theta = -45.0f;
CGAffineTransform t = CGAffineTransformIdentity;
t.b = tan(theta*M_PI/180.0f);
layer.transform = CATransform3DMakeAffineTransform(t);

The following sample will result in a layer that looks like the following



回答4:

There are a lot of resources on how transforms work and it takes a bit of time to really understand them (at least for me!), here is some straight-to-the-point code that makes sure to indicate to which axis the transform is applied.

/*!
 * Positive `skewX` creates a shift to the left.
 * Negative `skewX` creates a shift to the right.
 *
 * `skewX` is NOT pixel based. Test values of 0.0f - 1.0f.
 */
CGAffineTransform CGAffineTransformMakeSkewX(CGFloat skewX)
{
    return CGAffineTransformMakeSkew(skewX, 0.0f);
}

/*!
 * Positive `skewY` creates a shift to the bottom.
 * Negative `skewY` creates a shift to the top.
 *
 * `skewY` is NOT pixel based. Test values of 0.0f - 1.0f.
 */
CGAffineTransform CGAffineTransformMakeSkewY(CGFloat skewY)
{
    return CGAffineTransformMakeSkew(0.0f, skewY);
}

/*!
 * Positive `skewX` creates a shift to the left.
 * Negative `skewX` creates a shift to the right.
 *
 * Positive `skewY` creates a shift to the bottom.
 * Negative `skewY` creates a shift to the top.
 *
 * The skew values are NOT pixel based. Test values of 0.0f - 1.0f.
 */
CGAffineTransform CGAffineTransformMakeSkew(CGFloat skewX, CGFloat skewY)
{
    return CGAffineTransformMake(1.0f, skewY, skewX, 1.0f, 0.0f, 0.0f);
}