iOS 应用程序中的复选框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/650131/
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-08-30 15:45:17  来源:igfitidea点击:

Checkbox in iOS application

iosiphonecheckbox

提问by saikamesh

I need to add checkbox controls to my form. I know that there is no such control in iOS SDK. How could I do this?

我需要在表单中添加复选框控件。我知道 iOS SDK 中没有这样的控件。我怎么能这样做?

回答by Adrian

this has been driving me mad too and I found a different solution that works well for me and avoids having to use images.

这也让我发疯,我找到了一个不同的解决方案,它对我很有效并且避免使用图像。

  1. Add a new label object to Interface Builder.
  2. Create an IBOutlet property in Xcode and connect it up to it. In the code below I've called it 'fullyPaid' as I want to know if someone has fully paid a sum of money.
  3. Add the 2 functions below. The 'touchesBegan' function checks if you touched somewhere inside the 'fullyPaid' label object and if so, it calls the 'togglePaidStatus' function. The 'togglePaidStatus' function sets up two strings which have the unicode characters representing an empty box (\u2610) and a checked box (\u2611) respectively. Then it compares what's currently in the 'fullyPaid' object and toggles it with the other string.
  1. 向 Interface Builder 添加一个新标签对象。
  2. 在 Xcode 中创建一个 IBOutlet 属性并将其连接到它。在下面的代码中,我将其称为“fullyPaid”,因为我想知道是否有人已全额支付了一笔款项。
  3. 添加下面的2个函数。'touchesBegan' 函数检查您是否触摸了 'fullyPaid' 标签对象内的某处,如果是,它会调用 'togglePaidStatus' 函数。'togglePaidStatus' 函数设置两个字符串,它们的 unicode 字符分别代表一个空框 (\u2610) 和一个选中框 (\u2611)。然后它比较“fullyPaid”对象中当前的内容并将其与另一个字符串切换。

You might want to call the togglePaidStatus function in the viewDidLoad function to set it to an empty string initially.

您可能希望在 viewDidLoad 函数中调用 togglePaidStatus 函数以将其初始设置为空字符串。

Obviously you can add extra checks to prevent users toggling the checkbox if the label is not enabled, but that's not shown below.

显然,如果标签未启用,您可以添加额外的检查以防止用户切换复选框,但这在下面没有显示。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];   
    if (CGRectContainsPoint([fullyPaid frame], [touch locationInView:self.view]))
    {
        [self togglePaidStatus];
    }
}
-(void) togglePaidStatus
{
    NSString *untickedBoxStr = [[NSString alloc] initWithString:@"\u2610"];
    NSString *tickedBoxStr = [[NSString alloc] initWithString:@"\u2611"];   

    if ([fullyPaid.text isEqualToString:tickedBoxStr])
    {
        fullyPaid.text = untickedBoxStr;
    }
    else
    {
        fullyPaid.text = tickedBoxStr;
    }

    [tickedBoxStr release];
    [untickedBoxStr release];
}

回答by Eric Petroelje

Generally, you would use the UISwitch for checkbox-like functionality.

通常,您会使用 UISwitch 来实现类似复选框的功能。

You could roll your own though by using an image control with two images (checked/unchecked) and switching the images when they touch the control/

您可以通过使用带有两个图像(选中/未选中)的图像控件并在它们触摸控件时切换图像来滚动自己的图像/

回答by Brent Royal-Gordon

If you're showing a group of options and the user can select one of them, use a tableview with a checkmark accessory and a different text color on the selected row.

如果您正在显示一组选项并且用户可以选择其中一个,请使用带有复选标记附件和所选行上不同文本颜色的 tableview。

If you have a single option, your best bet is to use a switch. If you can't or don't want to, use a button, setting the normal image to an empty box and the selected image to a checked box. You'll have to make those two images yourself or find stock graphics to use for them.

如果您只有一个选项,最好的办法是使用 switch。如果您不能或不想,请使用按钮,将普通图像设置为空框,将所选图像设置为选中框。您必须自己制作这两个图像或找到用于它们的库存图形。

回答by S1LENT WARRIOR

Extending to Adrean's idea, i've achieved this using a very simple approach.
My idea is to change button (lets say checkBtn) text depending upon its state, and then change button's state in its IBAction.
Below is the code how i did this:

