I'm new to iOS and Swift. I've been making an android app for a couple years now. I'm learning Swift and making it for iOS devices.
I need help with alternative ways of Drop Down lists, since thats what i've using in android.
I've been researching UIPickerViews, UIPopovers with table views and more.
Twist is, i need multiple alternate of drop down lists in one ViewController.
Here is the view in my android app, that i want to look pretty similar in my iOS version.
I've been building survey applications for the last couple of months and this exact problem has come up several times. While a UIPickerView
mostly makes sense, it doesn't allow the user to see more than just a few options at a time and it doesn't scale well from iPhone 4s to a 6+ or iPad.
The first thing I would recommend is to create a button for your drop down menu. I've found that just about anything that looks remotely button like works well but making it look like a hyperlink or too inline with what's surrounding it doesn't work as well from a UX perspective.
Here's what the button I use looks like:
All that is is a. UIButton with a thin border around it with a corner radius of ~5.
As for the actual drop down, I've found popovers to generally be pretty effective. The easiest implementation for me was using UIAlertController
. (This is only available in iOS 8+ but should be fine if you're working in swift anyway.) With UIAlertController
you can have a very large number of options, a cancel button that's easily accessible, a title, a message all presented to the user in a very standard way. You can set the actions for each button when the controller is created so you don't have to work with delegates at all which keeps your code cleaner.
Here's what the alert controller for my previous example looks like. This is on an iPhone 5s in landscape which is the smallest layout possible but it scales up automatically as needed for any screen size and offers a similar experience for the user.
When the user has selected an answer, update the button text to match the new answer.
Instead of using UIAlertController
, I have created my own custom pop up with a table view but I've found myself basically recreating the alert controller just for the look of it and found it more difficult than it's worth to get the layout just right on every device. With that said, UIAlertController
offers almost nothing by way of customizing how it looks, which can be a deal breaker for some.
I feel like I should add that the reason I use a UIAlertController
instead of a UIPickerView
is intentional since it allows the user to see more options simultaneously and makes use of the available screen size on an iPad and larger iPhones. Additionally, the feedback after making a selection is instantaneous as the view disappears as soon as a selection is made, Cancel
is a standard action which allows the user to quickly not make a selection, and doesn't require the user to scroll if there are only a few options which means that a selection can be made in just one tap.
Here's the code I used to produce the button and corresponding UIAlertController
:
if (self.question.placeholderText) {
[self.answerButton setTitle:NSLocalizedString(self.question.placeholderText, @"") forState:UIControlStateNormal];
} else {
[self.answerButton setTitle:NSLocalizedString(@"Please Select One", nil) forState:UIControlStateNormal];
}
[self.answerButton setTitle:[self paddedString:self.answerButton.titleLabel.text] forState:UIControlStateNormal];
self.answerButton.titleLabel.textAlignment = NSTextAlignmentLeft;
self.answerButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
self.answerButton.titleLabel.font = [UIFont appFont];
[self.answerButton setTitleColor:[UIColor appColor] forState:UIControlStateNormal];
[self.answerButton addTarget:self action:@selector(longListLabelTapped) forControlEvents:UIControlEventTouchUpInside];
self.answerButton.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.0001f];
self.answerButton.titleLabel.layer.borderColor = [UIColor appColor].CGColor;
self.answerButton.titleLabel.layer.borderWidth = 1.0f;
self.answerButton.titleLabel.layer.cornerRadius = 5.0f;
- (NSString *)paddedString:(NSString *)input {
//This adds some space around the button title just to make it look better
return [NSString stringWithFormat:@" %@ ", input];
}
To create the UIAlertController
, you'll need an array of your options.
_optionsController = [UIAlertController
alertControllerWithTitle:self.question.longListTitle
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
}];
[_optionsController addAction:cancelAction];
for (NSString *optionName in self.question.possibleAnswers) {
UIAlertAction *action = [UIAlertAction actionWithTitle:optionName
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
// Do something with the selected answer
[self.answerButton setTitle:[self paddedString:optionName]
forState:UIControlStateNormal];
}];
[_optionsController addAction:action];
}