10

UISegmentedControl を使用しようとしていますが、セグメントの幅の計算に問題があります。コントロールはセグメントをすべて同じ幅にしますが、これは次のような一部のタイトルでは機能しません:

http://morrisphotoart.com/tmp/Scr​​eenshot2011-07-13_21.17.33.png

フォントがわかっていればセグメント幅を計算するコードを記述して setWidth:forSegmentAtIndex: メソッドを呼び出すことはできますが、フォントを取得するにはどうすればよいでしょうか? それとも別の方法がありますか?

左と中央のセグメントのタイトルは固定されていないため、幅をハードコーディングできません。

4

4 に答える 4

30

iOS 5 以降をサポートできる場合は、プロパティapportionsSegmentWidthsByContentを使用して に設定できますYES

iOS 5ドキュメントから:

aportionsSegmentWidthsByContent

コントロールがコンテンツの幅に基づいてセグメントの幅を調整しようとするかどうかを示します。

@property(nonatomic) BOOL 配分SegmentWidthsByContent

討論

このプロパティの値が YES の場合、幅の値が 0 のセグメントについて、コントロールはコンテンツの幅に基づいてセグメントの幅を調整しようとします。

于 2013-03-06T11:08:30.510 に答える
26

編集:より簡単なオプションはapportionsSegmentWidthsByContent、@Camsoft の回答 hereに記載されているように、iOS 5 プロパティを使用することです。


まあ、私は最終的にサブビューを突っ込んでUIFontを取得しました(これは将来のiOSで壊れる可能性があります)。モジュラー/再利用の愛好家として、このルーチンを作成して、コントロール内のセグメントがタイトルに対して均等に配置されるようにスペースを分散しました。

-(void)resizeSegmentsToFitTitles:(UISegmentedControl*)segCtrl {
    CGFloat totalWidths = 0;    // total of all label text widths
    NSUInteger nSegments = segCtrl.subviews.count;    
    UIView* aSegment = [segCtrl.subviews objectAtIndex:0];
    UIFont* theFont = nil;

    for (UILabel* aLabel in aSegment.subviews) {
        if ([aLabel isKindOfClass:[UILabel class]]) {
            theFont = aLabel.font;
            break;
        }
    }

    // calculate width that all the title text takes up
    for (NSUInteger i=0; i < nSegments; i++) {
        CGFloat textWidth = [[segCtrl titleForSegmentAtIndex:i] sizeWithFont:theFont].width;
        totalWidths += textWidth;
    }

    // width not used up by text, its the space between labels
    CGFloat spaceWidth = segCtrl.bounds.size.width - totalWidths;   

    // now resize the segments to accomodate text size plus 
    // give them each an equal part of the leftover space
    for (NSUInteger i=0; i < nSegments; i++) {
        // size for label width plus an equal share of the space
        CGFloat textWidth = [[segCtrl titleForSegmentAtIndex:i] sizeWithFont:theFont].width;
        // roundf??  the control leaves 1 pixel gap between segments if width 
        // is not an integer value, the roundf fixes this
        CGFloat segWidth = roundf(textWidth + (spaceWidth / nSegments));    
        [segCtrl setWidth:segWidth forSegmentAtIndex:i];
    }
}
于 2011-07-15T20:36:52.407 に答える
8
NSArray *itemArray = [NSArray arrayWithObjects: @"Title1", @"Title2", @"Titl3", @"Title4",nil];
segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
segmentedControl.frame = CGRectMake(0, 0, 310, 35);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.selectedSegmentIndex = 0;
[segmentedControl addTarget:self action:@selector(pickOne:) forControlEvents:UIControlEventValueChanged];   
segmentedControl.tintColor=[UIColor grayColor];

for (id segment in [segmentedControl subviews]) 
{
    for (id label in [segment subviews]) 
    {
        if ([label isKindOfClass:[UILabel class]])
        {

            [label setTextAlignment:UITextAlignmentCenter];
            [label setFont:[UIFont boldSystemFontOfSize:12]];
        }
    }           
}
于 2011-07-14T04:32:27.910 に答える
-1

iOS 7.1.1 に対応。UISegmentedControl の新しいフレーム サイズのみを計算し、残り (セグメントの比率) は iOS によって処理されます (apportionsSegmentWidthsByContent に基づく)。

自動レイアウトがオンの場合、これは機能しないことに注意してください。

void styleSegment_fitTitles(UISegmentedControl *segCtrl) {

    // Fit segments' titles
    [segCtrl sizeToFit];

    CGFloat em = font.pointSize;
    CGRect segCtrlRect = segCtrl.bounds;
    CGFloat segCtrlWidth = segCtrlRect.size.width + segCtrl.numberOfSegments*em;
    CGFloat segCtrlHeight = segCtrlRect.size.height + em;
    CGFloat segmentY = segCtrl.frame.origin.y - (segCtrlHeight - segCtrlRect.size.height)/2;
    segCtrl.frame = CGRectMake(segCtrl.frame.origin.x, segmentY, segCtrlWidth, segCtrlHeight);
}
于 2014-05-06T10:52:41.703 に答える