Custom Look & Feel of UIPickerView; - iphone

I want a UIPickerView in following design;
http://dl.dropbox.com/u/53051470/Screen%20shot%202012-04-18%20at%2012.02.36%20PM.png
(sorry as a new user, can't paste image here)
I read other questions on same topic too, and try to implement
pickerView:viewForRow:forComponent:reusingView:
method as well, but din't get the actual results;
Requirements are like selected value should display in green bar with checkmark image, and in white color; Moreover when user will start scrolling the picker, any value that enters inside green bar should turns into green color, and any value that leaves the green bar ares should turns into black;
Any suggestion?
Kind regards;

you should use the method
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
and decide which row is highlight
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
// i use a UILabel instead of your **custom UIView** , you may add a tick in you custom view
UILabel *testRow = view?(UILabel *)view:[[[UILabel alloc] initWithFrame:CGRectMake(0,0, 140, 40)] autorelease];
testRow.font = [UIFont fontWithName:[testArray objectAtIndex:row] size:16];
testRow.text = [fontsArray objectAtIndex:row];
testRow.backgroundColor = [UIColor clearColor];
if ( row == selectedRow )
{
testRow.backgroundColor = [UIColor greenColor];
}
return testRow;
}
don't forget set the showsSelectionIndicator to NO
pickView.showsSelectionIndicator = NO;

UIPickerView multiple-selection-behavior without adding other views in front of the pickerview,using: https://github.com/alexleutgoeb/ALPickerView
Improvements are highly appreciated!

Related

UIPickerView interactive area for tapping cut off in iOS 7

When I make a long picker with multiple components, only the components near the center react to the tap-to-select feature.
For example, if you want to pick the very next row under a selected row, you should be able to just tap it to make it animate up into the selection area. This feature still exists with iOS 7, but the area with in the UIPicker that will actually accept the tap is a very small window, no larger than 200px.
Is there any way to expand this tap-able area to include the entire UIPickerView, so any time you tap a row it becomes the selection?
EDIT here is the code, it's pretty standard...
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(#"picked %i %i" , component , row);
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 4;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 15;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return #"";
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *pickersLabel;
pickersLabel =[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, view.frame.size.width , view.frame.size.height )];
pickersLabel.text = [NSString stringWithFormat:#"thing %i" , row ];
pickersLabel.backgroundColor = [UIColor clearColor];
pickersLabel.backgroundColor = [UIColor colorWithRed:1/255.0 green:1/255.0 blue:2/255.0 alpha:0.05];
pickersLabel.opaque = NO;
[view addSubview:pickersLabel];
return pickersLabel;
}
I've had massive problems with UIPickerViews that were in .xibs instead of Storyboards in iOS 7. I'm not sure if there's some optimization going on behind the scenes in the Storyboard or if this is a straight-up bug, but it's worth a shot - I'm using a picker view that's coming from a Storyboard right now and I am able to tap on non-selected rows and they scroll up and become selected.

Custom iOS UIDatepicker using UIAppearance

