Проблема с представлением внешнего UIView в UIViewController: выходы не отображаются

У меня есть UIViewController, элементы пользовательского интерфейса которого настроены в раскадровке, и все работает нормально. Теперь я создал новый UIView в отдельных файлах xib, .h и .m, я назову его «оверлей»; Затем я представляю этот оверлей, который должен покрывать все, что ниже, так, чтобы можно было видеть только оверлей:

// in controller.m
OverlayView *overlayView = [[OverlayView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
overlayView.layer.zPosition = 1000;
[self.view addSubview:overlayView];

Наложение отображается в странном положении (его верх находится примерно в 50 пикселях от нижнего края панели навигации). Более того, кроме фона наложения, элементы наложения не видны. Это просто чистый красный холст. Я дважды проверил, что альфа-значения элементов равны 1, они настроены так, чтобы они не были скрытыми, и они также явно установлены в initWithFrame наложения:

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor redColor]; // red canvas shows up
        self.title.textColor = [UIColor blackColor]; // title can't be seen; why not?
        self.body.textColor = [UIColor blackColor]; // body can't be seen; why not?
    }
    return self;
}

Причина, по которой я не помещаю оверлей напрямую в xib контроллера, а затем просто меняю его свойство hidden, заключается в том, что этот оверлей должен использоваться несколькими контроллерами, и я хотел бы использовать его повторно, таким образом помещая его как отдельное представление .

Что я делаю неправильно?


person SeaJelly    schedule 13.02.2016    source источник


Ответы (2)


Родительское представление (представление контроллера представления) отвечает за установку фрейма дочернего представления. Если вы используете Auto Layout, вам нужно использовать setTranslateAutoresizingMaskIntoConstraints до NO и добавить желаемые ограничения в код. Имейте в виду, что дочерний фрейм будет установлен после вызова viewDidLayoutSubviews. Если вы не используете Auto Layout, просто установите рамку, используя метод setFrame в viewWillAppear.

person Lucian Boboc    schedule 13.02.2016
comment
Привет, спасибо за ответ, просто хочу дважды проверить, я правильно вас понял: здесь мы говорим об одном контроллере и двух представлениях, первое представление - это собственное представление контроллера, которое я установил в раскадровке, второе представление - это наложение, которое я хочу присутствует поверх собственного обзора контроллера. Так о каком детском представлении вы здесь говорите? - person SeaJelly; 13.02.2016
comment
Кроме того, вы предлагаете, чтобы я поместил логику [self.view addSubview:overlayView]; в viewWillAppear? Я уже пробовал это, результат был тот же. Фрейм уже был установлен, когда я звоню initWithFrame. - person SeaJelly; 13.02.2016
comment
Нет, представление нужно добавить в viewDidLoad. В viewWillAppear вы можете получить доступ к кадру или изменить его, если вам нужно, и если вы не используете Auto Layout. Если вы действительно используете Auto Layout, вы должны добавить ограничения при добавлении представления в viewDidLoad и не вмешиваться в фрейм, и вы можете получить доступ к фрейму только в viewDidLayoutSubviews. В viewWillAppear я не думаю, что рамка еще установлена. Опять же, очень важно, используете ли вы Auto Layout или нет. - person Lucian Boboc; 13.02.2016

Оказывается, мне пришлось загрузить перо из собственного initWithFrame представления.

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    id mainView;
    if (self) {
        NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"MyOverlayView" owner:self options:nil];
        mainView = [subviewArray objectAtIndex:0];
    }
    return mainView;
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

Код выше исправил это.

person SeaJelly    schedule 13.02.2016