2014-01-08 2 views
0

Xcode Interface Builder эмиссионных
Лично мне не нравится то, как интерфейс строитель работает в Xcode. В этом примере я пытаюсь создать довольно сложный контроллер вида. На контроллере вида viewDidLoad я показываю пользовательский вид предупреждения (как таковой). На самом деле это не предупреждение, а больше вид, который показывает пользователю некоторую информацию. У меня есть затемненный фоновой вид и вид сверху. Если я пытаюсь создать это в интерфейсе строителя становится слишком сложным, как вы не можете выбрать точку в фоновом режиме и переместить их и т.д., не опуская подвидов в чужие взгляды и так далее ...Programatically создание UIView с несколькими ярлыками

Сценарий
Что я пытаюсь сделать, это создать представление, в котором хранятся некоторые метки и кнопка. Контроллер представления имеет свойство сложности, основанное на этом, оно будет иметь другой текст в метках/количестве меток.
I.e. Легкие - 3 этикетки
Hard - 4 этикетки

Я создаю dimmedView и оповещения (стиль) Вид, как это:

// Setup the dimmedView 
UIView *dimmedView = [[UIView alloc] initWithFrame:self.view.frame]; 
dimmedView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6]; 

// Setup the startingAlertView 
UIView *startingAlertView = [[UIView alloc] init]; 
startingAlertView.backgroundColor = [UIColor whiteColor]; 

Я затем создать три/четыре метки на основе некоторой логики и добавления а также наклейки с дополнительными символами на startingAlertView.

Проблема очевидна в том, что ни в коем случае не задан кадр для представления. Это означает, что он возвращает 0,0,0,0. То, что я хотел бы сделать, - это представление, чтобы взять требуемую высоту на основе добавленных меток.

Я строю для IOS7 и используя автоматический макет. Должен ли я настраивать ограничения, которые затем могут корректировать соответствующие высоты и местоположения в представлении?

+0

@MarcoPace или использовать автомат, предназначенный для решения именно этой проблемы. – jrturton

+0

@jrturton Хорошо, я не читал последнее предложение. Поскольку он не использует IB, я ошибочно предположил, что он не хочет их использовать. Спасибо за ответ. –

+0

Спасибо, в этом примере IB не полезен ... главным образом потому, что это вид верхнего уровня и имеет сложный вид внизу. Если бы вы могли переключать представление, чтобы показать/скрыть внутри IB, пока вы работаете над другими ... теперь это было бы полезно – StuartM

ответ

2

Я строю для IOS7 и с использованием автоматической компоновки. Должен ли я настраивать ограничения, которые затем могут корректировать соответствующие высоты и местоположения в представлении?

Да. вы не используете initWithFrame: в автоматическом макете, или, вернее, можете, но кадр игнорируется. Создайте свой режим затемнения с рамкой CGRectZero, установив translatesAutoresizingMasksToConstraints в НЕТ, добавьте его в свой основной вид и создайте ограничения, привязанные ко всем краям супервизора.

Затем добавьте свой сигнал оповещения, опять же с нулевой рамкой и значением translates..., установленным в НЕТ.Создайте ограничения, чтобы центрировать это представление в вашем затемнении. Это представление получит свой размер из своих подзонов, так как метки имеют собственный размер.

Добавьте ярлыки в виде подсмотров этого вида, с нулевой рамкой и translates... установите значение НЕТ. В зависимости от их содержимого вы можете установить предпочтительную максимальную ширину макета или ограничение ширины.

Создайте ограничения, прикрепляя метки к левому и правому краям супервизора и выставляя ярлыки в вертикальном «стеке». В каждом случае вы можете добавить отступы, чтобы дать вашему оповещению немного границы.

Это может показаться большим количеством кода, поэтому вы можете прочитать статьи, которые я написал на visual format for auto layout и creating constraints in code, с ассоциированным autolayout convenience category, чтобы сделать вашу жизнь проще.