UNIQLO's new alarm app has a custom UIDatePicker:
And I want to create my own custom UIDatePicker.
I tried to change the appearance of the DatePicker, but looking for UI_APPEARANCE_SELECTOR in the UIDatePicker returns nothing.
Meaning that its not possible to change any values, as per the docs:
To support appearance customization, a class must conform to the UIAppearanceContainer protocol and relevant accessor methods must be marked with UI_APPEARANCE_SELECTOR.
How can change my UIDatePicker's appearance?
The API does not provide a way to do this.
You can make a pretty convincing replica yourself using a UIPickerView rather than using UIDatePicker.
As the UIDatePicker or UIPickerView don't have the UI_APPEARANCE_SELECTOR and even you can't change UIDatePicker contents' appearance as its UIControl and not having any delegate so it has its native appearance whereas in case of UIPickerView you can change its contents' appearance similar as in UITableView.
#pragma mark -
#pragma mark UIPicker Delegate & DataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 100;
}
//- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent: (NSInteger)component {
// return [NSString stringWithFormat:#"%d",row];
//}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *label= [[[UILabel alloc] initWithFrame:CGRectMake(30.0, 0.0, 50.0, 50.0)] autorelease];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[UIColor blueColor]];
[label setFont:[UIFont boldSystemFontOfSize:40.0]];
[label setText:[NSString stringWithFormat:#"%d",row]];
return label;
}
Check this out.
add this method in your implementation file
-(UIView *)pickerViews{
return ([datePicker.subviews objectAtIndex:0]);
}
-(void)viewDidLoad{
[super viewDidLoad];
[[self pickerViews].subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"%# --- > %i",obj, idx);
}];
}
when you run your app it will display all the subviews of the datePicker on your console, just choose any index and modify them one by one
modify the viewDidLoad and insert this code
UIView *background = (UIView *)[[self pickerViews].subviews objectAtIndex:0];
background.backgroundColor = [UIColor clearColor];
UIView *wheel2 = (UIView *)[[self pickerViews].subviews objectAtIndex:4];
wheel2.backgroundColor = [UIColor redColor];
UIView *wheel3 = (UIView *)[[self pickerViews].subviews objectAtIndex:11];
wheel3.backgroundColor = [UIColor redColor];
In this case i change the background color of index "0", "4", "11"
With iOS 5 the UIAppearance protocol was introduced, which lets you customize several UI elements. UIDatePicker happens to conform this protocol, so that is probably the easiest way to do this. That is, if you're willing to support only iOS 5 users. Matthew's option would probably the next best thing, which should also work with older iOS versions.
It appears to be quite difficult to change the way a UIDatePicker appears.
The example you provided, in my opinion, is a sophisticated customization of a simple UIPickerView with two columns and probably a simulated infinite scroll (as Apple does in the date picker, and it's quite simple to realize).
You can change little of the UIDatePicker through the UIAppearance proxy, as seen in this example:
UIDatePicker *picker = [UIDatePicker appearance];
picker.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.3];
UIView *view;
view = [UIView appearanceWhenContainedIn:[UITableView class], [UIDatePicker class], nil];
view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
UILabel *label = [UILabel appearanceWhenContainedIn:[UITableView class], [UIDatePicker class], nil];
label.font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
label.textColor = [UIColor blueColor];
Using this piece of code at the start of the application (just try it) you can change the aspect of only a couple of the main components of the date picker.
Labels are impossible to customize (and this test code proves it); apparently they are changed in aspect every time you rotate a column, since they are put inside a custom UITableView controller.
To fully change these appearances you should probably work with private APIs from Apple, that will eventually result in your app being rejected.
If you just need a custom hour-minute picker (as shown in your screenshot), the full customization of appearance is reachable only extending the UIPickerView class or assigning an appropriate delegate to a UIPickerView instance.
Through the
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
method on the delegate you can make the single element of the picker view appear the way you want. Then you will have to appropriately handle the data source to make the two components of the picker virtually infinite.
You can implement one yourself using two UIScrollViews, one for hours and one for minutes. You would just need to figure out the contentOffset of each scrollview when it has stopped moving, which off the top of my head would look like this:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (!decelerate) {
// get the offset here
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// also get the offset here
}
Take the value of the content offset and translate it into the hour value and minute value, probably by dividing the y position of the content offset by the 24 or 60 respectively. You will need to make the custom artwork yourself.
To change date picker color:
[datePickerView setValue:self.pickerLabelColor forKey:#"textColor"];
And to change font the only way I know is:
Create category UIFont+System and place this code inside
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize
{
return [UIFont fontWithName:fontName size:fontSize];
}
#pragma clang diagnostic pop
This will set as well fonts in another places in your app (replacing system font by your font).
You should go through the UICatalog by Apple. It has all the methods in which a UIDatePicker can be used including the custom date picker method . Study this link developer.apple.com/library/ios/samplecode/UICatalog/ . Also they have implemented a standard switch and the navigation bar which is given in the latter.
A combination of 2 UITableViews is the way to go.
UITableView is a subview of UIScrollView, so it handles the following event
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
}
and on getting the position, just scroll the table to the center using the following method
[myTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
Hope this helps.

How to change the font size in a UIPickerView? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
UIPickerView Font…
I'm really stuck on this one problem in my application. I searched everywhere to no avail. How can I change the font size in a UIPickerView?
Implement viewForRow:forComponent: method in picker's data delegate, create UILabel instance in it with the font (and all other properties) you need, e.g.:
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
UILabel* tView = (UILabel*)view;
if (!tView){
tView = [[UILabel alloc] init];
// Setup label properties - frame, font, colors etc
...
}
// Fill the label text here
...
return tView;
}
PickerView.transform = CGAffineTransformMakeScale(0.4, 0.4);

