Если вы хотите погладить вычтенный путь, вы сами по себе.Apple не предоставляет API, который возвращает (или просто обводит) вычитание одного пути из другого.
Если вы просто хотите заполнить вычтенный путь (как на вашем примере изображения), вы можете сделать это, используяотсечения путь.Вы должны использовать трюк, хотя.Когда вы добавляете путь к пути отсечения, новый путь отсечения - это пересечение старого пути отсечения и добавленного пути.Поэтому, если вы просто добавите smallMaskPath
к пути отсечения, вы в конечном итоге заполните только область внутри smallMaskPath
, что противоположно тому, что вы хотите.
Что вам нужно сделать, это пересечь существующийобтравочный контур с обратным из smallMaskPath
.К счастью, вы можете сделать это довольно легко, используя правило с четной и нечетной намоткой.Вы можете прочитать о четно-нечетном правиле в Quartz 2D Руководство по программированию .
Основная идея состоит в том, что мы создаем составной путь с двумя подпутями: ваш smallMaskPath
и огромный прямоугольник, который полностью окружает ваш smallMaskPath
и каждый второй пиксель, который вы, возможно, захотите заполнить.Из-за четно-нечетного правила каждый пиксель внутри smallMaskPath
будет рассматриваться как вне составного пути, а каждый пиксель за пределами smallMaskPath
будет рассматриваться как внутри составного пути.
Такдавайте создадим этот составной путь.Начнем с огромного прямоугольника.И нет прямоугольника, более огромного, чем бесконечный прямоугольник:
UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:CGRectInfinite];
Теперь мы превращаем его в составной путь, добавляя к нему smallMaskPath
:
[clipPath appendPath:smallMaskPath];
Затем мы устанавливаемпуть для использования четно-нечетного правила:
clipPath.usesEvenOddFillRule = YES;
Перед тем, как мы перейдем к этому пути, мы должны сохранить состояние графики, чтобы мы могли отменить изменение пути отсечения, когда закончим:
CGContextSaveGState(UIGraphicsGetCurrentContext()); {
Теперь мы можем изменить путь отсечения:
[clipPath addClip];
, и мы можем заполнить bigMaskPath
:
[[UIColor orangeColor] setFill];
[bigMaskPath fill];
Наконец мы восстановим состояние графики, отменивизмените путь отсечения:
} CGContextRestoreGState(UIGraphicsGetCurrentContext());
Вот код все вместе на случай, если вы хотите скопировать / вставить его:
UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:CGRectInfinite];
[clipPath appendPath:smallMaskPath];
clipPath.usesEvenOddFillRule = YES;
CGContextSaveGState(UIGraphicsGetCurrentContext()); {
[clipPath addClip];
[[UIColor orangeColor] setFill];
[bigMaskPath fill];
} CGContextRestoreGState(UIGraphicsGetCurrentContext());