328 lines
9.5 KiB
Objective-C
328 lines
9.5 KiB
Objective-C
//
|
|
// DownPicker.h
|
|
// --------------------------------------------------------
|
|
// Lightweight DropDownList/ComboBox control for iOS
|
|
//
|
|
// by Darkseal, 2013-2015 - MIT License
|
|
//
|
|
// Website: http://www.ryadel.com/
|
|
// GitHub: http://www.ryadel.com/
|
|
//
|
|
|
|
|
|
#import "DownPicker.h"
|
|
|
|
|
|
@implementation DownPicker
|
|
{
|
|
NSString* _previousSelectedString;
|
|
}
|
|
|
|
-(id)initWithTextField:(UITextField *)tf
|
|
{
|
|
return [self initWithTextField:tf withData:nil];
|
|
}
|
|
|
|
-(id)initWithTextField:(UITextField *)tf withData:(NSArray*) data
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
self->textField = tf;
|
|
self->textField.delegate = self;
|
|
|
|
// set UI defaults
|
|
self->toolbarStyle = UIBarStyleDefault;
|
|
|
|
// set language defaults
|
|
self->placeholder = @"Bitte wählen";//@"...";//@"Tap to choose...";
|
|
self->placeholderWhileSelecting = @"Bitte wählen";//@"Pick an option...";
|
|
self->toolbarDoneButtonText = @"Fertig";//@"Done";
|
|
self->toolbarCancelButtonText = @"Abbrechen";//@"Cancel";
|
|
|
|
// hide the caret and its blinking
|
|
[[textField valueForKey:@"textInputTraits"]
|
|
setValue:[UIColor clearColor]
|
|
forKey:@"insertionPointColor"];
|
|
|
|
// set the placeholder
|
|
self->textField.placeholder = self->placeholder;
|
|
|
|
// setup the arrow image
|
|
UIImage* img = [UIImage imageNamed:@"downArrow.png"]; // non-CocoaPods
|
|
if (img == nil) img = [UIImage imageNamed:@"DownPicker.bundle/downArrow.png"]; // CocoaPods
|
|
if (img != nil) self->textField.rightView = [[UIImageView alloc] initWithImage:img];
|
|
self->textField.rightView.contentMode = UIViewContentModeScaleAspectFit;
|
|
self->textField.rightView.clipsToBounds = YES;
|
|
|
|
// show the arrow image by default
|
|
[self showArrowImage:YES];
|
|
|
|
// set the data array (if present)
|
|
if (data != nil) {
|
|
[self setData: data];
|
|
}
|
|
|
|
self.shouldDisplayCancelButton = YES;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
|
|
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
|
{
|
|
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
|
}
|
|
|
|
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
|
|
{
|
|
self->textField.text = [dataArray objectAtIndex:row];
|
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
}
|
|
|
|
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
|
|
{
|
|
return [dataArray count];
|
|
}
|
|
|
|
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
|
|
{
|
|
return [dataArray objectAtIndex:row];
|
|
}
|
|
|
|
-(void)doneClicked:(id) sender
|
|
{
|
|
//hides the pickerView
|
|
[textField resignFirstResponder];
|
|
|
|
if (self->textField.text.length == 0 || ![self->dataArray containsObject:self->textField.text]) {
|
|
// self->textField.text = [dataArray objectAtIndex:0];
|
|
[self setValueAtIndex:-1];
|
|
self->textField.placeholder = self->placeholder;
|
|
}
|
|
/*
|
|
else {
|
|
if (![self->textField.text isEqualToString:_previousSelectedString]) {
|
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
}
|
|
}
|
|
*/
|
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
}
|
|
|
|
-(void)cancelClicked:(id)sender
|
|
{
|
|
[textField resignFirstResponder]; //hides the pickerView
|
|
if (_previousSelectedString.length == 0 || ![self->dataArray containsObject:_previousSelectedString]) {
|
|
self->textField.placeholder = self->placeholder;
|
|
}
|
|
self->textField.text = _previousSelectedString;
|
|
}
|
|
|
|
|
|
- (IBAction)showPicker:(id)sender
|
|
{
|
|
_previousSelectedString = self->textField.text;
|
|
|
|
pickerView = [[UIPickerView alloc] init];
|
|
pickerView.showsSelectionIndicator = YES;
|
|
pickerView.dataSource = self;
|
|
pickerView.delegate = self;
|
|
|
|
//If the text field is empty show the place holder otherwise show the last selected option
|
|
if (self->textField.text.length == 0 || ![self->dataArray containsObject:self->textField.text])
|
|
{
|
|
if (self->placeholderWhileSelecting) {
|
|
self->textField.placeholder = self->placeholderWhileSelecting;
|
|
}
|
|
// 0.1.31 patch: auto-select first item: it basically makes placeholderWhileSelecting useless, but
|
|
// it solves the "first item cannot be selected" bug due to how the pickerView works.
|
|
[self setSelectedIndex:0];
|
|
}
|
|
else
|
|
{
|
|
if ([self->dataArray containsObject:self->textField.text]) {
|
|
[self->pickerView selectRow:[self->dataArray indexOfObject:self->textField.text] inComponent:0 animated:YES];
|
|
}
|
|
}
|
|
|
|
UIToolbar* toolbar = [[UIToolbar alloc] init];
|
|
toolbar.barStyle = self->toolbarStyle;
|
|
[toolbar sizeToFit];
|
|
|
|
//space between buttons
|
|
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
|
|
target:nil
|
|
action:nil];
|
|
|
|
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc]
|
|
initWithTitle:self->toolbarDoneButtonText
|
|
style:UIBarButtonItemStyleDone
|
|
target:self
|
|
action:@selector(doneClicked:)];
|
|
|
|
if (self.shouldDisplayCancelButton) {
|
|
UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
|
|
initWithTitle:self->toolbarCancelButtonText
|
|
style:UIBarButtonItemStylePlain
|
|
target:self
|
|
action:@selector(cancelClicked:)];
|
|
|
|
[toolbar setItems:[NSArray arrayWithObjects:cancelButton, flexibleSpace, doneButton, nil]];
|
|
} else {
|
|
[toolbar setItems:[NSArray arrayWithObjects:flexibleSpace, doneButton, nil]];
|
|
}
|
|
|
|
|
|
//custom input view
|
|
textField.inputView = pickerView;
|
|
textField.inputAccessoryView = toolbar;
|
|
}
|
|
|
|
- (BOOL)textFieldShouldBeginEditing:(UITextField *)aTextField
|
|
{
|
|
if ([self->dataArray count] > 0) {
|
|
[self showPicker:aTextField];
|
|
return YES;
|
|
}
|
|
return NO;
|
|
}
|
|
|
|
- (void)textFieldDidBeginEditing:(UITextField *)textField
|
|
{
|
|
[self sendActionsForControlEvents:UIControlEventEditingDidBegin];
|
|
}
|
|
|
|
- (void)textFieldDidEndEditing:(UITextField *)aTextField {
|
|
// [self doneClicked:aTextField];
|
|
aTextField.userInteractionEnabled = YES;
|
|
[self sendActionsForControlEvents:UIControlEventEditingDidEnd];
|
|
}
|
|
|
|
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
-(void) setData:(NSArray*) data
|
|
{
|
|
dataArray = data;
|
|
}
|
|
|
|
-(void) showArrowImage:(BOOL)b
|
|
{
|
|
if (b == YES) {
|
|
// set the DownPicker arrow to the right (you can replace it with any 32x24 px transparent image: changing size might give different results)
|
|
self->textField.rightViewMode = UITextFieldViewModeAlways;
|
|
}
|
|
else {
|
|
self->textField.rightViewMode = UITextFieldViewModeNever;
|
|
}
|
|
}
|
|
|
|
-(void) setArrowImage:(UIImage*)image
|
|
{
|
|
[(UIImageView*)self->textField.rightView setImage:image];
|
|
}
|
|
|
|
-(void) setPlaceholder:(NSString*)str
|
|
{
|
|
self->placeholder = str;
|
|
self->textField.placeholder = self->placeholder;
|
|
}
|
|
|
|
-(void) setPlaceholderWhileSelecting:(NSString*)str
|
|
{
|
|
self->placeholderWhileSelecting = str;
|
|
}
|
|
|
|
-(void) setAttributedPlaceholder:(NSAttributedString *)attributedString
|
|
{
|
|
self->textField.attributedPlaceholder = attributedString;
|
|
}
|
|
|
|
-(void) setToolbarDoneButtonText:(NSString*)str
|
|
{
|
|
self->toolbarDoneButtonText = str;
|
|
}
|
|
|
|
-(void) setToolbarCancelButtonText:(NSString*)str
|
|
{
|
|
self->toolbarCancelButtonText = str;
|
|
}
|
|
|
|
-(void) setToolbarStyle:(UIBarStyle)style;
|
|
{
|
|
self->toolbarStyle = style;
|
|
}
|
|
|
|
-(UIPickerView*) getPickerView
|
|
{
|
|
return self->pickerView;
|
|
}
|
|
|
|
-(UITextField*) getTextField
|
|
{
|
|
return self->textField;
|
|
}
|
|
|
|
-(NSString*) getValueAtIndex:(NSInteger)index
|
|
{
|
|
return (self->dataArray.count > index) ? [self->dataArray objectAtIndex:index] : nil;
|
|
}
|
|
|
|
-(void) setValueAtIndex:(NSInteger)index
|
|
{
|
|
if (index >= 0) [self pickerView:nil didSelectRow:index inComponent:0];
|
|
else [self setText:nil];
|
|
}
|
|
|
|
/**
|
|
Getter for text property.
|
|
@return
|
|
The value of the selected item or NIL NIL if nothing has been selected yet.
|
|
*/
|
|
- (NSString*) text {
|
|
return self->textField.text;
|
|
}
|
|
|
|
/**
|
|
Setter for text property.
|
|
@param txt
|
|
The value of the item to select or NIL to clear selection.
|
|
*/
|
|
- (void) setText:(NSString*)txt {
|
|
if (txt != nil) {
|
|
NSInteger index = [self->dataArray indexOfObject:txt];
|
|
if (index != NSNotFound) [self setValueAtIndex:index];
|
|
}
|
|
else {
|
|
self->textField.text = txt;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Getter for selectedIndex property.
|
|
@return
|
|
The zero-based index of the selected item or -1 if nothing has been selected yet.
|
|
*/
|
|
- (NSInteger)selectedIndex {
|
|
NSInteger index = [self->dataArray indexOfObject:self->textField.text];
|
|
return (index != NSNotFound) ? (NSInteger)index : -1;
|
|
}
|
|
|
|
/**
|
|
Setter for selectedIndex property.
|
|
@param index
|
|
Sets the zero-based index of the selected item using the setValueAtIndex method: -1 can be used to clear selection.
|
|
*/
|
|
- (void)setSelectedIndex:(NSInteger)index {
|
|
[self setValueAtIndex:(NSInteger)index];
|
|
}
|
|
|
|
@end
|