根据每个段中的标题更改分段控件的宽度?

Posted

技术标签:

【中文标题】根据每个段中的标题更改分段控件的宽度?【英文标题】:Change width of a segmented control based on titles in each segment? 【发布时间】:2012-08-12 23:44:51 【问题描述】:

这样开头,我喜欢:

然后我添加了一个段,这发生了: 宽度是在 IB 中设置的,而不是在代码中。

我所需要的只是一种动态计算宽度的方法。最后,它会做这样的事情:

control.width = (labelWidths + marginWidths);
// where marginWidths = (marginWidth * control.numberOfSegments)

【问题讨论】:

【参考方案1】:

prgrmr 的回答 here 中的方法可以很好地达到预期目的,但事实并非如此。

而不是使用自定义 UILabel 子视图增加不必要的开销, 我已经修改了上面链接中的示例代码来提出这个:

- (void)resizeSegmentsToFitTitles:(UISegmentedControl *)control 
    CGFloat textWidth = 0; // total width of all text labels
    CGFloat marginWidth = 0; // total width of all margins
    NSUInteger nSegments = control.subviews.count;
    UIView *aSegment = [control.subviews objectAtIndex:0];
    UIFont *theFont = nil;

    // get font for segment title label
    for (UILabel *label in aSegment.subviews) 
        if ([label isKindOfClass:[UILabel class]]) 
            theFont = label.font;
            break;
        
    

    // calculate width of text in each segment
    for (NSUInteger i = 0; i < nSegments; i++) 
        NSString *title = [control titleForSegmentAtIndex:i];
        CGFloat width = [title sizeWithFont:theFont].width;
        CGFloat margin = 15;

        if (width > 200) 
            NSString *ellipsis = @"…";
            CGFloat width2 = [ellipsis sizeWithFont:theFont].width;

            while (width > 200-width2) 
                title = [title substringToIndex:title.length-1];
                width = [title sizeWithFont:theFont].width;
            

            title = [title stringByAppendingString:ellipsis];
        

        [control setTitle:title forSegmentAtIndex:i];

        textWidth += width;
        marginWidth += margin;
    

    // resize segments to accomodate text size, evenly split total margin width
    for (NSUInteger i = 0; i < nSegments; i++) 
        // size for label width plus an equal share of the space
        CGFloat textWidth = [[control titleForSegmentAtIndex:i]
                             sizeWithFont:theFont].width;
        // the control leaves a 1 pixel gap between segments if width
        // is not an integer value; roundf() fixes this
        CGFloat segWidth = roundf(textWidth + (marginWidth / nSegments));
        [control setWidth:segWidth forSegmentAtIndex:i];
    

    // set control width
    [control setFrame:CGRectMake(0, 0, (textWidth + marginWidth), 30)];

【讨论】:

我在 ios7 中使用它来纠正分段控制器在不应该截断标题时的问题,但是最后一段不可点击...任何想法为什么? ***.com/questions/18890428/… Here 是简化的iOS 7 友好版本。【参考方案2】:

您可以使用属性apportionsSegmentWidthsByContent 并将其设置为YES

【讨论】:

当我以编程方式更改文本时,这似乎对我不起作用。 @primehalo 每次以编程方式更新文本后尝试设置此属性。 感谢@Rajesh 快速修复!!【参考方案3】:

如下图所示,将 Auto-Size 属性更改为“与内容成比例”。

【讨论】:

这应该是公认的答案 - 它是最快、最简单且效果很好的。谢谢你,Ankit。 文本被截断..它没有进入下一行【参考方案4】:

第一个选项如下所示:

segmentedControl.setWidth(100, forSegmentAt: 0)
segmentedControl.setWidth(50, forSegmentAt: 1)

这为您提供了单独大小的细分,同时坚持您定义的值,这意味着您可以根据需要调整美学。第二个选项如下所示:

segmentedControl.apportionsSegmentWidthsByContent = true

这会将完全控制权交给 iOS,这可能是大多数时候最好的做法。

适用于 iOS 5.0

hackingwithswift

【讨论】:

【参考方案5】:

它将调整分段控件的大小以适应每个分段的文本标签中的文本。

  override func viewDidLoad() 
    super.viewDidLoad()

   UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0
   

【讨论】:

以上是关于根据每个段中的标题更改分段控件的宽度?的主要内容,如果未能解决你的问题,请参考以下文章

通过更改分段控件更改视图

《iOS Human Interface Guidelines》——Segmented Control

在 Swift 的标头中使用分段控件更改 UICollectionView 的内容

如何从另一个 UIViewController 更改分段控件标题(设置)

如何使用分段控件显示 plist 中的所有类别?

带有 TableView 的 UINavigationBar 和 UITabBar 内的分段控件