Установить цвет фона только для части UIView

Я хочу, чтобы нижняя часть (не совсем половина) моего UIView была другого цвета, чем верхняя.

Мне интересно, должен ли я создать CGRect, а затем раскрасить его? Это на правильном пути?

- (void)drawRect:(CGRect)rect { 

    CGRect aRect = CGRectMake(x, y, width, height);

    // Fill the rectangle with grey
    [[UIColor greyColor] setFill];
    UIRectFill( rect );
}

person AllieCat    schedule 05.08.2013    source источник
comment
Вам нужно создать подкласс UIView, чтобы переопределить метод drawRect.   -  person dana0550    schedule 05.08.2013
comment
Пожалуйста, одобрите ответ, если он помог.   -  person Efren    schedule 14.06.2017


Ответы (6)


Да, так как вы уже переопределяете метод drawRect, это подойдет.

- (void)drawRect:(CGRect)rect { 

    CGRect topRect = CGRectMake(0, 0, rect.size.width, rect.size.height/2.0);
    // Fill the rectangle with grey
    [[UIColor greyColor] setFill];
    UIRectFill( topRect );

    CGRect bottomRect = CGRectMake(0, rect.size.height/2.0, rect.size.width, rect.size.height/2.0);
    [[UIColor redColor] setFill];
    UIRectFill( bottomRect );

}

Измените значения внутри фреймов по своему усмотрению.

person Lucas Eduardo    schedule 05.08.2013
comment
Когда я помещаю ваш код в свой файл .m, ничего не происходит. drawRect вызывается автоматически, верно? - person AllieCat; 05.08.2013
comment
В какой .m файл вы это помещаете? Да, он вызывается автоматически, но drawRect — это метод класса UIView. Вы действительно переопределяете UIView? - person Lucas Eduardo; 05.08.2013
comment
Как я уже сказал, drawRect — это метод класса UIView. Вам нужно создать класс, который переопределяет UIView, и добавить его в качестве подвида основного представления вашего контроллера представления. - person Lucas Eduardo; 05.08.2013

В Swift 5.1 и iOS 13 вы можете выбрать один из двух следующих способов решения вашей проблемы.


№1. Нарисуйте и заполните указанный экземпляр CGRect экземпляром UIColor внутри подкласса UIView, используя функцию UIRectFill(_:)

UIKit предоставляет функцию UIRectFill(_:). UIRectFill(_:) имеет следующее объявление:

func UIRectFill(_ rect: CGRect)

Заполняет указанный прямоугольник текущим цветом.

Следующий код Playground показывает, как использовать UIRectFill(_:):

import UIKit
import PlaygroundSupport

class CustomView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)

        backgroundColor = UIColor.green
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        let bottomRect = CGRect(
            origin: CGPoint(x: rect.origin.x, y: rect.height / 2),
            size: CGSize(width: rect.size.width, height: rect.size.height / 2)
        )
        UIColor.red.set()
        UIRectFill(bottomRect)
    }

}

let view = CustomView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
PlaygroundPage.current.liveView = view

№ 2. Нарисуйте и заполните указанный экземпляр CGRect экземпляром UIColor внутри подкласса UIView, используя метод fill(_:) CGContext.

CGContext имеет метод под названием fill(_:). fill(_:) имеет следующее объявление:

func fill(_ rect: CGRect)

Закрашивает область, содержащуюся в предоставленном прямоугольнике, используя цвет заливки в текущем графическом состоянии.

Следующий код Playground показывает, как использовать fill(_:):

import UIKit
import PlaygroundSupport

class CustomView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)

        backgroundColor = UIColor.green
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        let bottomRect = CGRect(
            origin: CGPoint(x: rect.origin.x, y: rect.height / 2),
            size: CGSize(width: rect.size.width, height: rect.size.height / 2)
        )
        UIColor.red.set()
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.fill(bottomRect)
    }

}

