基于内容调整UIView大小

4
我有一个视图,其中填充了许多使用解析XML得到的标签。该视图在UIScrollView中。其中一些XML对于标签来说太长了。我正在根据XML内容调整标签大小。当标签被重新调整大小时,它们会重叠后续的标签,因为我的UIView(位于UIScrollView内部)没有被重新调整大小。我已经在互联网上搜寻了几个小时,试图找到答案,但我尝试过的所有方法都没有达到我想要的效果。非常感谢您的帮助。
这是我的populateLabels方法。
-(void) populateLabels {

NSString *noInfo = (@"No Information Available");
lblCgName.text = _Campground.campground;
NSString *cgLoc = _Campground.street1; 
NSString *cgCity = _Campground.city;
NSString *cgState = _Campground.state1;
NSString *cgCountry = _Campground.country;
NSString *cgZipPostal = _Campground.zipPostal;
cgLoc = [[cgLoc stringByAppendingString:@", "] stringByAppendingString:cgCity];
cgLoc = [[cgLoc stringByAppendingString:@", "] stringByAppendingString:cgState];
cgLoc = [[cgLoc stringByAppendingString:@", "] stringByAppendingString:cgCountry];
cgLoc = [[cgLoc stringByAppendingString:@" "] stringByAppendingString:cgZipPostal];
lblCgLoc.text = cgLoc;
double dRate = [_Campground.regRate1 doubleValue];
double dRate2 = [_Campground.regRate2 doubleValue];
NSString *rate = [[NSString alloc] initWithFormat:@"$%0.2f",dRate];
NSString *rate2 = [[NSString alloc] initWithFormat:@"$%0.2f",dRate2];
if ([rate2 isEqualToString:@"$0.00"]) {
    lblRate.text = rate;
} else {
    rate = [[rate stringByAppendingString:@" - "] stringByAppendingString:rate2];
    lblRate.text = rate;
}
double dPaRate = [_Campground.paRate1 doubleValue];
double dPaRate2 = [_Campground.paRate2 doubleValue];
NSString *paRate = [[NSString alloc] initWithFormat:@"$%0.2f",dPaRate];
NSString *paRate2 = [[NSString alloc] initWithFormat:@"$%0.2f",dPaRate2];
if ([paRate2 isEqualToString:@"$0.00"]) {
    lblPaRate.text = paRate;
} else {
    paRate = [[paRate stringByAppendingString:@" - "] stringByAppendingString:paRate2];
    lblPaRate.text = paRate;
}
lblLocal1.text = _Campground.localPhone1;
lblLocal2.text = _Campground.localPhone2;
lblTollFree.text = _Campground.tollFree;
lblFax.text = _Campground.fax;
lblEmail.text = _Campground.email;
lblWebsite.text = _Campground.website;
NSString *gps = _Campground.latitude;
NSString *longitude = _Campground.longitude;
gps = [[gps stringByAppendingString:@", "] stringByAppendingString:longitude];
lblGps.text = gps;
lblHighlights.text = _Campground.highlights;
lblHighlights.lineBreakMode = UILineBreakModeWordWrap;
lblHighlights.numberOfLines = 0;

//label resizing

CGSize maximumLabelSize = CGSizeMake(296,9999);

CGSize expectedLabelSize = [_Campground.highlights sizeWithFont:lblHighlights.font 
                                  constrainedToSize:maximumLabelSize 
                                                  lineBreakMode:lblHighlights.lineBreakMode]; 

//adjust the label the the new height.
CGRect newFrame = lblHighlights.frame;
newFrame.size.height = expectedLabelSize.height;
lblHighlights.frame = newFrame;

lblTents.text = _Campground.tents;
lblNotes.text = _Campground.notes;
lblDirections.text = _Campground.directions;
lblRentals.text = _Campground.rentals;

}

我很感谢您的建议,但那并不是我真正需要的。他们正在使用代码创建滚动视图并调整其大小。我想要重新调整已经存在于滚动视图中的视图的大小。一切都运作良好,它可以滚动到底部。我只需要扩展标签所在的视图即可。 - tallybear
我建议您首先创建所有标签,然后在此之后动态计算视图高度 - 标签高度 + 标签间偏移高度 + 页眉页脚偏移量。现在有了这个高度,您可以创建您的视图,然后在其中添加标签。 - rishi
3个回答

