Запутался насчет UIBezierPath + applyTransform + CGPath - PullRequest
3 голосов
/ 25 сентября 2011

Я масштабирую UIBezierPath (построенный из одного прямоугольника [0,0 - 1x1]) с коэффициентом 2 в обоих направлениях x и y.UIBezierPath ".bounds" в порядке (то есть масштабируется как положено), а ".CGPath" остается неизменным ...

Код:

#import <UIKit/UIKit.h>

int main(int argc, char *argv[])
{
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0,
                                                                     1, 1)];
    NSLog(@"path.bounds box before transform:%@",
          NSStringFromCGRect(path.bounds));
    NSLog(@"path.CGPath box before transform:%@",
          NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath)));

    [path applyTransform:CGAffineTransformMakeScale(2, 2)];

    NSLog(@"path.bounds box after transform:%@",
          NSStringFromCGRect(path.bounds));
    NSLog(@"path.CGPath box after transform:%@",
          NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath)));

    return 0;        
}

Вывод:

path.bounds box before transform:{{0, 0}, {1, 1}}
path.CGPath box before transform:{{0, 0}, {1, 1}}
path.bounds box after transform:{{0, 0}, {2, 2}}
path.CGPath box after transform:{{0, 0}, {1, 1}}

Почему?

Ответы [ 2 ]

7 голосов
/ 25 июля 2012

Начиная с iOS 5.1, CGPath, возвращаемое из свойства UIBezier *1002*, действительно обновляется, когда к UIBezierPath применено новое преобразование.

Однако это не исключаетрешение для старых версий iOS.Вы можете получить CGPath из UIBezierPath, преобразовать его напрямую, а затем установить обратно на UIBezierPath.И вот, все остальные свойства, такие как границы и происхождение, будут обновлены правильно и немедленно.

UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(0.0f, 0.0f,
                                                                 1.0f, 1.0f)];

CGAffineTransform transform = CGAffineTransformMakeScale(2.0f, 2.0f);
CGPathRef intermediatePath = CGPathCreateCopyByTransformingPath(path.CGPath,
                                                                &transform);

path.CGPath = intermediatePath;

CGPathRelease(intermediatePath);
4 голосов
/ 31 октября 2011

Причина этого различия заключается в том, что вызов applyTransform просто сохраняет матрицу преобразования в объекте пути.Это не приводит к изменению самого пути.path.bounds - это вычисляемое свойство, которое получается с помощью преобразования, тогда как вызов CGPathGetBoundingBox просто перебирает элементы переданного в CGPath объекта.

Поскольку потенциально может быть большое количество элементов пути,сохранение матрицы преобразования и не модификация всех элементов пути каждый раз, когда назначается новая матрица, выполняется как оптимизация.Эта работа выполняется только один раз или минимально, когда запрашиваются только определенные свойства, такие как границы, UIBezierPath.

...