К какому типу содержимого относится режим UIViewContentMode?

Согласно официальному документу на UIView о contentMode имущество:

The content mode specifies how the cached bitmap of the view’s layer is adjusted when the view’s bounds change

Что определяет содержание в этом определении? Это вспомогательное представление или когда мы должны определить цвет фона для представления например.

Моим самым первым предположением было то, что оно должно применяться по крайней мере для подпредставлений в представлении, но, например, следующий фрагмент кода не даст мне ожидаемого результата при игре с UIViewContentModeCenter тег:

 UIView* redView = [[UIView alloc] initWithFrame:CGRectMake(80, 80, 150, 200)];
 redView.contentMode = UIViewContentModeCenter;
 redView.backgroundColor = [UIColor redColor];

 UIView* greenView = [[UIView alloc] initWithFrame:redView.bounds];
 greenView.backgroundColor = [UIColor greenColor];
 [redView addSubview:greenView];

 redView.frame = CGRectInset(redView.frame, -5, -5);
 [self.view addSubview:redView];

Я только что создал RedView, который будет включать GreenView. Я также настроил режим контента redview, чтобы UIViewContentModeCenter - почему в коде, который я написал, greenView не центрируется, когда я меняю рамку своего родителя? не то, что UIViewContentModeCenter должен делать?

Спасибо за разъяснения!

PS: Вы можете легко проверить приведенный выше код в loadView простого шаблона проекта контроллера представления.

2 ответа

Решение

Из документации:

Режим содержимого определяет, как корректируется кэшированное растровое изображение слоя представления при изменении границ представления.

Для изображения это говорит об изображении. Для представления, которое рисует свой контент, речь идет о нарисованном контенте. Это не влияет на макет подпредставлений.

Вам нужно посмотреть на маски авторазмера на месте в подпредставлениях. Контентный режим - это красная сельдь здесь. Если вы не можете получить макет, который вам нужен, с помощью масок автоматического изменения размера, то вам нужно реализовать layoutSubviews и вычислить позиции и кадры подпредставления вручную.

из ответа Джртуртона на: /questions/21661400/avtomaticheski-masshtabirujte-uiview-pri-izmenenii-orientatsii-chtobyi-proportsionalno-masshtabirovat-ego-chtobyi-ono-sootvetstvovalo-roditelskomu-vidu/21661420#21661420

Сначала прочитайте о режимах содержания здесь

В вашем примере вы меняете рамку красного вида. Это вызовет layoutSubviews в представлении, которое переместит зеленый вид в соответствии с ограничениями макета или автоматически изменяющими размеры масками. Вы не указали ни одного. Таким образом, рамка зеленого вида останется прежней.

Режим содержимого определяет, как слой представления должен обновляться при изменении размера. В зависимости от режима содержимого будет вызываться drawRect или нет.

Вы можете проверить влияние различных режимов содержимого на следующем примере:

Добавьте подкласс UIView, который рисует круг, используя эту реализацию drawRect:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    NSLog(@"drawRect %@", NSStringFromCGRect(rect));

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddEllipseInRect(ctx, self.bounds);
    [[UIColor redColor] setFill];
    CGContextFillPath(ctx);
}

В контроллере вида создайте и добавьте круговое представление:

CircleView* circleView = [[CircleView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
circleView.contentMode = UIViewContentModeCenter; // <- try different modes here
[self.view addSubview:circleView];

Теперь давайте анимируем кадр и посмотрим, что произойдет:

dispatch_async(dispatch_get_main_queue(), ^{
    [UIView animateWithDuration:5 animations:^{
        circleView.frame = CGRectMake(10, 10, 100, 200);
    }];
});

Я делаю это асинхронно, чтобы заставить CoreGraphics рисовать вид хотя бы один раз с исходным кадром. Если вы не установите режим содержимого, вы получите размытый круг, потому что он просто масштабируется без перерисовки. UIViewContentModeCenter заставляет маленький круг оставаться в центре - также не требуется перерисовка. UIViewContentModeRedraw заставляет представление снова рисовать представление с новым фреймом. На самом деле это происходит до запуска анимации.

Обратите внимание, что режим содержимого может повлиять на производительность рисования.

Другие вопросы по тегам