IOS, Objective-c

Tips to create dropdown list in IOS

Tips to create dropdown list in IOS

The Native iOS controls do not specifically have a native control for a dropdown. What we want is a control that behaves like a dropdown that uses a UIPickerControl .
Native iOS dropdown
To create the dropdown arrow we create a UIView for the right hand side of the UITextField. You could use an UIImageView but I’ve chosen to subclass UIView and draw my own arrow in drawInRect::
////rawRCDropdownArrowView.h

#import <UIKit/UIKit.h>

// This view is used to draw an arrow for the rightView within the UITextField

@interface RCDropdownArrowView : UIView

+(RCDropdownArrowView*) default;

@end

////rawRCDropdownArrowView.m

#import “RCDropdownArrowView.h”

@implementation RCDropdownArrowView

+(RCDropdownArrowView*) default {

RCDropdownArrowView* view = [[RCDropdownArrowView alloc] initWithFrame:CGRectMake(0, 0, 31, 28)];
view.backgroundColor = [UIColor whiteColor];
return view;

}

– (void)drawRect:(CGRect)rect {

//// Color Declarations
UIColor* strokeColor = [UIColor colorWithRed: 0.827 green: 0.827 blue: 0.827 alpha: 1];

//// Frames
CGRect frame = self.bounds;

//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 24.82, CGRectGetMinY(frame) + 8.08)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 25.98, CGRectGetMinY(frame) + 9.25)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 17.01, CGRectGetMinY(frame) + 18.22)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 17.01, CGRectGetMinY(frame) + 18.22)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 15.85, CGRectGetMinY(frame) + 19.38)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 15.85, CGRectGetMinY(frame) + 19.38)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 15.85, CGRectGetMinY(frame) + 19.38)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 14.68, CGRectGetMinY(frame) + 18.22)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 14.68, CGRectGetMinY(frame) + 18.22)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 5.71, CGRectGetMinY(frame) + 9.25)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 6.88, CGRectGetMinY(frame) + 8.08)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 15.85, CGRectGetMinY(frame) + 17.05)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 24.82, CGRectGetMinY(frame) + 8.08)];
[bezierPath closePath];
bezierPath.miterLimit = 4;

bezierPath.usesEvenOddFillRule = YES;

[strokeColor setFill];
[bezierPath fill];

//// Bezier 2 Drawing
UIBezierPath* bezier2Path = [UIBezierPath bezierPath];
[bezier2Path moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.5, CGRectGetMinY(frame) + 28)];
[bezier2Path addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.5, CGRectGetMinY(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.5, CGRectGetMinY(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.5, CGRectGetMinY(frame))];
[strokeColor setStroke];
bezier2Path.lineWidth = 1;
[bezier2Path stroke];

//// Bezier 3 Drawing
UIBezierPath* bezier3Path = [UIBezierPath bezierPath];
[bezier3Path moveToPoint: CGPointMake(CGRectGetMinX(frame) + 31, CGRectGetMinY(frame) + 28)];
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 31, CGRectGetMinY(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 31, CGRectGetMinY(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 31, CGRectGetMinY(frame))];
[strokeColor setStroke];
bezier3Path.lineWidth = 1;
[bezier3Path stroke];

}

 

////rawRCDropdown.h
Subclass UITextField
By subclass-ing UITextField we can easily add the UIPickerControl as the inputView as well as the arrow view as the rightView.

#import <UIKit/UIKit.h>

@interface RCDropdown : UITextField

@property (nonatomic) id<UIPickerViewDelegate> pickerDelegate;
@property (nonatomic) id<UIPickerViewDataSource> pickerDataSource;

@end

////rawRCDropdown.m

#import “RCDropdown.h”
#import “RCDropdownArrowView.h”

@implementation RCDropdown {
UIPickerView* _pickerView;
}

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

// The leftView is optional, but I like a little padding.
// You may also want to subclass this into your own UITextField
self.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
self.leftViewMode = UITextFieldViewModeAlways;

self.layer.borderColor = [[UIColor colorWithRed: 0.827 green: 0.827 blue: 0.827 alpha: 1] CGColor];;
self.layer.borderWidth= 1.0f;

self.rightView = [RCDropdownArrowView default];
self.rightViewMode = UITextFieldViewModeAlways;

_pickerView = [[UIPickerView alloc] initWithFrame:CGRectZero];
_pickerView.showsSelectionIndicator = YES;
self.inputView = _pickerView;
}

return self;
}

-(void)setTag:(NSInteger)tag {
[super setTag:tag];
_pickerView.tag = tag;
}

-(void)setPickerDelegate:(id<UIPickerViewDelegate>)pickerDelegate {
_pickerView.delegate = pickerDelegate;
}

-(void)setPickerDataSource:(id<UIPickerViewDataSource>)pickerDataSource {
_pickerView.dataSource = pickerDataSource;
}

@end

/////rawRCRegisterViewController.m

Usage Within interface builder I can easily add UITextField controls to my view and change it’s class to RCDropdown. All that is left to do is setup the data source for the picker control:

#import “RCRegisterViewController.h”

@interface RCRegisterViewController () {
NSArray* _titleSelectionData;
}

– (void)viewDidLoad {

_titleSelectionData = [NSArray arrayWithObjects:@””, @”Mr”, @”Ms”, @”Mrs”, @”Miss”, @”Dr”, nil];

_titleTextField.pickerDelegate = self;
_titleTextField.pickerDataSource = self;
_titleTextField.tag = 1;
}

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if(pickerView.tag == 1) _titleTextField.text = [_titleSelectionData objectAtIndex:row];
}

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return _titleSelectionData.count;
}

-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [_titleSelectionData objectAtIndex:row];
}