2014-11-05 3 views
1

Проанализировав какое-то странное поведение в iOS 8.0, касающееся поведения автоматического макета, и искали какие-либо советы или помогали решить эту проблему. У меня есть UIView, который содержит другой UIView как subView, который содержит две метки. Ограничения для этих меток добавляются программно следующим образом:Программный автоматический макет Проблема iOS 8.0

//StreamCaptionTextView.m 
    - (void)updateConstraints 
    { 
     NSDictionary *views = @{ 
           @"title" : self.titleLabel, 
           @"desc" : self.descLabel 
           }; 

     NSDictionary *metrics = @{ 
           @"top" : @0, 
           @"middle" : @(-2) 
           }; 

     [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[title]-0-|" options:0 metrics:metrics views:views]]; 
     [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[desc]-0-|" options:0 metrics:metrics views:views]]; 
     [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[title]-middle-[desc(==title)]" options:0 metrics:metrics views:views]]; 

     [super updateConstraints]; 
    } 

Родитель вид этого LabelView имеет ограничения в месте для LabelView, а также.

//StreamCaptionView which contains the StreamCaptionTextView 
- (void)updateConstraints 
{ 
    [self removeConstraints:self.constraints]; 

    NSMutableDictionary *views = [[NSMutableDictionary alloc] initWithDictionary:@{ 
                       @"image" : self.profileImageBtn, 
                       @"leftView" : self.leftText 
                       }]; 
    NSDictionary *metrics = @{ 
          @"top"  : @6, 
          @"left"  : @8, 
          @"imageSize" : @24, 
          @"marginText" : @10, 
          @"maxWidth" : @120 
          }; 

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[image(imageSize)]" options:0 metrics:metrics views:views]]; 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[leftView]-top-|" options:0 metrics:metrics views:views]]; 

    if(self.rightAcessoryView) 
    { 
    views[@"rightView"] = self.rightAcessoryView ; 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-left-[image(imageSize)]-2-[leftView]-10-[rightView(maxWidth)]-10-|" options:0 metrics:metrics views:views]]; 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[rightView]-top-|" options:0 metrics:metrics views:views]]; 
    } 
    else 
    { 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-marginText-[image(imageSize)]-2-[leftView]-marginText-|" options:0 metrics:metrics views:views]]; 
    } 

    [super updateConstraints]; 
} 


//This is the View that contains the captionView 
- (void)setVo:(RecordingStreamItemVO *)vo 
    { 
     _vo = vo; 

     __weak RecordingDetailVideoView *_self = self; 

     self.captionView.title   = vo.user.screenname; 
     self.captionView.subTitle   = vo.title; 
     self.captionView.profileImageURL = vo.user.pictureURL; 

     //Here, the captionView is the rectangular blur, inside of the 
     //captionView is another UIView that contains the UILabels. 

    } 

По какой-то причине только на iOS 8.0 метки не получают должным образом визуализацию в labelView. Это нормально работает на iOS 8.1 и 7.1 и т. Д. Я попытался сделать недействительными ограничения с помощью [self.labelView setNeedsUpdateConstraints], но это не похоже на то, что исправить проблему. Я немного искал эту проблему, и я видел, что у других людей были проблемы с автозапуском с iOS 8.0, но хотелось бы проверить, является ли это проблемой iOS и любыми потенциальными обходными решениями, которые я могу реализовать.

Labels RenderingLabels Not Rendering

// Вот некоторые фотографии, показывающие, что это выглядит как в визуальном отладчике Xcode

// Первая фотография находится на прошивке 8.1, которая работает должным образом

enter image description here

// Эта фотография находится на iOS 8.0, которая, кажется, игнорирует ограничение.

enter image description here

// ИОС 8,0