扩展到Adrean 的想法,我使用一种非常简单的方法实现了这一点。
我的想法是checkBtn根据其状态更改按钮(可以说)文本,然后在其IBAction.
下面是我如何做到这一点的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [checkBtn setTitle:@"\u2610" forState:UIControlStateNormal];    // uncheck the button in normal state
    [checkBtn setTitle:@"\u2611" forState:UIControlStateSelected];  // check the button in selected state
}

- (IBAction)checkButtonTapped:(UIButton*)sender {
    sender.selected = !sender.selected;    // toggle button's selected state  

    if (sender.state == UIControlStateSelected) {    
        // do something when button is checked 
    } else {
        // do something when button is unchecked
    }
}

回答by cannyboy

I wanted to do this programmatically, and also solve the problem that the hit area was really too small. This is adapted from various sources, including Mike and Mike's commenter Agha.

我想通过编程来做这个,同时也解决了命中区域真的太小的问题。这是改编自各种来源,包括 Mike 和 Mike 的评论者 Agha。

In your header

在你的标题中

@interface YourViewController : UIViewController {
    BOOL checkboxSelected;
    UIButton *checkboxButton;
}

@property BOOL checkboxSelected;;
@property (nonatomic, retain) UIButton *checkboxButton;

-(void)toggleButton:(id)sender;

And in your implementation

在你的实施中

// put this in your viewDidLoad method. if you put it somewhere else, you'll probably have to change the self.view to something else
// create the checkbox. the width and height are larger than actual image, because we are creating the hit area which also covers the label
UIButton* checkBox = [[UIButton alloc] initWithFrame:CGRectMake(100, 60,120, 44)];  
[checkBox setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal];
// uncomment below to see the hit area
// [checkBox setBackgroundColor:[UIColor redColor]];
[checkBox addTarget:self action:@selector(toggleButton:) forControlEvents: UIControlEventTouchUpInside];
// make the button's image flush left, and then push the image 20px left
[checkBox setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[checkBox setImageEdgeInsets:UIEdgeInsetsMake(0.0, 20.0, 0.0, 0.0)];
[self.view addSubview:checkBox];

// add checkbox text text
UILabel *checkBoxLabel = [[UILabel alloc] initWithFrame:CGRectMake(140, 74,200, 16)];
[checkBoxLabel setFont:[UIFont boldSystemFontOfSize:14]];
[checkBoxLabel setTextColor:[UIColor whiteColor]];
[checkBoxLabel setBackgroundColor:[UIColor clearColor]];
[checkBoxLabel setText:@"Checkbox"];
[self.view addSubview:checkBox];

// release the buttons
[checkBox release];
[checkBoxLabel release];

And put this method in too:

也把这个方法放进去:

- (void)toggleButton: (id) sender
{
    checkboxSelected = !checkboxSelected;
    UIButton* check = (UIButton*) sender;
    if (checkboxSelected == NO)
        [check setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal];
    else
        [check setImage:[UIImage imageNamed:@"checkbox-checked.png"] forState:UIControlStateNormal];

}

回答by slobodans

Here is my version of checkbox for iphone.

这是我的 iphone 复选框版本。

It is single class which extends UIButton. It is simple so i will paste it here.

它是扩展 UIButton 的单个类。这很简单,所以我会把它贴在这里。

CheckBoxButton.h file content

CheckBoxButton.h 文件内容

#import <UIKit/UIKit.h>

@interface CheckBoxButton : UIButton

@property(nonatomic,assign)IBInspectable BOOL isChecked;

@end

CheckBoxButton.m file content

CheckBoxButton.m 文件内容

#import "CheckBoxButton.h"

@interface CheckBoxButton()

@property(nonatomic,strong)IBInspectable UIImage* checkedStateImage;
@property(nonatomic,strong)IBInspectable UIImage* uncheckedStateImage;

@end

@implementation CheckBoxButton

-(id)init
{
    self = [super init];

    if(self)
    {
        [self addTarget:self action:@selector(switchState) forControlEvents:UIControlEventTouchUpInside];
    }

    return self;
}

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if(self)
    {
        [self addTarget:self action:@selector(switchState) forControlEvents:UIControlEventTouchUpInside];
    }

    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if(self)
    {
        [self addTarget:self action:@selector(switchState) forControlEvents:UIControlEventTouchUpInside];
    }

    return self;
}

-(void)setIsChecked:(BOOL)isChecked
{
    _isChecked = isChecked;

    if(isChecked)
    {
        [self setImage:self.checkedStateImage forState:UIControlStateNormal];
    }
    else
    {
        [self setImage:self.uncheckedStateImage forState:UIControlStateNormal];
    }
}

