UIView не появляется и метод drawRect никогда не вызывается

Я создал подкласс UIView под названием MiniView.

Я пытаюсь добавить его в свой viewController следующим образом:

@interface SomeViewController ()

@property (strong, nonatomic) MiniView *miniView;

@end

- (void)viewDidLoad
        {
        [super viewDidLoad];

        self.miniView = [[MiniView alloc] initWithFrame:CGRectMake(20.f, 20.f, 200.f, 200.f)];
        _miniView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:_miniView];
    }

Класс MiniView выглядит так:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    NSLog(@"DRAW RECT");
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIColor * redColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0];
    CGContextSetFillColorWithColor(context, redColor.CGColor);
    CGContextFillRect(context, self.bounds);
}

Но drawRect никогда не вызывается, если я не вызываю его явно из метода setNeedsLayout. Он также ничего не рисует. Я пробовал просто добавить UIImageView в метод drawRect, и это нормально. Но приведенный выше код ничего не дает.

Я тоже получаю сообщение об ошибке:

: CGContextSetFillColorWithColor: недопустимый контекст 0x0. Это серьезная ошибка. Это приложение или используемая им библиотека использует недопустимый контекст и тем самым способствует общему снижению стабильности и надежности системы. Это уведомление любезно: пожалуйста, устраните эту проблему. В грядущем обновлении это станет фатальной ошибкой.

Если я распечатаю оператор журнала в методе drawRect и выведу значения 'rect', он будет правильным при 200 x 200, поэтому я не знаю, почему контекст равен 0x0.

Итак, одна проблема заключается в том, что drawRect никогда не вызывается, а другая проблема в том, что если я вызываю его явно, ничего не отображается ...


person Smikey    schedule 28.10.2013    source источник
comment
Ах, я только что понял, что делаю неправильно - я переопределил метод setNeedsDisplay в моем классе MiniView на что-то NSLog. Значит, он вёл себя неправильно. Я позвонил в [super setNeedsDisplay], и теперь он работает хлопает головой   -  person Smikey    schedule 28.10.2013


Ответы (4)


Никогда не вызывайте drawRect explicity, попробуйте следующее:

- (void)viewDidLoad
        {
        [super viewDidLoad];

        self.miniView = [[MiniView alloc] initWithFrame:CGRectMake(20.f, 20.f, 200.f, 200.f)];
        _miniView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:_miniView];

        [_miniView setNeedsDisplay];
    }
person Antonio MG    schedule 28.10.2013
comment
Я вызвал setNeedsDisplay в другом месте, но, как было сказано выше, я понял, что переопределил его в MiniView без вызова [super setNeedsDisplay]. Спасибо за ответ - он заставил меня понять, что я делаю не так. - person Smikey; 28.10.2013
comment
@Smikey: Вы должны опубликовать это как отдельный ответ, поскольку он отличается от того, что предлагал Антонио MG. - person Peter Hosey; 29.10.2013

Вероятно, вам нужно вызвать setNeedsDisplay в пользовательском подклассе UIView:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.miniView = [[MiniView alloc] initWithFrame:CGRectMake(20.f, 20.f, 200.f, 200.f)];
    _miniView.backgroundColor = [UIColor blackColor];
    [_miniView setNeedsDisplay];    // Added this
    [self.view addSubview:_miniView];
}

По сути, это средство сообщить системе, что ваш UIView нужно перерисовать. Дополнительную информацию см. В документации.

person occulus    schedule 28.10.2013

Публикация в виде отдельного ответа по запросу:

Фактическая проблема заключалась в том, что я переопределил метод setNeedsDisplay в классе MiniView, например:

- (void)setNeedsDisplay
{
    NSLog(@"Redrawing info: %@", [_info description]);
}

Поскольку я пренебрегал вызовом [super setNeedsDisplay], метод drawRect никогда не вызывался и ничего не рисовалось. Итак, это исправлено:

- (void)setNeedsDisplay
{
    [super setNeedsDisplay];
    NSLog(@"Redrawing info: %@", [_info description]);
}
person Smikey    schedule 29.10.2013

Хорошо, в вашем методе рисования включите эту строку: -

        [super drawRect:rect];
person Hussain Shabbir    schedule 28.10.2013
comment
В прямом подклассе UIView в этом нет необходимости. «Реализация этого метода по умолчанию ничего не делает». - person Peter Hosey; 29.10.2013