objective-c 自定义 UISegmentedControl

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1281601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:04:57  来源:igfitidea点击:

Custom UISegmentedControl

iphoneobjective-ccocoa-touchuikituisegmentedcontrol

提问by

How do I make a custom UISegmentedControl?

我如何定制UISegmentedControl

I have 2 images, 1 that should be displayed when the segment is active and the other if the segment is inactive. Can i override the style or something so i have a UISegmentedControlwith my own images as active/inactive background?

我有 2 个图像,当段处于活动状态时应显示 1 个图像,如果段处于非活动状态时应显示另一个图像。我可以覆盖样式或其他东西,以便我将UISegmentedControl自己的图像作为活动/非活动背景吗?

回答by Jon

I had to add this extra code, in addition to having 2 different states for the "on" and "off" positions:

除了“开”和“关”位置有两种不同的状态外,我还必须添加这个额外的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Set set segControl background to transparent
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
    CGContextFillRect(context, rect);
    UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [self.segControl setBackgroundImage:transparentImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

    [self.segControl setDividerImage:transparentImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}

EDIT: Because this is getting some publicity, a cleaner solution is to use [UIImage new] instead of creating transparent images, as such:

编辑:因为这是得到一些宣传,更清洁的解决方案是使用 [UIImage new] 而不是创建透明图像,如下所示:

 [self.segControl setDividerImage:[UIImage new] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
 [self.segControl setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

回答by Bocaxica

You can use the methods which are described in the iOS developer libary:

您可以使用 iOS 开发人员库中描述的方法:

http://developer.apple.com/library/ios/ipad/#documentation/uikit/reference/UISegmentedControl_Class/Reference/UISegmentedControl.html

http://developer.apple.com/library/ios/ipad/#documentation/uikit/reference/UISegmentedControl_Class/Reference/UISegmentedControl.html

Scroll down to the "Customizing Appearance" section. There are methods to set background images for several button states, button divider images, etc.

向下滚动到“自定义外观”部分。有一些方法可以为多个按钮状态、按钮分隔图像等设置背景图像。

These methods are only available in iOS5 and later.

这些方法仅在 iOS5 及更高版本中可用。

@property tintColor  
– backgroundImageForState:barMetrics:
– setBackgroundImage:forState:barMetrics:
– contentPositionAdjustmentForSegmentType:barMetrics:
– setContentPositionAdjustment:forSegmentType:barMetrics:
– dividerImageForLeftSegmentState:rightSegmentState:barMetrics:
– setDividerImage:forLeftSegmentState:rightSegmentState:barMetrics:
– titleTextAttributesForState:
– setTitleTextAttributes:forState:

回答by rpetrich

The simplest way would be to create your own control that mimics UISegmentedControl. UISegmentedControljust arranges a series of buttons and manages their image states for you; it doesn't do anything special.

最简单的方法是创建自己的模仿UISegmentedControl. UISegmentedControl只需排列一系列按钮并为您管理它们的图像状态;它没有做任何特别的事情。

回答by FreeAppl3

I wrote something that works as @rpetrich was explaining without placing in a array and in my opinion is the easiest solution to this. Hope someone finds this useful

我写了一些像@rpetrich 解释的那样工作的东西,而不用放在数组中,在我看来,这是最简单的解决方案。希望有人觉得这很有用

.h

。H

IBOutlet UIButton *index0;
IBOutlet UIButton *index1;
IBOutlet UIButton *index2;
IBOutlet UIImageView *segMentControl;

-(IBAction)segmentSwitch:(UIButton *) buttonIndexPressed;

.m

.m

-(IBAction)segmentSwitch:(UIButton *) buttonIndexPressed
{
    if (buttonIpressed == index0)
    {
        [segmentControl setImage:[UIImage imageNamed:@"Seg1Sel.png"]];
        NSLog(@"index 0 pushed");

        index0.enabled = NO;
        index1.enabled = YES;
        index2.enabled = YES;        
    }
    else if (buttonIpressed == index1)
    {
         [segmentControl setImage:[UIImage imageNamed:@"Seg2Sel.png"]];
         NSLog(@"index 1 pushed");

         index0.enabled = YES;
         index1.enabled = NO;
         index2.enabled = YES;
    }
    else if (buttonIpressed == index2)
    {
        [segmentControl setImage:[UIImage imageNamed:@"Seg3Sel.png"]];
        NSLog(@"index 2 pushed");

        index0.enabled = YES;
        index1.enabled = YES;
        index2.enabled = NO;
    }
}

回答by Patricia

Yes, you you DO need 2 images (on and off) for each section of the segment bar. (4 segments... 8 images.) But it lets you set a total of 16 choices! (All with only consuming 1 row in your GUI.)

是的,对于分段栏的每个部分,您确实需要 2 张图像(打开和关闭)。(4 段... 8 幅图像。)但它可以让您设置总共 16 个选项!(所有这些都只在您的 GUI 中消耗 1 行。)

I got everything working EXCEPT... how do you hide the original segment bar graphics?

我一切正常,除了......你如何隐藏原始的段条图形?

Can't set alpha to 0. (It will also hide your images.)

不能将 alpha 设置为 0。(它也会隐藏您的图像。)

Can't set "tintClear" to "clear". (Not sure why it makes it black and white.)

无法将“tintClear”设置为“clear”。(不知道为什么它让它变成黑白的。)

Can't set it to "hidden"... nothing will work at all.

不能将它设置为“隐藏”......什么都不会起作用。

Can't set "background" to "clear". (The background is NOT the segmentbar graphics.)

无法将“背景”设置为“清除”。(背景不是段条图形。)

回答by virata

it works just fine

它工作得很好

[segmentControl setImage:[UIImage imageNamed:@"Rolenew.png"] forSegmentAtIndex:0];

回答by catanore

Try HMSegmentedControl, it allows images and other settings too. Available at https://github.com/HeshamMegid/HMSegmentedControl

试试 HMSegmentedControl,它也允许图像和其他设置。可在https://github.com/HeshamMegid/HMSegmentedControl 获得

回答by Saranjith

Swift 3.0 Version of Jon's answer.

Jon 的答案的 Swift 3.0 版本。

var transparentImage = UIGraphicsGetImageFromCurrentImageContext() as? UIImage
UIGraphicsEndImageContext()
segControl.setBackgroundImage(transparentImage, for: .normal, barMetrics: .default)
segControl.setDividerImage(transparentImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)

回答by arvinq

Swift 4

斯威夫特 4

This is how I managed it. Make a segmented control and insert segments using the images. Be sure to set one image as selected as this will be the initial selected index. Also set the backgroundColorand tintColorto clear so that segmented control will only show your image.

我就是这样管理的。使用图像制作分段控件并插入片段。确保将一张图像设置为选定的,因为这将是初始选定的索引。还将backgroundColortintColor设置为 clear 以便分段控件仅显示您的图像。

var newSegmentedControl: UISegmentedControl = {
        let segmentedControl = UISegmentedControl()

        segmentedControl.insertSegment(with: UIImage(named: "x_Selected.jpg"), at: 0, animated: true)
        segmentedControl.insertSegment(with: UIImage(named: "y_Normal.jpg"), at: 1, animated: true)

        segmentedControl.addTarget(self, action: #selector(segmentedControlChanged), for: .valueChanged)

        segmentedControl.selectedSegmentIndex = 0
        segmentedControl.backgroundColor = .clear
        segmentedControl.tintColor = .clear            

    }()

Function called when the value of segmented control changes.

当分段控件的值发生变化时调用的函数。

@objc func segmentedControlChanged(sender: UISegmentedControl) {

    if sender.selectedSegmentIndex == 0 {
        sender.setImage(UIImage(named: "x_Selected.jpg"), forSegmentAt: sender.selectedSegmentIndex)
        sender.setImage(UIImage(named: "y_Normal.jpg"), forSegmentAt: 1)
    } else if sender.selectedSegmentIndex == 1 {
        sender.setImage(UIImage(named: "x_Normal.jpg"), forSegmentAt: 0)
        sender.setImage(UIImage(named: "y_Selected.jpg"), forSegmentAt: sender.selectedSegmentIndex)
    } 

}

Hope you find this useful :)

希望你觉得这个有用 :)

回答by groundhog

In order to do this you must listen for the UIControlEventValueChangedand change the image yourself. You shouldn't need to subclass the UISegmentedControl - remember composition over inheritanceis preferred!

为此,您必须监听UIControlEventValueChanged并自己更改图像。您不应该需要继承UISegmentedControl -记住组合优先于继承