-(void)switchState
{
    self.isChecked = !self.isChecked;
    [self sendActionsForControlEvents:UIControlEventValueChanged];
}

@end

You can set images for checked/unchecked as well as isChecked property in the attribute inspector of visual studio.

您可以在 Visual Studio 的属性检查器中为选中/未选中以及 isChecked 属性设置图像。

enter image description here

在此处输入图片说明

To add CheckBoxButton in storyboard or xib, simple add UIButton and set custom class like on next image.

要在故事板或 xib 中添加 CheckBoxButton,只需添加 UIButton 并设置自定义类,如下一张图像。

enter image description here

在此处输入图片说明

Button will send UIControlEventValueChanged event, every time when isChecked state is changed.

按钮将发送 UIControlEventValueChanged 事件,每当 isChecked 状态改变时。

回答by Brayden

Everyones code here is very long, slightly messy, and could be done a lot simpler. I have a project on GitHub that subclass UIControl that you can download and check out and gives you an almost native checkbox UI element:

这里每个人的代码都很长,有点乱,而且可以做得更简单。我在 GitHub 上有一个项目,它是 UIControl 的子类,您可以下载并查看它,并为您提供几乎原生的复选框 UI 元素:

https://github.com/Brayden/UICheckbox

https://github.com/Brayden/UICheckbox

回答by mTouch

I made it with a UITextField to avoid drawing anything strange but I liked putting inside as text the tick unicode (Unicode Character 'CHECK MARK' (U+2713)) for the NSString: @"\u2713".

我用 UITextField 制作它以避免绘制任何奇怪的东西,但我喜欢将 NSString 的刻度 unicode(Unicode 字符“CHECK MARK”(U+2713))作为文本放入其中:@"\u2713"。

This way, in my .h file (implementing the protocol for the UITextField 'UITextFieldDelegate'):

这样,在我的 .h 文件中(实现 UITextField 'UITextFieldDelegate' 的协议):

UITextField * myCheckBox;

In my viewDidLoad or the function to prepare the UI:

在我的 viewDidLoad 或准备 UI 的函数中:

...
myCheckBox = [[UITextField alloc] initWithFrame:aFrame];
myCheckBox.borderStyle = UITextBorderStyleRoundedRect; // System look like
myCheckBox.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
myCheckBox.textAlignment = NSTextAlignmentLeft;
myCheckBox.delegate = self;
myCheckBox.text = @" -"; // Initial text of the checkbox... editable!
...

Then, add an event selector for reating in the touch event and calling 'responseSelected' event:

然后,添加一个事件选择器,用于在触摸事件中读取并调用 'responseSelected' 事件:

...
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(checkboxSelected)];
[myCheckBox addGestureRecognizer:tapGesture];
...

Finally respond to that selector

最后响应那个选择器

-(void) checkboxSelected
{
    if ([self isChecked])
    {
        // Uncheck the selection
        myCheckBox.text = @" -";
    }else{
       //Check the selection
       myCheckBox.text = @"\u2713";
    }
}

The function 'isChecked' only checks if the text is the @"\u2713" check mark. To prevent showing the keyboard when the text field is selected use the event of the UITextField 'textFieldShouldBeginEditing' and add the event selector to manage the selection:

函数 'isChecked' 仅检查文本是否为 @"\u2713" 复选标记。要防止在选择文本字段时显示键盘,请使用 UITextField 'textFieldShouldBeginEditing' 的事件并添加事件选择器来管理选择:

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    // Question selected form the checkbox
    [self checkboxSelected];

    // Hide both keyboard and blinking cursor.
    return NO;
}

回答by hiepnd

I like the idea of Adrian to use the characters rather than images. But I don't like the box, it need only the checkmark itself (@"\u2713"). I draw a box (a rounded box) programmatically and place an UILabel contains the checkmark inside it. This way of implementation makes it easy to use the custom view in any application without care about any dependent resource. You can also customize the color of the checkmark, the rounded box and the background with ease. Here's the complete code:

我喜欢 Adrian 使用角色而不是图像的想法。但我不喜欢这个框,它只需要复选标记本身(@"\u2713")。我以编程方式绘制一个框(一个圆角框),并在其中放置一个包含复选标记的 UILabel。这种实现方式可以轻松地在任何应用程序中使用自定义视图,而无需关心任何依赖资源。您还可以轻松自定义复选标记、圆角框和背景的颜色。这是完整的代码:

#import <UIKit/UIKit.h>

@class CheckBoxView;