Changing style of UIPickerView

How can I change the style of a UIPickerview. I want to change its white background to green color and its black frame to red color.
Anyone please help. I am a beginner.
As far as I know you can't actually change the frame's color, but you can create an image with a transparent area in the middle and add that on top of the frame like so:
[picker addSubview:image];
As for the background color, you can create your own custom views for each row by implementing the UIPickerViewDelegate method:
- (UIView *)pickerView:(UIPickerView *)pickerView
viewForRow:(NSInteger)row
forComponent:(NSInteger)component
reusingView:(UIView *)aView;
You could then set the background color of the view you return via
[myView setBackgroundColor:[UIColor yellowColor]];
However this only affects the rows with data. I don't think you can currently set the background color of the component itself which is a shame.
I personally prefer this:
[self.picker setBackgroundColor:[UIColor greenColor]];
self.picker.layer.borderColor = [UIColor whiteColor].CGColor;
self.picker.layer.borderWidth = 4;

How to change UIPicker Color ? iPhone

I have observed that UIPicker always remains in black color,
Is there any way to change the color of UIPicker & it's Selection Indicator?
Thanks for helping me.
I assume all you want to change is the color of the border of the picker, not of the region in the center with which the user interacts. In this case, do the following:
Create 4 "cover" UIViews and add them directly to the UIPicker, as in:
[picker addSubview: coverView];
Position these views over the top, bottom, left and right sides of the picker border. (You will need to experiment with sizes.) Set the backgroundColor of the coverViews to the color you want, and adjust the alpha to get the gradient shading from the picker. Again, this may take a bit of experimentation.
The alternative would be to create one big coverView that covers the entire picker, and override the - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event method so that your cover view did not intercept the touches meant for the picker.
You can create your own custom pickers, check the UICatalog sample project at apples site, they show how to make a custom picker, it might help you https://developer.apple.com/iphone/library/samplecode/UICatalog/
Create a single overlay image as Amagrammer suggested but instead of adding it to your view as an image, add it as a button. Then disable the interaction on the button and the picker will receive the touch events without the need to intercept or override anything.
You can do this by adding 5 ImageView also. First one is of size "Selection Indicator" and put it exactly over "Selection Indicator". Now change that imageView's alpha to 0.2 or whatever you want and also add image/color as per your choice. Now, you will see your custom "Selection Indicator". Also, same thing you can do for borders. Add each imageView to four sides of pickerview and make it's size equal to border size. Now fill the images/color you want in that ImageView.
This is the best solution I have found
http://www.inexika.com/blog/Customizing-UIPickerView-UIDatePicker
You'll need to create a new UIView with a UIImageView inside it and then set that as the Accessory for the cell. So you'll need to create a image just like the default accessory but in the color you want.
UIView* accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 24, 50)];
UIImageView* accessoryViewImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"NEWIMAGE.png"]];
accessoryViewImage.center = CGPointMake(12, 25);
[accessoryView addSubview:accessoryViewImage];
[cell setAccessoryView:accessoryView];
[accessoryViewImage release];
[accessoryView release];
for changing text color here's the solution
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
CGRect imageFrame = CGRectMake(0.0, 0.0, 15, 15);
UIImageView *label = [[[UIImageView alloc] initWithFrame:imageFrame] **autorelease**];
if (row == 0)
{
label.backgroundColor = [UIColor redColor];
}
if (row == 1)
{
label.backgroundColor = [UIColor blueColor];
}
if (row == 2)
{
label.backgroundColor = [UIColor blackColor];
}
return label;
}