Add opaque subview to UITextField - ios

I have a subclass of UITextField and I'm trying ot add an opaque subview to it. However, when I type in the UITextField, it appears transparent and I can see the text behind the view. How can I make the view fully opaque? Here is the code that inits the subclass and adds the view.
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
_dropdownIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ab- dropdown-on"]];
dropdownIcon.backgroundColor = [UIColor blackColor];
_dropdownIcon.frame = CGRectMake(self.frame.size.width-DROPDOWN_ICON_SIZE,0,DROPDOWN_ICON_SIZE,DROPDOWN_ICON_SIZE);
[self addSubview:_dropdownIcon];
}
return self;
}

Your subclass needs to override the -textRectForBounds: method to return the actual area you want text to draw in, e.g.
- (CGRect)textRectForBounds:(CGRect)bounds
{
CGRect textRect = [super textRectForBounds:bounds];
textRect.size.width -= 30; // or however wide your control is—play with this value
return textRect;
}
What you’re seeing is not the icon being non-opaque—the text is just being drawn over it, because the text field doesn’t “know” the icon is there.
You might also look into the rightView property and the related -rightViewRectForBounds: method, though those are mostly useful if you want the text field to automatically show and hide your accessory view.

Related

UIPickerView Maximum Width in iOS 9

I have an app that uses a UIPickerView to set various parameters having to do with line style for a graph series (line width, colour, and line style). This picker is used in a table view row. I have defined the frame for the picker so that its width fills the width of the cell's contentView member. Up until iOS 9, this appeared to work. With iOS 9, there appears to be some sort of maximum cap on the width of a UIPickerView. Has anyone encountered anything similar to this?
The picker view is being created like this:
self.picker = [[[UIPickerView alloc] init] autorelease];
[self.contentView addSubview:self.picker];
self.picker.dataSource = self;
self.picker.delegate = self;
self.picker.backgroundColor = [UIColor grouped_table_view_background_colour];
The cell is layed out as follows:
-(void) layoutSubviews
{
// we need to allow the base class to perform its layout.
static CGFloat left_margin = 40;
static CGFloat right_margin = 40;
CGSize my_size;
[super layoutSubviews];
my_size = self.contentView.bounds.size;
my_size.width -= left_margin + right_margin;
// we now need to lay out the views.
CGRect picker_rect = CGRectMake(left_margin, 5, my_size.width, my_size.height);
self.picker.frame = picker_rect;
// we want to look at the bounds of the picker
CGRect picker_bounds = self.picker.bounds;
NSLog(#"picker bounds x=%g, y=%g, w=%g, h=%g", picker_bounds.origin.x, picker_bounds.origin.y, picker_bounds.size.width, picker_bounds.size.height);
}
I am also overloading the widthForComponent method as follows:
-(CGFloat) pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
// we want to look at the bounds of the picker
CGRect picker_bounds = self.picker.bounds;
NSLog(#"picker bounds x=%g, y=%g, w=%g, h=%g", picker_bounds.origin.x, picker_bounds.origin.y, picker_bounds.size.width, picker_bounds.size.height);
return picker_bounds.size.width / 3;
}
I can see that the bounds of the view appear correctly both in the values that are logged as well as the background colour of the view. Despite this, the picker appears to fill less than half the width that is available (688 points on my iPad)
After [[UIPickerView alloc] init] the Picker has a size of {320,216} and this size will be used in pickerView:widthForComponent:. If you just resize the picker afterwards, the function pickerView:widthForComponent: won't be called again, so the components are stuck at their width.
Try to initialise the picker with the correct size like..
picker=[[UIDatePicker new] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(self.view.bounds), 216.0)];
or call [self.picker setNeedsLayout] after you change the picker frame to force pickerView:widthForComponent: to be called again.

Is it possible to use custom view for SKCalloutView?

Is it possible to make a custom UIView, with elements such as Label and Button, and use it as a CalloutView?
What I read through the documentation so far doesn't implicates that it is possible.
Changing left and right button is possible, together with adding custom UIImageView for an arrow, but couldn't figure out if customising entire view is actually possible.
Yes - you just have to override the calloutViewForAnnotation callback. There is an example in the demo project (see inside AnnotationsViewController.m) where you can create a user defined UIView and return that
- (UIView*)mapView:(SKMapView *)mapView calloutViewForAnnotation:(SKAnnotation *)annotation
{
//Custom callouts.
if (annotation.identifier == self.annotation1.identifier)
{
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 200.0f, 50.0f)];
view.backgroundColor = [UIColor purpleColor];
view.alpha = 0.5f;
return view;
}
return nil;// Default callout view will be used.
}

