iPhone - Нарисуйте прозрачный прямоугольник на UIView, чтобы показать вид под

В настоящее время у меня есть два UIViews: один красный фон, а другой синий. Синий вид - это подпредставление красного вида. Что я хотел бы сделать, так это уметь вырезать прямоугольники на синем виде, чтобы красный вид был виден. Как ты это делаешь?

5 ответов

Решение

Вы должны переопределить вид сверху drawRect метод. Так, например, вы можете создать HoleyView класс, который происходит от UIView (вы можете сделать это, добавив новый файл в ваш проект, выбрав подкласс Objective-C и установив "Подкласс" в UIView). В HoleyView, drawRect будет выглядеть примерно так:

- (void)drawRect:(CGRect)rect {
    // Start by filling the area with the blue color
    [[UIColor blueColor] setFill];
    UIRectFill( rect );

    // Assume that there's an ivar somewhere called holeRect of type CGRect
    // We could just fill holeRect, but it's more efficient to only fill the
    // area we're being asked to draw.
    CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );

    [[UIColor clearColor] setFill];
    UIRectFill( holeRectIntersection );
}

Если вы используете Интерфейсный конструктор, убедитесь, что изменили класс дырочного представления на HoleyView, Вы можете сделать это, выбрав в представлении в Интерфейсном Разработчике и выбрав панель "Удостоверение" в Инспекторе (в правом нижнем углу значок "i").

Вы также должны установить непрозрачный вид сверху либо с помощью следующего фрагмента кода, либо сняв флажок Opaque Установите флажок в свойствах представления в Интерфейсном Разработчике (вы найдете его в разделе "Вид" атрибутов представления) и установите непрозрачность его цвета фона на 0% (цвет фона устанавливается в том же разделе).

topView.opaque = NO;
topView.backgroundColor = [UIColor clearColor];

Если вы хотите сделать круги, вы должны использовать Core Graphics (иначе Кварц 2D). Возможно, вы захотите прочитать руководство по программированию, которое доступно здесь.

Чтобы нарисовать эллипс вместо прямоугольника, ваш drawRect будет выглядеть примерно так:

- (void)drawRect:(CGRect)rect {
    // Get the current graphics context
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor( context, [UIColor blueColor].CGColor );
    CGContextFillRect( context, rect );

    if( CGRectIntersectsRect( holeRect, rect ) )
    {
        CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
        CGContextFillEllipseInRect( context, holeRect );
    }
}

Во всех остальных ответах есть доля правды, но вполне возможно нарисовать чистым цветом, или, так сказать, стереть существующие цвета в любом пути, даже с помощью -[UIBezierPath fill] или аналогичных удобных методов. Все, что вам нужно сделать, это установить соответствующий режим смешивания контекста в зависимости от эффекта, которого вы пытаетесь достичь, например, так:

CGContextSetBlendMode(context, kCGBlendModeClear);
[[UIColor clearColor] set];
[myArbitraryPolygonPath fill];

Существует около двух десятков различных вариантов, которые вы можете выбрать, взгляните на ссылку CGContext.

Чтобы нарисовать эллипс вместо прямоугольника, просто установите blendMode в clear:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor( context, [UIColor blackColor].CGColor );
    CGContextFillRect( context, rect );

    CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );

    CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
    CGContextSetBlendMode(context, kCGBlendModeClear);

    CGContextFillEllipseInRect( context, holeRect );
}

Это могут быть глупые способы, но я бы не делал это так, как вы описываете, а заставлял бы выглядеть так, как вы хотите.

(Ответ Жака только что всплыл - выглядит хорошо для меня)

Подход 1: В контроллере представления построить список прямоугольников, которые располагаются вокруг открытой "дыры". По мере того, как количество ваших отверстий увеличивается, количество плиточных канавок также будет увеличиваться.

Подход 2: поменять мышление. Синий вид должен быть сзади с разделами красного вида, помещенного сверху этого. Вы по-прежнему видите красный вид со всеми, кроме "дыр", маскированными синим видом, но на самом деле вы копируете области из вида, который хотите выставить, и помещаете их поверх маски по мере создания каждого отверстия. Если у вас есть эффект, имитирующий глубину, вы можете добавить это по мере необходимости для каждого отверстия.

Ни один не требует подклассов или drawRect:.

Некоторые ответы довольно старые.

2023, Новейшие технологии включают...

       class CompImage: UIIImageView {

     override func common() {
         super.common()
         layer.compositingFilter = "multiplyBlendMode"
         
         print("Filters available to you ...\n",
          CIFilter.filterNames(inCategory: kCICategoryCompositeOperation))
     }
 }

и

      guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
ctx.setStrokeColor(
..
ctx.setBlendMode(.multiply) // review the choices available
..
Другие вопросы по тегам