使用 Interface Builder 动态调整 UILabel 的大小并在其下方重新定位 UIView

Posted

技术标签:

【中文标题】使用 Interface Builder 动态调整 UILabel 的大小并在其下方重新定位 UIView【英文标题】:Resize UILabel dynamically and reposition UIViews below it using Interface Builder 【发布时间】:2013-04-10 14:01:27 【问题描述】:

我有一个UILabel,它可以包含任意数量的宽度受限的行。我调整UILabel 的大小以适应给定的文本没有问题,但是,我正在实现一个“查看更多...”/“查看更少...”按钮,这将增加或减少@987654325 的大小@。基于此,任何低于此UILabelUIView's 都会受到影响,并且需要相应地在其y 轴上重新定位。

我正在尝试使用 XIB 文件中的内置功能,但完全没有运气。

UILabel 的自动调整大小设置:

为 UILabel 下的所有 UIView 自动调整大小:

有人能在这里为我指出正确的方向吗?所以基本上一个场景是:

    屏幕加载 标签填充了一定数量的可用文本,宽度受限 UIView's 下面的 UILabel 被重新定位,因为 UILabel 的高度比 XIB 文件中显示的高度增加了 用户按下“查看更多”,UILabel 会调整大小以适应所有可用文本并增加高度,所有 UIView 都会相应地重新定位到屏幕下方 用户按下“查看更少”,UILabel 的高度会降低,隐藏更多文本,UIView's 会相应地向上移动。

谢谢,希望解释清楚!我正在尝试在 XIB 文件中尽可能多地减少代码,但我的所有 UI 元素仍然可以通过 IBOutlets 访问,如果这被证明是唯一的解决方案 (我希望不是) .

注意:我需要支持ios4.3及以上,所以无法使用iOS6自动布局功能。

【问题讨论】:

如果您使用自动布局,这可以只使用扩展和收缩标签所需的代码来完成。你有理由不使用它吗? 抱歉我不明白你的问题?通过调整标签的高度来扩展和收缩标签,同时将其限制为特定宽度,当按下“查看更多/查看更少”按钮时会发生此事件 我的问题是关于自动布局。为什么要使用 struts 和 springs 而不是自动布局(在 iOS 6 中默认打开)。是否需要支持 iOS 6 之前的操作系统? 抱歉误会了。支持 4.3+ 所以不能使用自动布局功能。 【参考方案1】:

自动调整大小通常仅在您更改父视图的大小时强制执行子视图布局。您可以通过 IBOutlets 将其中的大部分链接起来,但是,当您点击查看更多按钮时,您必须告诉您的父视图调整大小。

如果您愿意,您可以在 UIView 上使用这些扩展:http://glassofcocoa.com/blog/2012/11/14/uiview-extensions/,您可以很容易地手动完成并使用动画 - 看起来像:

//assume you have a BOOL value wether toggled or not called 'isViewingMore' and a stored startHeight
- (IBAction)didTapViewMore:(id)sender

    if (!_isViewingMore)
    
        _isViewingMore = YES;
        CGSize constraint = CGSizeMake(_myLabel.frame.size.width, CGFLOAT_MAX);
        CGFloat lblheight = [@"" sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:14.0f] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap].height;
        _myLabel.height = lblHeight;
    
    else
    
        _isViewingMore = NO;
        myView.height = startHeight
    
    UIView *lastView = nil;
    for (UIView *view in self.view.subviews)
    
        if ((id)view != (id)_myLabel)
        
            if (lastView == nil)
            
                view.top = _myLabel.bottom;
            
            else
            
                view.top = lastView.bottom;
            
            lastView = view;
        
    

如果您只想采用 IB 路线,则需要将您的子视图放在一个父视图中并调整父视图的大小 - 这应该告诉子视图更新他们的位置/大小。

希望这会有所帮助。

【讨论】:

【参考方案2】:

我最终无法使用自动调整大小的功能,因此我通过创建一个 UIView 解决了这个问题,该 UIView 充当所有子视图的容器,这些子视图位于扩展的 UILabel 之下。

然后,我能够创建一个辅助方法,根据全尺寸 UILabel 和半尺寸标签之间的差异调整框架。

- (void)repositionMoveableViewContainerWithFrame:(CGRect)newFrame animated:(BOOL)animated

    CGRect newContainerPosition = self.moveableViewsContainer.frame;
    CGFloat difference = (newFrame.size.height - self.adjustableLabel.frame.size.height);
    newContainerPosition.origin.y = newContainerPosition.origin.y + difference;

    if (animated) 
        // Adjust frame animated
     else 
        // Adjust frame without animation.
        

【讨论】:

以上是关于使用 Interface Builder 动态调整 UILabel 的大小并在其下方重新定位 UIView的主要内容,如果未能解决你的问题,请参考以下文章

如何像 Interface Builder 一样调整 iOS UI 组件的大小

Interface Builder 自动布局和调整大小

如何在 Interface Builder 中的 UIViewController 中自动调整 UIView Outlet 的大小

为啥在 Interface Builder 中更改字体大小会阻止 UILabel 调整大小以适应内容?

iOS:在 Interface Builder 中使用动态 contentSize 创建 UIScrollView

Interface Builder 以小增量降低情节提要、调整大小和重新定位视图