36 Stimmen

Kontrollkästchen in iOS-Anwendung

Ich muss Kontrollkästchen Steuerelemente zu meinem Formular hinzufügen. Ich weiß, dass es kein solches Steuerelement in iOS SDK gibt. Wie könnte ich das tun?

6voto

slobodans Punkte 841

Hier ist meine Version der Checkbox für das iPhone.

Es ist eine einzelne Klasse, die UIButton erweitert. Es ist einfach, so werde ich es hier einfügen.

Inhalt der Datei CheckBoxButton.h

#import <UIKit/UIKit.h>

@interface CheckBoxButton : UIButton

@property(nonatomic,assign)IBInspectable BOOL isChecked;

@end

CheckBoxButton.m Datei Inhalt

#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

Sie können Bilder für checked/unchecked sowie die isChecked-Eigenschaft im Attributinspektor von Visual Studio festlegen.

enter image description here

Um CheckBoxButton in Storyboard oder xib hinzuzufügen, fügen Sie einfach UIButton und benutzerdefinierte Klasse wie auf dem nächsten Bild.

enter image description here

Die Schaltfläche sendet das Ereignis UIControlEventValueChanged jedes Mal, wenn der Status von isChecked geändert wird.

0 Stimmen

Großartige Antwort, weil es gut mit Storyboard funktioniert, so dass es viel Positionierungscode vermeidet (und nur sauberen Code hinterlässt) und ich in der Lage bin, benutzerdefinierte Bilder zu verwenden. Auch schön erklärt, so dass für einen Neuling zu iOS wie mich dies einfach zu implementieren ist. Jetzt um herauszufinden, warum meine Bilder in blau wie der Text auf der Schaltfläche erscheinen...

0 Stimmen

Ok, um zu vermeiden, dass Ihr Bild unter iOS 7+ blau eingefärbt wird, setzen Sie die Eigenschaft Typ auf Benutzerdefiniert, wie Sie im ersten Screenshot von @slobodans' Antwort sehen können, aber ich habe die Antwort von hier: stackoverflow.com/a/21313338/1479962

0 Stimmen

Beste Antwort! Die Schaltfläche IBDesignable zu machen ist ein toller Bonus!

4voto

Brayden Punkte 1795

Everyones Code hier ist sehr lang, etwas unordentlich, und könnte viel einfacher gemacht werden. Ich habe ein Projekt auf GitHub, dass Unterklasse UIControl, die Sie herunterladen und überprüfen können, und gibt Ihnen eine fast native Checkbox UI-Element:

https://github.com/Brayden/UICheckbox

1voto

hiepnd Punkte 821

Mir gefällt die Idee von Adrian, die Zeichen anstelle von Bildern zu verwenden. Aber ich mag die Box nicht, es braucht nur das Häkchen selbst (@" \u2713 "). Ich zeichne programmatisch eine Box (eine abgerundete Box) und platziere darin ein UILabel, das das Häkchen enthält. Diese Art der Implementierung macht es einfach, die benutzerdefinierte Ansicht in jeder Anwendung zu verwenden, ohne sich um abhängige Ressourcen kümmern zu müssen. Sie können auch die Farbe des Häkchens, des abgerundeten Kastens und des Hintergrunds ganz einfach anpassen. Hier ist der vollständige Code:

#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];
        }
    }
}

0 Stimmen

Ich habe diesen Code ausprobiert. Es funktioniert nicht.. Ich habe versucht, ihn zu reparieren, aber ich konnte das Problem nicht finden. Kannst du das Problem beheben?

0 Stimmen

Gerade überprüft den Code mit Xcode 4.2 iOS 5.0 mit keinen Fehler. Haben Sie es in einem leeren Projekt versucht?

0 Stimmen

Ja. Es funktioniert immer noch nicht. Ich habe eine UIView in xib hinzugefügt und die Klasse dieser Ansicht in CheckBoxView geändert. Ist das nicht der Weg, wie es funktionieren soll?

1voto

Dilip Punkte 8979

In der Datei .h

#import <UIKit/UIKit.h>

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

Und .m-Datei

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

Das wird den Zweck erfüllen...

1voto

mTouch Punkte 11

Ich habe es mit einem UITextField, um zu vermeiden, Zeichnung etwas seltsam, aber ich mochte setzen innerhalb als Text das Häkchen Unicode (Unicode-Zeichen 'CHECK MARK' (U+2713)) für die NSString: @" \u2713 ".

Auf diese Weise, in meiner .h-Datei (Implementierung des Protokolls für das UITextField 'UITextFieldDelegate'):

UITextField * myCheckBox;

In meiner viewDidLoad oder die Funktion, um die UI vorzubereiten:

...
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!
...

Fügen Sie dann einen Ereignis-Selektor hinzu, um das Touch-Ereignis zu aktivieren und das Ereignis "responseSelected" aufzurufen:

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

Antworten Sie schließlich auf diesen Selektor

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

Die Funktion 'isChecked' prüft nur, ob der Text das @" ist. \u2713 "Häkchen setzen. Um zu verhindern, dass die Tastatur angezeigt wird, wenn das Textfeld ausgewählt ist, verwenden Sie das Ereignis des UITextFields 'textFieldShouldBeginEditing' und fügen Sie den Ereignisselektor hinzu, um die Auswahl zu verwalten:

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

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

0 Stimmen

Tolle Antwort @mTouch - das Einzige, was ich tun musste, abgesehen von der Einstellung der UITextFieldDelegate im View-Controller wurde das bool isChecked definiert als BOOL isChecked; . Dies bedeutete, dass Ihr if ([self isChecked]) wurde if (isChecked) stattdessen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X