简体   繁体   English

自定义UISegmentedControl

[英]Custom UISegmentedControl

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. 我有2个图像,1表示段处于活动状态时应显示,而另一个图像处于非活动状态时应显示。 Can i override the style or something so i have a UISegmentedControl with my own images as active/inactive background? 我可以覆盖样式或其他东西,所以我有一个UISegmentedControl ,我自己的图像作为活动/非活动背景?

I had to add this extra code, in addition to having 2 different states for the "on" and "off" positions: 我不得不添加这个额外的代码,除了为“开”和“关”位置有2个不同的状态:

- (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新]而不是创建透明图像,因此:

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

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:

The simplest way would be to create your own control that mimics UISegmentedControl . 最简单的方法是创建自己的模仿UISegmentedControl的控件。 UISegmentedControl just arranges a series of buttons and manages their image states for you; UISegmentedControl只是安排一系列按钮并为您管理其图像状态; it doesn't do anything special. 它没有做任何特别的事情。

Yes, you you DO need 2 images (on and off) for each section of the segment bar. 是的,您需要为分段栏的每个部分提供2张图像(打开和关闭)。 (4 segments... 8 images.) But it lets you set a total of 16 choices! (4段...... 8张图片。)但它可以让你设置16个选项! (All with only consuming 1 row in your GUI.) (所有只在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". 无法将“tintClear”设置为“clear”。 (Not sure why it makes it black and white.) (不知道为什么它会变成黑色和白色。)

Can't set it to "hidden"... nothing will work at all. 无法将其设置为“隐藏”......根本不会有任何作用。

Can't set "background" to "clear". 无法将“背景”设置为“清除”。 (The background is NOT the segmentbar graphics.) (背景不是分段栏图形。)

I wrote something that works as @rpetrich was explaining without placing in a array and in my opinion is the easiest solution to this. 我写了一些有用的东西,因为@rpetrich正在解释而不放在一个数组中,在我看来这是最容易解决的问题。 Hope someone finds this useful 希望有人觉得这很有用

.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;
    }
}

它工作得很好

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

Try HMSegmentedControl, it allows images and other settings too. 尝试HMSegmentedControl,它也允许图像和其他设置。 Available at https://github.com/HeshamMegid/HMSegmentedControl 可在https://github.com/HeshamMegid/HMSegmentedControl获得

In order to do this you must listen for the UIControlEventValueChanged and change the image yourself. 为此,您必须监听UIControlEventValueChanged自行更改映像。 You shouldn't need to subclass the UISegmentedControl - remember composition over inheritance is preferred! 您不应该需要子类化UISegmentedControl - 请记住组合优先于继承

Swift 3.0 Version of Jon's answer. Swift 3.0版Jon的回答。

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

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 backgroundColor and tintColor to 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 :) 希望你觉得这个有用 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM