Проанализировав какое-то странное поведение в 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 и любыми потенциальными обходными решениями, которые я могу реализовать.
// Вот некоторые фотографии, показывающие, что это выглядит как в визуальном отладчике Xcode
// Первая фотография находится на прошивке 8.1, которая работает должным образом
// Эта фотография находится на iOS 8.0, которая, кажется, игнорирует ограничение.
// ИОС 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.
Я знаю, что это не то, что вы ищете, но когда-нибудь пробовали один из этого? https://github.com/smileyborg/PureLayout Это действительно упрощает процесс записи ограничений и делает его более интуитивным для тех, кто их читает. –
Вы пробовали отлаживать его с помощью View Debugger? Вы должны быть в состоянии видеть, что именно происходит, как позиционируется вид и какие ограничения играют – sha
@sha Я включил некоторые фотографии визуального отладчика, который имеет Xcode. Я вижу, что в iOS 8.0 позиция Constraint отличается от 8.1. – zic10