@protocol CheckBoxViewDelegate
- (void) checkBoxValueChanged:(CheckBoxView *) cview;
@end

@interface CheckBoxView : UIView {
    UILabel *checkMark;
    bool isOn;
    UIColor *color;
    NSObject<CheckBoxViewDelegate> *delegate;
}
@property(readonly) bool isOn;
@property(assign) NSObject<CheckBoxViewDelegate> *delegate;

- (void) drawRoundedRect:(CGRect) rect inContext:(CGContextRef) context;
@end



#import "CheckBoxView.h"

#define SIZE 30.0
#define STROKE_WIDTH 2.0
#define ALPHA .6
#define RADIUS 5.0

@implementation CheckBoxView
@synthesize isOn, delegate;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, SIZE, SIZE)])) {
        // Initialization code
    }
    //UIColor *color = [UIColor blackColor];
    color = [[UIColor alloc] initWithWhite:.0 alpha:ALPHA];

    self.backgroundColor = [UIColor clearColor];
    checkMark = [[UILabel alloc] initWithFrame:CGRectMake(STROKE_WIDTH, STROKE_WIDTH, SIZE - 2 * STROKE_WIDTH, SIZE - 2*STROKE_WIDTH)];
    checkMark.font = [UIFont systemFontOfSize:25.];
    checkMark.text = @"\u2713";
    checkMark.backgroundColor = [UIColor clearColor];
    checkMark.textAlignment = UITextAlignmentCenter;
    //checkMark.textColor = [UIColor redColor];
    [self addSubview:checkMark];
    [checkMark setHidden:TRUE];
    isOn = FALSE;
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGRect _rect = CGRectMake(STROKE_WIDTH, STROKE_WIDTH, SIZE - 2 * STROKE_WIDTH, SIZE - 2*STROKE_WIDTH);
    [self drawRoundedRect:_rect inContext:UIGraphicsGetCurrentContext()];
    [checkMark setHidden:!isOn];
}


- (void)dealloc {
    [checkMark release];
    [color release];
    [super dealloc];
}

- (void) drawRoundedRect:(CGRect) rect inContext:(CGContextRef) context{
    CGContextBeginPath(context);
    CGContextSetLineWidth(context, STROKE_WIDTH);
    CGContextSetStrokeColorWithColor(context, [color CGColor]);
    CGContextMoveToPoint(context, CGRectGetMinX(rect) + RADIUS, CGRectGetMinY(rect));
    CGContextAddArc(context, CGRectGetMaxX(rect) - RADIUS, CGRectGetMinY(rect) + RADIUS, RADIUS, 3 * M_PI / 2, 0, 0);
    CGContextAddArc(context, CGRectGetMaxX(rect) - RADIUS, CGRectGetMaxY(rect) - RADIUS, RADIUS, 0, M_PI / 2, 0);
    CGContextAddArc(context, CGRectGetMinX(rect) + RADIUS, CGRectGetMaxY(rect) - RADIUS, RADIUS, M_PI / 2, M_PI, 0);
    CGContextAddArc(context, CGRectGetMinX(rect) + RADIUS, CGRectGetMinY(rect) + RADIUS, RADIUS, M_PI, 3 * M_PI / 2, 0);
    CGContextClosePath(context);
    CGContextStrokePath(context);
}

#pragma mark Touch
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint loc = [touch locationInView:self];
    if(CGRectContainsPoint(self.bounds, loc)){
        isOn = !isOn;
        //[self setNeedsDisplay];
        [checkMark setHidden:!isOn];
        if([delegate respondsToSelector:@selector(checkBoxValueChanged:)]){
            [delegate checkBoxValueChanged:self];
        }
    }
}

回答by hasan

Subclass UIButton, drop a button to view controller, select it and change class name to CheckBox in the identity inspector.

子类 UIButton,拖放一个按钮来查看控制器,选择它并在身份检查器中将类名更改为 CheckBox。

#import "CheckBox.h"

@implementation CheckBox

#define checked_icon @"checked_box_icon.png"
#define empty_icon @"empty_box_icon.png"

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self)
    {
        [self setImage:[UIImage imageNamed:empty_icon] forState:UIControlStateNormal];
        [self addTarget:self action:@selector(didTouchButton) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

- (void)didTouchButton {
    selected = !selected;
    if (selected)
        [self setImage:[UIImage imageNamed:checked_icon] forState:UIControlStateNormal];
    else
        [self setImage:[UIImage imageNamed:empty_icon] forState:UIControlStateNormal];
}

@end