我有UIViewController
创建此布局:
给我带来麻烦的部分是底部较暗的区域,包含文字。
较暗的部分是UIScrollView
子类,它使用自动布局创建此布局:
我有几个UILabel
s(“Omschrijving”,“Informatie”,以及视图底部的小标签)和UITextView
(包含以“罗伯特兰登“)。
我将UITextView
的高度明确设置为60点,当点击“Meer”按钮时,我使用boundingRectWithSize:options:attributes:context
计算其全高。然后我将其高度约束常数从其先前的硬编码值更改为我计算的值。
这就是出错的地方。在UITextView
的高度变化之前,布局绝对正常。 UIScrollView
子类中的所有内容似乎都莫名其妙地移动了。我使用Reveal查看了视图层次结构:。
我几个小时以来一直在搞乱这些限制,我找不到解决方案。
所有视图都将translatesAutoresizingMaskIntoConstraints
设置为NO。
这是模拟器上的iOS 8,带有Xcode 6 b4。
我的init方法如下所示:
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.translatesAutoresizingMaskIntoConstraints = NO;
[self layoutIfNeeded];
[self addExpandButton];
[self setupUI];
[self setupConstraints];
[self layoutIfNeeded];
self.backgroundColor = [UIColor clearColor];
self.textView.backgroundColor = [UIColor clearColor];
self.textView.userInteractionEnabled = NO;
}
return self;
}
setupUI
创建所有视图并将它们添加到scrollView。为简洁起见,我删除了一些重复的代码行
- (void)setupUI
{
// Initialization
UILabel *descriptionLabel = [[UILabel alloc] initWithFrame:CGRectZero];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 60.0) textContainer:nil];
textView.translatesAutoresizingMaskIntoConstraints = NO;
textView.editable = NO;
textView.textContainerInset = UIEdgeInsetsMake(0.0, -5.0, 0.0, -5.0);
textView.textColor = [UIColor whiteColor];
// init all the UILabels with CGRectZero frames
// ...
// ...
UIView *separator = [[UIView alloc] initWithFrame:CGRectZero];
separator.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.5];
// Set the text
descriptionLabel.text = @"Omschrijving";
textView.text = @"Robert Langdon, hoogleraar kunstgeschiedenis en symboliek, wordt op een nacht wakker in een ziekenhuis in Florence zonder te weten hoe hij daar is beland. Geholpen door een stoïcijnse jonge vrouw, Sienna Brooks, vlucht Langdon en raakt hij verzeild in een duizelingwekkend avontuur. Langdon ontdekt dat hij in het bezit is van een reeks verontrustende codes, gecreëerd door een briljante wetenschapper; een genie dat geobsedeerd is door het einde van de wereld en het duistere meesterwerk Inferno van Dante Alighieri.";
// Set the text of the labels
// ...
// ...
descriptionLabel.font = [UIFont fontWithName:@"ProximaNova-Semibold" size:14.0];
textView.font = [UIFont fontWithName:@"ProximaNova-Regular" size:12.0];
informationLabel.font = [UIFont fontWithName:@"ProximaNova-Semibold" size:14.0];
UIFont *font = [UIFont fontWithName:@"ProximaNova-Regular" size:10.0];
// Set the font of the labels
// ...
// ...
// Add the views to the view hierarchy
[self addSubview:descriptionLabel];
[self addSubview:textView];
[self addSubview:separator];
[self addSubview:informationLabel];
// Add the other labels as subviews
// ...
// ...
[self.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UILabel class]]) {
UILabel *label = (UILabel *)obj;
[label sizeToFit];
label.textColor = [UIColor whiteColor];
}
}];
// Assign the local properties to properties
// ...
// ...
for (UIView *view in self.subviews) {
view.translatesAutoresizingMaskIntoConstraints = NO;
}
}
现在谈到约束。我有一个很大的方法,可以添加所有名为-addConstraints
的约束。
- (void)setupConstraints
{
// Omschrijving label top
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[descriptionLabel]-3-[textView]"
options:NSLayoutFormatAlignAllLeading
metrics:nil
views:@{@"descriptionLabel": self.descriptionLabel,
@"textView": self.textView}]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.descriptionLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:3.0]];
// Omschrijving label leading
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[descriptionLabel]"
options:0
metrics:nil
views:@{@"descriptionLabel": self.descriptionLabel}]];
// Text view width
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[textView(==width)]"
options:0
metrics:@{@"width": @220.0}
views:@{@"textView": self.textView}]];
// Text view height
NSArray *textViewHeightConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[textView(==60.0)]"
options:0
metrics:nil
views:@{@"textView": self.textView}];
[self addConstraints:textViewHeightConstraints];
self.textViewHeightConstraints = textViewHeightConstraints;
NSLog(@"%@", self.textViewHeightConstraints);
// Text view expand button
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[textView][expandButton(==12.0)]"
options:NSLayoutFormatAlignAllTrailing
metrics:nil
views:@{@"textView": self.textView, @"expandButton": self.expandButton}]];
// Separator
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[expandButton]-6-[separator]"
options:NSLayoutFormatAlignAllTrailing
metrics:nil
views:@{@"expandButton": self.expandButton, @"separator": self.separator}]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[separator(==textView)]"
options:0
metrics:nil
views:@{@"separator": self.separator, @"textView": self.textView}]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[separator(==0.5)]"
options:0
metrics:nil
views:@{@"separator": self.separator}]];
NSString *leftVisualFormatString = @"V:[separator]-6-[informationLabel]-spacing-[languageDescriptionLabel]-spacing-[categoryDescriptionLabel]-spacing-[publisherDescriptionLabel]-spacing-[publishedDateDescriptionLabel]-spacing-[pageCountDescriptionLabel]-|";
NSDictionary *descriptionViews = @{@"separator": self.separator,
@"informationLabel": self.informationLabel,
@"languageDescriptionLabel": self.languageDescriptionLabel,
@"categoryDescriptionLabel": self.categoryDescriptionLabel,
@"publisherDescriptionLabel": self.publisherDescriptionLabel,
@"publishedDateDescriptionLabel": self.publishedDateDescriptionLabel,
@"pageCountDescriptionLabel": self.pageCountDescriptionLabel};
NSDictionary *metrics = @{@"spacing": @1.0};
// All at once: vertical spacing and leading alignment for the labels on the left
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:leftVisualFormatString
options:NSLayoutFormatAlignAllLeading
metrics:metrics
views:descriptionViews]];
// Same, for the righthand labels
NSDictionary *views = @{@"languageLabel": self.languageLabel,
@"categoryLabel": self.categoryLabel,
@"publisherLabel": self.publisherLabel,
@"publishedDateLabel": self.publishedDateLabel,
@"pageCountLabel": self.pageCountLabel};
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[pageCountDescriptionLabel]-20-[pageCountLabel]"
options:0
metrics:nil
views:@{@"pageCountDescriptionLabel": self.pageCountDescriptionLabel,
@"pageCountLabel": self.pageCountLabel}]];
NSString *rightVisualFormatString = @"V:[languageLabel]-spacing-[categoryLabel]-spacing-[publisherLabel]-spacing-[publishedDateLabel]-spacing-[pageCountLabel]-|";
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:rightVisualFormatString
options:NSLayoutFormatAlignAllLeading
metrics:metrics
views:views]];
}
正如我所说,在我称之为这种方法之前一切正常:
- (void)tappedExpandButton:(id)sender
{
if (self.textViewHeightConstraints.count == 1) {
NSLayoutConstraint *constraint = self.textViewHeightConstraints.firstObject;
CGFloat newHeight = [self.textView.text boundingRectWithSize:CGSizeMake(self.textView.textContainer.size.width, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName: self.textView.font}
context:nil].size.height;
constraint.constant = ceilf(newHeight);
[self layoutIfNeeded];
}
}
谢谢!
答案 0 :(得分:1)
我想我已经明白了。由于某种原因,我还不明白,添加约束时包含UIScrollView
的框架已更改。这对我来说似乎仍然很奇怪,因为我认为只有它的contentSize
应该改变,但是从暗区(UIView
)到UIScrollView
添加约束来修复它。这是代码:
[self.darkEffectView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[descriptionView]|"
options:0
metrics:nil
views:@{@"descriptionView": self.descriptionView}]];
[self.darkEffectView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[descriptionView]|"
options:0
metrics:nil
views:@{@"descriptionView": self.descriptionView}]];