Setting backgroundColor doesn't seem to work on a UIView

I have some code that tries to set the backgroundColor in a UIView from an Image but all I see is black screen. Here is what I did -
Have a UIViewController class and UIView class
The UIView class has a drawRect function.
In the UIViewController viewDidLoad function create the UIView class
After that the drawRect in the UIView is called.
Here is the code for the UIView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect
{
UIColor *backGround = [UIColor colorWithPatternImage:[UIImage imageNamed:#"test.png"]];
self.backgroundColor = backGround;
}
Verified in the debugger that the backGround object is not nil after execution. Also tested the test.png file exists and I can create a UIImageView with it.
I see that the result is the same if I set the backgroundColor in the initWithFrame function instead of the drawRect()
The reason I want to set the backgroundColor is I am drawing a board game and I want to use the image as the background. That way I can just draw the lines (board) on the image.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
UIColor *backGround = [UIColor colorWithPatternImage:[UIImage imageNamed:#"test.png"]];
self.backgroundColor = backGround;
}
return self;
}
Changing the background in drawRect won't work. Any changes to it must be done in the init method.
just try out this in the viewDidLoad
-(void)viewDidLoad{
UIColor *backGround = [UIColor colorWithPatternImage:[UIImage imageNamed:#"test.png"]];
self.view.backgroundColor = backGround;
//.....
}
EDIT:
For your problem :
the drawing is being done by a layer associated with your view. It looks like, in your environment, the background-colored layer is doing its drawing before your -drawRect: method is called. When the layer redraws, your -drawRect: method also happens to be called. So, after you change the background color, you don't see any changes till the background layer draws again, which you can tell happened because your -drawRect: gets called again. (Here && Check for more info)
In drawRect method you should not set background. You have to do drawing, which you want to draw in view. Background view is separate view. If you want to set the background view within your custom view, do it in init method or else you can do it in your view controller(anywhere).

UITableViewCell contentView custom disclosure image frame issue

Disclaimer: I've been working too late. But, I'm determined to get through this one tonight.
I have an app where I support different color themes. The dark cell backgrounds have been problematic.
I've been poking around trying to find a formidable way to draw the accessory disclosure icon in uitableviewcells with black backgrounds.
I decided to try overriding setAccessoryType to inherit the functionality for my 50+ views:
-(void) addWhiteDisclosureImage {
UIImageView *disclosureView = (UIImageView*) [self.contentView viewWithTag:kDisclosureReplacementImageTag];
if(!disclosureView) {
[super setAccessoryType:UITableViewCellAccessoryNone];
disclosureView = [[UIImageView alloc] initWithImage:self.whiteDisclosureImage];
disclosureView.tag = kDisclosureReplacementImageTag;
disclosureView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
DebugLog(#"%f, %f", self.frame.size.width, self.frame.size.height);
[self.contentView addSubview:disclosureView];
[self.contentView bringSubviewToFront:disclosureView];
[disclosureView release];
}
}
- (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType {
if(accessoryType == UITableViewCellAccessoryDisclosureIndicator) {
if ([self.viewController isKindOfClass:[ViewControllerBase class]]) {
ViewControllerBase *view = (ViewControllerBase*) self.viewController;
if(view.colorTheme && view.colorTheme.controlBackgroundColor) {
if([ViewColors colorAverage:view.colorTheme.controlBackgroundColor] < 0.2) { //substitute white disclosure indicator
[self addWhiteDisclosureImage];
return;
} else { //not dark enough
[self removeWhiteDisclosureImage];
[super setAccessoryType:accessoryType];
return;
}
} else { //no colorTheme.backgroundColor
[self removeWhiteDisclosureImage];
[super setAccessoryType:accessoryType];
return;
}
} else { //viewController is not type ViewControllerBase
[self removeWhiteDisclosureImage];
[super setAccessoryType:accessoryType];
return;
}
}
UIView *disclosureView = [self.contentView viewWithTag:kDisclosureReplacementImageTag];
if(disclosureView)
[disclosureView removeFromSuperview];
[super setAccessoryType:accessoryType];
}
This override is typically called in cellForRowAtIndexPath.
It seemed like a good option until I drill down and come back. For some cells, the cell frame will be a great deal larger than the first time through. This consistently happens to the same cell in a list of 6 that I've been testing against. There's clearly something unique about this cell: it's frame.size.
Here is the size of the cell that I log for the first tableview load (in some cases every load/reload):
320.000000, 44.000000
This is the difference in what I get for some (not all) of the cells after call to reloadData:
759.000000, 44.000000
Does anyone know why this might happen?
Update: the suspect cell's custom accessory disclosure view almost acts like it's autoresizing flag is set to none. I confirmed this by setting all to none. I say almost because I see it line up where it should be after reloadData. A split second later it moves clear over to the left (where they all end up when I opt for no autoresizing).
Don't mess around with subviews and calculating frames.
Just replace the accessoryView with the new imageView. Let iOS do the work.

How to change UIPickerView height

Is it possible to change the height of UIPickerView? Some applications seem to have shorter PickerViews but setting a smaller frame doesn't seem to work and the frame is locked in Interface Builder.
It seems obvious that Apple doesn't particularly invite mucking with the default height of the UIPickerView, but I have found that you can achieve a change in the height of the view by taking complete control and passing a desired frame size at creation time, e.g:
smallerPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)];
You will discover that at various heights and widths, there are visual glitches. Obviously, these glitches would either need to be worked around somehow, or choose another size that doesn't exhibit them.
None of the above approaches work in iOS 4.0
The pickerView's height is no longer re-sizable. There is a message which gets dumped to console if you attempt to change the frame of a picker in 4.0:
-[UIPickerView setFrame:]: invalid height value 66.0 pinned to 162.0
I ended up doing something quite radical to get the effect of a smaller picker which works in both OS 3.xx and OS 4.0. I left the picker to be whatever size the SDK decides it should be and instead made a cut-through transparent window on my background image through which the picker becomes visible. Then simply placed the picker behind (Z Order wise) my background UIImageView so that only a part of the picker is visible which is dictated by the transparent window in my background.
There are only three valid heights for UIPickerView (162.0, 180.0 and 216.0).
You can use the CGAffineTransformMakeTranslation and CGAffineTransformMakeScale functions to properly fit the picker to your convenience.
Example:
CGAffineTransform t0 = CGAffineTransformMakeTranslation (0, pickerview.bounds.size.height/2);
CGAffineTransform s0 = CGAffineTransformMakeScale (1.0, 0.5);
CGAffineTransform t1 = CGAffineTransformMakeTranslation (0, -pickerview.bounds.size.height/2);
pickerview.transform = CGAffineTransformConcat (t0, CGAffineTransformConcat(s0, t1));
The above code change the height of picker view to half and re-position it to the exact (Left-x1, Top-y1) position.
Try:
pickerview.transform = CGAffineTransformMakeScale(.5, 0.5);
In iOS 4.2 & 4.3 the following works:
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.frame = CGRectMake(0, 0, 320, 180);
[self addSubview:datePicker];
The following does not work:
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 320, 180)];
[self addSubview:datePicker];
I have an app that is in the app store with a 3 line date picker. I thought the height change may have been prevented because you see the text under the date picker's border, but this happens to the normal 216 height date picker too.
Which is the bug? Your guess is as good as mine.
Also there are 3 valid heights for UIDatePicker (and UIPickerView) 162.0, 180.0, and 216.0. If you set a UIPickerView height to anything else you will see the following in the console when debugging on an iOS device.
2011-09-14 10:06:56.180 DebugHarness[1717:707] -[UIPickerView setFrame:]: invalid height value 300.0 pinned to 216.0
As of iOS 9, you can freely change UIPickerView's width and height. No need to use the above mentioned transform hacks.
I have found that you can edit the size of the UIPickerView - just not with interface builder. open the .xib file with a text editor and set the size of the picker view to whatever you want. Interface builder does not reset the size and it seems to work. I'm sure apple locked the size for a reason so you'll have to experiment with different sizes to see what works.
Advantages:
Makes setFrame of UIPickerView behave like it should
No transform code within your UIViewController
Works within viewWillLayoutSubviews to rescale/position the UIPickerView
Works on the iPad without UIPopover
The superclass always receives a valid height
Works with iOS 5
Disadvantages:
Requires you to subclass UIPickerView
Requires the use of pickerView viewForRow to undo the transformation for the subViews
UIAnimations might not work
Solution:
Subclass UIPickerView and overwrite the two methods using the following code. It combines subclassing, fixed height and the transformation approach.
#define FIXED_PICKER_HEIGHT 216.0f
- (void) setFrame:(CGRect)frame
{
CGFloat targetHeight = frame.size.height;
CGFloat scaleFactor = targetHeight / FIXED_PICKER_HEIGHT;
frame.size.height = FIXED_PICKER_HEIGHT;//fake normal conditions for super
self.transform = CGAffineTransformIdentity;//fake normal conditions for super
[super setFrame:frame];
frame.size.height = targetHeight;
CGFloat dX=self.bounds.size.width/2, dY=self.bounds.size.height/2;
self.transform = CGAffineTransformTranslate(CGAffineTransformScale(CGAffineTransformMakeTranslation(-dX, -dY), 1, scaleFactor), dX, dY);
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
//Your code goes here
CGFloat inverseScaleFactor = FIXED_PICKER_HEIGHT/self.frame.size.height;
CGAffineTransform scale = CGAffineTransformMakeScale(1, inverseScaleFactor);
view.transform = scale;
return view;
}
An easy way to change the visible height of a picker view is to embed the picker in a UIView, adjust the parent view's height to the height you want to see of the picker, then enable "Clip Subviews" in Interface Builder on the parent UIView or set view.clipsToBounds = true in code.
I wasn't able to follow any of the above advice.
I watched multiple tutorials and found this one the most beneficial:
I added the following code to set the new height inside the "viewDidLoad" method, which worked in my app.
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)];
[self.view addSubview:picker];
picker.delegate = self;
picker.dataSource = self;
Hope this was helpful!
This has changed a lot in iOS 9 (in iOS 8 it's pretty similar to what we're seeing here). If you can afford to target iOS 9 only, then you resize the UIPickerView as you see fit, by setting its frame. Good!
Here it is from iOS 9 Release Notes
UIPickerView and UIDatePicker are now resizable and
adaptive—previously, these views would enforce a default size even if
you attempted to resize them. These views also now default to a width
of 320 points on all devices, instead of to the device width on
iPhone.
Interfaces that rely on the old enforcement of the default size will
likely look wrong when compiled for iOS 9. Any problems encountered
can be resolved by fully constraining or sizing picker views to the
desired size instead of relying on implicit behavior.
I am working with ios 7, Xcode 5. I was able to adjust the height of date picker indirectly by enclosing it in a view. The container views height can be adjusted.
Create a view in IB or code. Add your picker as a subview of this view. Resize the view. This is easiest to do in IB. Create constraints from the view to its superview and from the picker to this new view.
Since the Picker curves around it spills out over the top and bottom of the view. You can see in IB when you add top and bottom constraints from the picker to the view it shows a standard space something like 16 points above and below the superview container. Set the view to clip it if you don't want this behaviour (ugly warning).
Here's what it looks like at 96 points high on an iPhone 5. The picker with the spillover is about 130 points high. Pretty skinny!
I'm using this in my project to prevent the picker from spreading out to an unnecessary height. This technique trims it down and forces a tighter spill over. It actually looks slicker to be a bit more compact.
Here's an image of the view showing the spillover.
Here's the IB constraints I added.
As mentioned above UIPickerView is now resizable. I just want to add though that if you want to change the pickerView's height in a tableView Cell, I didn't have any success with setting the height anchor to a constant. However, using lessThanOrEqualToConstant seems to work.
class PickerViewCell: UITableViewCell {
let pickerView = UIPickerView()
func setup() {
// call this from however you initialize your cell
self.contentView.addSubview(self.pickerView)
self.pickerView.translatesAutoresizingMaskIntoConstraints = false
let constraints: [NSLayoutConstraint] = [
// pin the pickerView to the contentView's layoutMarginsGuide
self.pickerView.leadingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.leadingAnchor),
self.pickerView.topAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.topAnchor),
self.pickerView.trailingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.trailingAnchor),
self.pickerView.bottomAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.bottomAnchor),
// set the height using lessThanOrEqualToConstant
self.pickerView.heightAnchor.constraint(lessThanOrEqualToConstant: 100)
]
NSLayoutConstraint.activate(constraints)
}
}
Even thought it is not resizing, another trick may help in the situation when the UIPicker is located at the bottom of the screen.
One can try moving it slightly downwards, but the central row should remain visible. This will help reveal some space above the picker since bottom rows will be offscreen.
I repeat that this is not the way of changing UIPicker view's height but some idea on what you can do if all other attempts fail.
Ok, after struggling for a long time with the stupid pickerview in iOS 4, I've decided to change my control into simple table:
here is the code:
ComboBoxView.m = which is actually looks more like pickerview.
//
// ComboBoxView.m
// iTrophy
//
// Created by Gal Blank on 8/18/10.
//
#import "ComboBoxView.h"
#import "AwardsStruct.h"
#implementation ComboBoxView
#synthesize displayedObjects;
#pragma mark -
#pragma mark Initialization
/*
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
if ((self = [super initWithStyle:style])) {
}
return self;
}
*/
#pragma mark -
#pragma mark View lifecycle
/*
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
*/
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
return [[self displayedObjects] count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *MyIdentifier = [NSString stringWithFormat:#"MyIdentifier %i", indexPath.row];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
//cell.contentView.frame = CGRectMake(0, 0, 230.0,16);
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 5, 230.0,19)] autorelease];
VivatAwardsStruct *vType = [displayedObjects objectAtIndex:indexPath.row];
NSString *section = [vType awardType];
label.tag = 1;
label.font = [UIFont systemFontOfSize:17.0];
label.text = section;
label.textAlignment = UITextAlignmentCenter;
label.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
label.adjustsFontSizeToFitWidth=YES;
label.textColor = [UIColor blackColor];
//label.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:label];
//UIImage *image = nil;
label.backgroundColor = [UIColor whiteColor];
//image = [awards awardImage];
//image = [image imageScaledToSize:CGSizeMake(32.0, 32.0)];
//[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
//UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
//cell.accessoryView = imageView;
//[imageView release];
}
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Here is the .h file for that:
//
// ComboBoxView.h
// iTrophy
//
// Created by Gal Blank on 8/18/10.
//
#import <UIKit/UIKit.h>
#interface ComboBoxView : UITableViewController {
NSMutableArray *displayedObjects;
}
#property (nonatomic, retain) NSMutableArray *displayedObjects;
#end
now, in the ViewController where I had Apple UIPickerView I replaced with my own ComboBox view and made it size what ever I wish.
ComboBoxView *mypickerholder = [[ComboBoxView alloc] init];
[mypickerholder.view setFrame:CGRectMake(50, 220, 230, 80)];
[mypickerholder setDisplayedObjects:awardTypesArray];
that's it, now the only thing is left is to create a member variable in the combobox view that will hold current row selection, and we are good to go.
Enjoy everyone.
You can not generally do it in xib or setting frame programtically but if you open its parent xib as source and change height from there then it works.Right click the xib within which pickerview is contained,Search pickerview and you can find height,width etc in that tag,Change height there then save file.
<pickerView contentMode="scaleToFill" id="pai-pm-hjZ">
<rect key="frame" x="0.0" y="41" width="320" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<connections>
<outlet property="dataSource" destination="-1" id="Mo2-zp-Sl4"/>
<outlet property="delegate" destination="-1" id="nfW-lU-tsU"/>
</connections>
</pickerView>
As far as I know, it's impossible to shrink the UIPickerView. I also haven't actually seen a shorter one used anywhere. My guess is that it was a custom implementation if they did manage to shrink it.
If you want to create your picker in IB, you can post-resize it to a smaller size. Check to make sure it still draws correctly though, as there comes a point where it looks heinous.
Swift: You need to add a subview with clip to bounds
var DateView = UIView(frame: CGRectMake(0, 0, view.frame.width, 100))
DateView.layer.borderWidth=1
DateView.clipsToBounds = true
var myDatepicker = UIDatePicker(frame:CGRectMake(0,-20,view.frame.width,162));
DateView.addSubview(myDatepicker);
self.view.addSubview(DateView)
This should add a clipped 100 height date picker in the top of the view controller.
My trick: use datepicker's mask layer to make datePicker some part visible. as you see just like change the datepicke's frame.
- (void)timeSelect:(UIButton *)timeButton {
UIDatePicker *timePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 550)];
timePicker.backgroundColor = [UIColor whiteColor];
timePicker.layer.mask = [self maskLayerWithDatePicker:timePicker];
timePicker.layer.masksToBounds = YES;
timePicker.datePickerMode = UIDatePickerModeTime;
[self.view addSubview:timePicker];
}
- (CALayer *)maskLayerWithDatePicker:(UIDatePicker *)datePicker {
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, datePicker.width*0.8, datePicker.height*0.8) cornerRadius:10];
shapeLayer.path = path.CGPath;
return shapeLayer;
}
I use a mask layer to change it's display size
// swift 3.x
let layer = CALayer()
layer.frame = CGRect(x: 0,y:0, width: displayWidth, height: displayHeight)
layer.backgroundColor = UIColor.red.cgColor
pickerView.layer.mask = layer
Embed in a stack view. Stack view is a component recently added by Apple in their iOS SDK to reflect grid based implementations in java script web based front end libraries such as bootstrap.
After a long day of scratching my head, I've found something that works for me. The codes below will recreate the UIDatePicker everytime the user change the phone orientation. This will remove whatever glitches that the UIDatePicker have after an orientation change.
Since we are recreating the UIDatePicker, we need an instance variable that will keep the selected date value. The codes below are tested on iOS 4.0.
#interface AdvanceDateViewController : UIViewController<UIPickerViewDelegate> {
UIDatePicker *datePicker;
NSDate *date;
}
#property (nonatomic, retain) UIDatePicker *datePicker;
#property (nonatomic, retain) NSDate *date;
-(void)resizeViewWithOrientation:(UIInterfaceOrientation) orientation;
#end
#implementation AdvanceDateViewController
#synthesize datePicker, date;
- (void)viewDidLoad {
[super viewDidLoad];
[self resizeViewWithOrientation:self.interfaceOrientation];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self resizeViewWithOrientation:self.interfaceOrientation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self resizeViewWithOrientation:toInterfaceOrientation];
}
-(void)resizeViewWithOrientation:(UIInterfaceOrientation) orientation{
[self.datePicker removeFromSuperview];
[self.datePicker removeTarget:self action:#selector(refreshPickupDate) forControlEvents:UIControlEventValueChanged];
self.datePicker = nil;
//(Re)initialize the datepicker, thanks to Apple's buggy UIDatePicker implementation
UIDatePicker *dummyDatePicker = [[UIDatePicker alloc] init];
self.datePicker = dummyDatePicker;
[dummyDatePicker release];
[self.datePicker setDate:self.date animated:YES];
[self.datePicker addTarget:self action:#selector(refreshPickupDate) forControlEvents:UIControlEventValueChanged];
if(UIInterfaceOrientationIsLandscape(orientation)){
self.datePicker.frame = CGRectMake(0, 118, 480, 162);
} else {
self.datePicker.frame = CGRectMake(0, 200, 320, 216);
}
[self.view addSubview:self.datePicker];
[self.view setNeedsDisplay];
}
#end
stockPicker = [[UIPickerView alloc] init];
stockPicker.frame = CGRectMake(70.0,155, 180,100);
If You want to set the size of UiPickerView. Above code is surely gonna work for u.
In iOS 5.0, I got the following to work:
UIDatePicker *picker = [[UIDatePicker alloc] init];
picker.frame = CGRectMake(0.0, 0.0, 320.0, 160.0);
This created a date picker like the one Apple uses in the Calendar app when creating a new event in landscape mode. (3 rows high instead of 5.) This didn't work when I set the frame within the initWithFrame: method, but so far works when setting it using a separate method.
for iOS 5:
if you take a quick look at the UIPickerView Protocol Reference
you'll find
– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
I think is the first one you're looking for

Resources