3
< p >这个- (void) populateLabels方法在哪里?如果它在视图控制器中,你应该可以轻松访问需要调整大小的视图。或者,如果标签(看起来已经创建了)已添加到需要调整大小的视图中,则可以访问其父视图。你已经拥有所需的大小,只需在方法结束时设置超级视图的框架大小即可。

如果您首先要根据字符串内容找到每个标签的大小,则需要使用NSString方法:-sizeWithFont。有几个变体允许您指定约束:

计算单行文本的度量 - sizeWithFont: - sizeWithFont:forWidth:lineBreakMode: - sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: 计算多行文本的度量 - sizeWithFont:constrainedToSize: - sizeWithFont:constrainedToSize:lineBreakMode:

请记住,UILables仅显示1行文本。还要记住,这将返回字符串占用的大小。像UILabels和UITextViews这样的视图倾向于添加填充,因此在计算高度时可能需要考虑这一点。在计算出高度并放置每个标签之后,您应该知道超级视图需要的大小并相应地设置它。此外,如果您不知道哪个标签将是最后/最低/最远的视图(超级视图的大小应该是原点.y +最后一个视图的size.height),您可以执行以下操作:

CGFloat totalHeight = 0.0f;
for (UIView *view in superView.subviews)
    if (totalHeight < view.frame.origin.y + view.frame.size.height) totalHeight = view.frame.origin.y + view.frame.size.height;

如果您还不知道它的高度,那么这将为您提供superview的高度(如果需要,您也可以为宽度执行相同的操作)。


populateLabels方法位于我的CampgroundDetailsViewController.m文件中。在该文件的nib中,我将所有对象(标签、文本视图、按钮等)放置在一个视图内,然后将该视图放置在滚动视图内。我是否做错了什么? - tallybear
我看不出来有什么问题,在该方法的末尾只需调整包含标签/文本/视图/按钮等的视图的大小,同时还应设置滚动视图的contentSize以适应。您可以通过CampgroundDetailsViewController的类实例变量访问这两个视图。 - Aaron Hayman
你知道如何根据内容动态设置视图吗?我听说需要使用sizeToFit,但是我应该传入什么呢? - tallybear
你是指标签的大小吗?你可以使用每个NSString实例可用的sizeWithFont:方法找到字符串所占用的矩形大小。此方法有几种变体,允许你限制大小。我会更新我的回答。 - Aaron Hayman

1

你真的需要使用大量的标签吗?
看起来你需要使用UITextView或UIScrollView。


我考虑过使用UITextView,但问题在于我的目标用户群。我正在构建的应用程序是为房车旅行者设计的。我们目前有一个iPhone应用程序,但我们收到的抱怨比赞扬多。它使用UITextView来显示“方向”、“亮点”和“注释”部分。他们抱怨一旦到达TextView后无法滚动视图。我们99%的抱怨都是因为我们的会员不知道如何使用他们的设备。 - tallybear
如果UITextView中的内容少于UITextView本身,它将无法滚动。我不认为在这里使用UITextView会有任何问题。但这取决于你。 - Valeriy Van
我已经到了这个地步,只想告诉老年人去适应并使用UITextView。我刚用TextView替换了“Highlights”标签,它非常出色的运行了。那么我就不必调整视图的大小,我可以将其设置为静态的,并加载一堆TextViews,而毫不担心。 - tallybear
一堆UITextViews?有趣。您只需要一个UITextView来处理所有文本内容。 - Valeriy Van
也许我没有理解你的问题。如果你需要强制重新布局子视图,请调用[self layoutSubviews]。不幸的是,这个方法的默认实现什么也不做,你需要自己实现它。 - Valeriy Van
好的,这里有不同的部分。我正在构建的应用程序列出了露营地的设施等信息供房车主使用。公园的指导路线、公园亮点、关于公园的附加说明等。我为每个部分使用了不同的UITextView,因为它们比一行长。起初我使用标签并根据内容展开它们。然后反过来,我想根据所有标签(现在是TextViews)的总内容扩展(或收缩)视图。我仍然遇到一个调整基于其内容调整大小的问题,但我没有之前那么糟糕了。 - tallybear

1
调整UIView大小的一般方法是使用sizeToFit基于其子视图。此方法会自动调整您的UIView大小。
如果您想限制大小,则需要使用sizeThatFits:此方法不会自动调整您的UIView大小,而是返回大小。
顺便说一下:这两种方法仅考虑子视图,因此不包括绘图或核心文本。

我尝试在我的scrollView上使用sizeToFit,但它没有任何作用。我的scrollView里面有一个View,所有的东西都在这个View上。我应该换一种方式吗? - tallybear

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接