let view = CustomView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
PlaygroundPage.current.liveView = view
person Imanou Petit    schedule 21.08.2017
comment
Какой лучше №1 или №2? - person Jack; 19.04.2018

Вы также можете добавить CALayer в качестве подслоя к вашему представлению. Включите фреймворки CoreGraphics и QuartzCore и создайте CGRect с желаемым форм-фактором в методе drawRect. Создайте экземпляр CALayer с прямоугольником и добавьте его в слой представления, используя [self.layer addSublayer:theLayer]. Перед добавлением используйте метод CALayer -setBackgroundColor:.

Если это внутри контроллера представления, а не подкласса представления, сделайте то же самое в методе viewDidLoad.

Брайан

person bmeulmeester    schedule 05.08.2013
comment
ваша теория ясна, но дайте какой-нибудь код, это поможет мне полностью. - person Kishore Kumar; 08.01.2016

Вы можете использовать этот код. Пожалуйста, измените CGRect по вашему желанию.

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

    CGRect topView = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 2);
    CGRect bottomView = CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 2, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 2);

    UIColor * grayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0];

    CGContextSetFillColorWithColor(context, grayColor.CGColor);
    CGContextFillRect(context, bottomView);

    CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
    CGContextFillRect(context, topView);
}

Следующая ссылка может помочь вам больше. http://www.raywenderlich.com/32925/core-graphics-tutorial-shadows-and-gloss

person shuvo    schedule 05.08.2013

Вы можете сделать CGRect и обрезать часть части для заполнения.

Но почему бы не попробовать два разных UIView, расположенных рядом друг с другом?

Бхарат

person slysid    schedule 05.08.2013

Переопределите метод drawRect вашего подкласса UIView. Следующий код сделает верхнюю половину вашего представления черной, а нижнюю — красной.

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Top View
    CGRect topRect = {CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds), CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds)};
    [[UIColor blackColor] setFill];
    UIRectFill(topRect);

    // Bottom View
    CGRect bottomRect = {CGRectGetMinX(self.bounds), CGRectGetMidY(self.bounds), CGRectGetMaxX(self.bounds), CGRectGetMidY(self.bounds)};
    [[UIColor redColor] setFill];
    UIRectFill(bottomRect);
}

ПРИМЕЧАНИЕ. Также вы можете переопределить метод drawRect: только при создании подкласса UIView. Основываясь на вашем комментарии, у меня есть ощущение, что это не то, что вы делаете.

person dana0550    schedule 05.08.2013
comment
Когда я реализую ваш код, я получаю сообщение об ошибке, что свойство "frame" не найдено в типе объекта [myUIView]... - person AllieCat; 05.08.2013
comment
Вы подклассифицируете UIView? Если да, то у вас должен быть доступ к свойству фрейма. - person dana0550; 05.08.2013
comment
Кроме того, я считаю, что опубликованный код неверен. Вы хотите определить topRect и bottomRect с точки зрения self.bounds, а не self.frame, потому что frame соответствует координатному пространству супервида, а bounds — координатному пространству вида, и это то, что вам нужно для пользовательского рисования. - person Zev Eisenberg; 05.08.2013
comment
@ZevEisenberg Это правильно, в некоторых случаях границы полезны. Но в этом случае, когда создается экземпляр подкласса UIView, для фрейма устанавливается его суперпредставление. - person dana0550; 05.08.2013
comment
Использование frame здесь неверно в любое время, когда источник представления не находится в {0,0} в пространстве координат его суперпредставления или когда в представлении есть преобразование, которое может привести к тому, что frame и bounds будут разными. - person Zev Eisenberg; 05.08.2013
comment
Если это работает, это не неправильно. Рамки и границы имеют свои варианты использования. Опять же, в этом случае рамка подкласса совпадает с границами, поскольку он устанавливает подкласс UIView для заполнения рамки представления... Границы полезны, когда у вас есть меньший дочерний UIView родительского представления. В данном случае это не имеет значения. - person dana0550; 05.08.2013