36

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

4

15 回答 15

32

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

  1. 向 Interface Builder 添加一个新的标签对象。
  2. 在 Xcode 中创建一个 IBOutlet 属性并将其连接到它。在下面的代码中,我将其称为“fullPaid”,因为我想知道是否有人已经全额支付了一笔钱。
  3. 添加下面的2个功能。“touchesBegan”函数检查您是否触摸了“fullyPaid”标签对象内的某个位置,如果是,它调用“togglePaidStatus”函数。'togglePaidStatus' 函数设置两个字符串,它们的 unicode 字符分别代表一个空框 (\u2610) 和一个复选框 (\u2611)。然后它比较“fullyPaid”对象中当前的内容,并将其与另一个字符串切换。

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

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

-(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];
}
于 2010-04-10T21:23:12.713 回答
25

通常,您会将 UISwitch 用于类似复选框的功能。

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

于 2009-03-16T12:12:56.393 回答
14

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

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

于 2009-03-16T12:33:15.473 回答
9

延伸到Adrean 的想法,我用一种非常简单的方法实现了这一点。我的想法是根据其状态
更改按钮(比如说)文本,然后在其更改按钮的状态。 下面是我如何做到这一点的代码:checkBtnIBAction

- (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
    }
}
于 2014-03-19T04:17:55.977 回答
6

这是我的 iPhone 复选框版本。

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

CheckBoxButton.h 文件内容

#import <UIKit/UIKit.h>

@interface CheckBoxButton : UIButton

@property(nonatomic,assign)IBInspectable BOOL isChecked;

@end

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

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

在此处输入图像描述

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

在此处输入图像描述

每次更改 isChecked 状态时,按钮都会发送 UIControlEventValueChanged 事件。

于 2014-12-31T13:44:30.607 回答
6

我想以编程方式进行此操作,同时也解决命中区域实在太小的问题。这改编自各种来源,包括 Mike 和 Mike 的评论者 Agha。

在你的标题中

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

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

-(void)toggleButton:(id)sender;

在你的实施中

// 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];

并将此方法也放入:

- (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];

}
于 2010-05-21T16:46:29.317 回答
4

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

https://github.com/Brayden/UICheckbox

于 2012-07-18T07:03:53.907 回答
1

我喜欢 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];
        }
    }
}
于 2010-07-23T09:41:11.697 回答
1

在 .h 文件中

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    BOOL isChecked;
    UIImageView * checkBoxIV;
}
@end

和 .m 文件

- (void)viewDidLoad
{
    [super viewDidLoad];
    isChecked = NO;

    //change this property according to your need
    checkBoxIV = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 15, 15)]; 
    checkBoxIV.image =[UIImage imageNamed:@"checkbox_unchecked.png"]; 

    checkBoxIV.userInteractionEnabled = YES;
    UITapGestureRecognizer *checkBoxIVTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handlecheckBoxIVTapGestureTap:)];
    checkBoxIVTapGesture.numberOfTapsRequired = 1;
    [checkBoxIV addGestureRecognizer:checkBoxIVTapGesture];
}

- (void)handlecheckBoxIVTapGestureTap:(UITapGestureRecognizer *)recognizer {
    if (isChecked) {
        isChecked = NO;
        checkBoxIV.image =[UIImage imageNamed:@"checkbox_unchecked.png"];
    }else{
        isChecked = YES;
        checkBoxIV.image =[UIImage imageNamed:@"checkbox_checked.png"];   
    }
}

这会成功的......

于 2013-06-14T10:12:42.290 回答
1

我使用 UITextField 来避免绘制任何奇怪的东西,但我喜欢将 NSString 的刻度 unicode (Unicode Character 'CHECK MARK' (U+2713)) 作为文本放入内部:@"\u2713"。

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

UITextField * myCheckBox;

在我的 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!
...

然后,在触摸事件中添加一个事件选择器,并调用“responseSelected”事件:

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

最后响应那个选择器

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

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

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

    // Hide both keyboard and blinking cursor.
    return NO;
}
于 2014-10-07T11:13:05.453 回答
1

子类 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
于 2015-05-13T11:59:15.443 回答
1

我最近做了一个。从 GitHub 免费获取。看看是否会有所帮助。效果就像

在此处输入图像描述

于 2019-04-01T20:36:35.610 回答
0

用户 Aruna Lakmal;仅供参考,当您将此代码添加到 IB 时,正如您所描述的那样,不会调用 initWithFrame,而是调用 initWithCoder。实施 initWithCoder ,它将按照您的描述工作。

于 2013-01-20T03:15:07.690 回答
0

使用 SF 符号的简单 UIButton 子类可以解决问题

class CheckBoxButton: UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
    }

    func setup() {
        setImage(UIImage(systemName: "square.fill"), for: .normal)
        setImage(UIImage(systemName: "checkmark.square.fill"), for: .selected)
    }
}

故事板

如果您使用故事板,请确保按钮类型设置为custom如下图所示

按钮类型自定义


用法

您所要做的就是isSelected在动作/选择器方法中切换变量

@objc func toggle(_ sender: UIButton) {
    sender.isSelected.toggle()
}


演示

复选框演示

于 2021-09-30T12:37:46.613 回答
0

一个简单的UIButton子类将能够表现得像 Android 中的复选框。

import UIKit

class CheckedUIButton: UIButton {
    var checked: Bool = false {
        didSet {
            if checked {
                setImage(UIImage(systemName: "checkmark.circle"), for: .normal)
            } else {
                setImage(UIImage(systemName: "circle"), for: .normal)
            }
        }
    }
    
    //initWithFrame to init view from code
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        commonInit()
    }
     
    //initWithCode to init view from xib or storyboard
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        commonInit()
    }
    
    private func commonInit() {
        addTarget(self, action: #selector(self.checkedTapped), for: .touchUpInside)
    }

    @objc
    private func checkedTapped() {
        self.checked.toggle()
    }
}

输出

在此处输入图像描述

(未选中状态)


在此处输入图像描述

(检查状态)

于 2021-09-24T06:46:28.390 回答