+1

Прежде всего спасибо за ответ. Во-вторых, сообщение в блоге удивительно, что ДЕЙСТВИТЕЛЬНО помогло мне самому получить ответ. Вы правы, это требует некоторого кода и игры вокруг, но это в значительной степени помогло мне в понимании кодирования ограничений вместо этого, спасибо! – StuartM

+0

Добро пожаловать! – jrturton

+0

Привет, я на самом деле всегда использовал CGRectZero, пока не использую этот проект с открытым исходным кодом https://github.com/BaiduLBS/BaiduMapKit, самый популярный набор карт в Китае. Когда экземпляр своего представления карты (подкласс UIView) в коде и передается CGRectZero для init (frame :), он всегда отображается неправильно в первый раз! После первого раза, когда он будет отображаться правильно, любой размер, отличный от нуля, не будет иметь этой проблемы. Я никогда не понимаю, почему. Есть ли у вас какие-либо идеи ? – Qiulang

0

Если вы отправляетесь на автоматический макет маршрута, вы можете добавить ограничения, которые будут содержать надлежащее пространство между каждой меткой и правильное пространство между верхней и нижней частью представления с помощью первой и последней меток. Однако, если вы не делаете этого в Interface Builder, вы также можете пропустить и с использованием автоматического макета, потому что довольно просто настроить высоту представления при добавлении меток.

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

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

0

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

Вот краткий пример, обратите внимание, что мы не используем фрейм, и используя CGRectZero для наших UILabels, позиционирование происходит от updateConstraints. Я использую Visual Format Language для компоновки меток, которые я рекомендую, если вы делаете это программно.

Здесь мы делаем метки шириной родительского вида, а затем просто складываем друг на друга.

#import "View.h" 

@implementation View{ 
    UILabel *_label1; 
    UILabel *_label2; 
    UILabel *_label3; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     _label1 = [[UILabel alloc] initWithFrame:CGRectZero]; 
     _label1.translatesAutoresizingMaskIntoConstraints = NO; 
     _label1.text = @"LABEL 1"; 

     _label2 = [[UILabel alloc] initWithFrame:CGRectZero]; 
     _label2.translatesAutoresizingMaskIntoConstraints = NO; 
     _label2.text = @"LABEL 2"; 

     _label3 = [[UILabel alloc] initWithFrame:CGRectZero]; 
     _label3.translatesAutoresizingMaskIntoConstraints = NO; 
     _label3.text = @"LABEL 3"; 

     [self addSubview:_label1]; 
     [self addSubview:_label2]; 
     [self addSubview:_label3]; 
    } 


    [self updateConstraintsIfNeeded]; 

    return self; 
} 

-(void)updateConstraints 
{ 
    [super updateConstraints]; 

    NSDictionary *_viewsDictionary = NSDictionaryOfVariableBindings(_label1,_label2,_label3); 


    // Set the contraintsto span the entire width of the super view 
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_label1]-|" 
                    options:0 
                    metrics:nil 
                    views:_viewsDictionary]; 

    [self addConstraints:constraints]; 

    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_label2]-|" 
                    options:0 
                    metrics:nil 
                    views:_viewsDictionary]; 
    [self addConstraints:constraints]; 

    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_label3]-|" 
                    options:0 
                    metrics:nil 
                    views:_viewsDictionary]; 

    [self addConstraints:constraints]; 


    // Last setup the vertical contraints other wise they will end up in a random place 
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_label1]-[_label2]-[_label3]" 
                    options:0 
                    metrics:nil 
                    views:_viewsDictionary]; 
    [self addConstraints:constraints]; 
} 

/* 
// Only override drawRect: if you perform custom drawing. 
// An empty implementation adversely affects performance during animation. 
- (void)drawRect:(CGRect)rect 
{ 
    // Drawing code 
} 
*/ 

@end 
Смежные вопросы