layer = <CALayer: 0x17396c90>> 
    | | | | | | | | | | <StreamCaptionView: 0x15f1fe10; frame = (0 146; 320 35); layer = <CALayer: 0x15f2b3e0>> 
    | | | | | | | | | | | <UIButton: 0x15fcc240; frame = (10 6; 24 24); opaque = NO; layer = <CALayer: 0x15fcc340>> 
    | | | | | | | | | | | | <UIImageView: 0x1700d1c0; frame = (0 0; 24 24); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1700d240>> 
    | | | | | | | | | | | <StreamCaptionTextView: 0x15fcc410; frame = (36 6; 274 23); layer = <CALayer: 0x15f2f620>> 
    | | | | | | | | | | | | <MarqueeLabel: 0x15f2f650; baseClass = UILabel; frame = (0 0; 274 13.5); text = 'test1'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15f200b0>> 
    | | | | | | | | | | | | | <UILabel: 0x17378d20; frame = (0 0; 26 0); text = 'test1'; userInteractionEnabled = NO; tag = 700; animations = { position=<CAKeyframeAnimation: 0x173b8960>; }; layer = <_UILabelLayer: 0x17378de0>> 
    | | | | | | | | | | | | | <UILabel: 0x173906b0; frame = (45 0; 22 0); text = 'test1'; userInteractionEnabled = NO; tag = 701; animations = { position=<CAKeyframeAnimation: 0x173b8a60>; }; layer = <_UILabelLayer: 0x17390770>> 
    | | | | | | | | | | | | <MarqueeLabel: 0x17390c40; baseClass = UILabel; frame = (0 11.5; 274 13.5); text = 'Test'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17390d60>> 
    | | | | | | | | | | | | | <UILabel: 0x17390940; frame = (0 0; 17 0); text = 'Test'; userInteractionEnabled = NO; tag = 700; animations = { position=<CAKeyframeAnimation: 0x173b93a0>; }; layer = <_UILabelLayer: 0x17390a00>> 
    | | | | | | | | | | | | | <UILabel: 0x173a1640; frame = (82 0; 48 0); text = 'Test'; userInteractionEnabled = NO; tag = 701; animations = { position=<CAKeyframeAnimation: 0x173b94a0>; }; layer = <_UILabelLayer: 0x173a1700>> 
    | | | | | | | | | <_UITableViewCellSeparatorView: 0x173ae010; frame = (15 179.5; 305 0.5); layer = <CALayer: 0x173ad1d0>> 
    | | | | | | | | <TimePublishedDetailView: 0x173a1d60; frame = (238.5 20; 71.5 11); layer = <CALayer: 0x173a1ef0>> 
    | | | | | | | | | <UIImageView: 0x173a21e0; frame = (0 0; 9 9); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x173a2260>> 
    | | | | | | | | | <UILabel: 0x173a85d0; frame = (16 -2; 55.5 13.5); text = '5 hours ago'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x173a8550>> 

Update:

я на самом деле решил это в контроллере родительского вида с очень простым исправлением.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 

    [self.view addSubview:self.detailsView]; 
    [self.view setNeedsUpdateConstraints]; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self loadDetails]; 

    [self.view layoutIfNeeded]; //This fixed the iOS 8.0 problem 

} 

//In my case the self.detailsView property contains the view hierarchy which 
//contains the UILabels that weren't being rendered properly way down 
//in the view hierarchy. calling layoutIfNeeded fixes this problem for me. 
+0

Я знаю, что это не то, что вы ищете, но когда-нибудь пробовали один из этого? https://github.com/smileyborg/PureLayout Это действительно упрощает процесс записи ограничений и делает его более интуитивным для тех, кто их читает. –

+0

Вы пробовали отлаживать его с помощью View Debugger? Вы должны быть в состоянии видеть, что именно происходит, как позиционируется вид и какие ограничения играют – sha

+0

@sha Я включил некоторые фотографии визуального отладчика, который имеет Xcode. Я вижу, что в iOS 8.0 позиция Constraint отличается от 8.1. – zic10

ответ

0

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

po [[UIWindow keyWindow] recursiveDescription] 

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

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

Теперь у меня есть эти журналы я замечаю следующие строки:

| | | | | | | | | | | | | <UILabel: 0x17378d20; frame = (0 0; 26 0); text = 'test1'; userInteractionEnabled = NO; tag = 700; animations = { position=<CAKeyframeAnimation: 0x173b8960>; }; layer = <_UILabelLayer: 0x17378de0>> 
    | | | | | | | | | | | | | <UILabel: 0x173906b0; frame = (45 0; 22 0); text = 'test1'; userInteractionEnabled = NO; tag = 701; animations = { position=<CAKeyframeAnimation: 0x173b8a60>; }; layer = <_UILabelLayer: 0x17390770>> 

Таким образом, все этикетки, кажется, не имеют высоту.

Эта линия может быть выключен:

@"V:|-top-[title]-middle-[desc(==title)]" 

Это не похоже, чтобы нажать на дно, поэтому он не может дать название высоты, ни DESC?Попробуйте сделать что-то вроде этого:

@"V:|-top-[title]-middle-[desc(==title)]-|" 

Или дать минимальную высоту:

@"V:|-top-[title(>=10)]-middle-[desc(==title)]" 
+0

Это должно быть строка в выражении else ниже if (self.rightAccessoryView) – zic10

+0

спасибо за ваши предложения, которые я пробовал, но, к сожалению, они не решили мою проблему. Эта иерархия представлений довольно сложна, и в ней много деталей. Я понимаю, что это всего лишь небольшой фрагмент гораздо большей картины. Одна вещь, которую я заметил, это то, что в моем представленииDidLoad я загружаю все свойства для этой иерархии представлений. Тем не менее, переход на другой контроллер и обратно будет запускать viewWillAppear, и метки будут загружены правильно на iOS 8.0 в этом сценарии. Я не уверен, что это очень помогает. – zic10

+0

В чем разница в визуальном дереве при рекурсивном описании, когда это неправильно, и когда оно работает после viewWillAppear? –

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