是否可以更改UIPickerView的高度?某些应用程序似乎具有较短的PickerViews,但设置较小的框架似乎不起作用,并且框架已在Interface Builder中锁定。
是否可以更改UIPickerView的高度?某些应用程序似乎具有较短的PickerViews,但设置较小的框架似乎不起作用,并且框架已在Interface Builder中锁定。
Answers:
显然,Apple并没有特别邀请默认高度为的废话UIPickerView
,但我发现您可以通过完全控制并在创建时传递所需的帧大小来实现视图高度的更改,例如:
smallerPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)];
您会发现在各种高度和宽度上都有视觉故障。显然,这些小故障要么需要以某种方式解决,要么选择其他不显示它们的大小。
以上方法均无法在iOS 4.0中使用
pickerView的高度不再可调整大小。如果您尝试在4.0中更改选择器的框架,则会有一条消息转储到控制台:
-[UIPickerView setFrame:]: invalid height value 66.0 pinned to 162.0
我最终做了一些相当激进的工作,以得到在OS 3.xx和OS 4.0中都可以使用的较小选取器的效果。我将选择器的大小设置为SDK决定的大小,而是在背景图像上制作了一个透明的透明窗口,通过该窗口可以看到选择器。然后只需将选择器放置在背景UIImageView的后面(按Z顺序排列),以便仅部分选择器可见,这是由背景中的透明窗口决定的。
的有效高度只有三个UIPickerView (162.0, 180.0 and 216.0)
。
您可以使用CGAffineTransformMakeTranslation
和CGAffineTransformMakeScale
功能来适当地配合选择器以方便使用。
例:
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));
上面的代码将选取器视图的高度更改为一半,然后将其重新放置到精确的位置(左x1,上y1)。
尝试:
pickerview.transform = CGAffineTransformMakeScale(.5, 0.5);
在iOS 4.2和4.3中,以下功能有效:
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.frame = CGRectMake(0, 0, 320, 180);
[self addSubview:datePicker];
以下内容不起作用:
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 320, 180)];
[self addSubview:datePicker];
我在应用商店中有一个带有3行日期选择器的应用。我认为高度变化可能已被阻止,因为您看到了日期选择器边框下方的文本,但这也发生在正常的216高度日期选择器中。
哪个错误?你的猜测和我的一样好。
此外,UIDatePicker
(和UIPickerView
)162.0、180.0和216.0 还有3个有效高度。如果将其他UIPickerView
高度设置为其他高度,则在iOS设备上进行调试时,控制台中将显示以下内容。
2011-09-14 10:06:56.180 DebugHarness[1717:707] -[UIPickerView setFrame:]: invalid height value 300.0 pinned to 216.0
我发现您可以编辑UIPickerView的大小-只是不能使用界面生成器。使用文本编辑器打开.xib文件,然后将选择器视图的大小设置为所需的大小。界面生成器不会重置大小,并且似乎可以正常工作。我确定Apple锁定了尺寸是有原因的,所以您必须尝试不同的尺寸才能看到效果。
UIPickerView
表现得像应该的UIViewController
viewWillLayoutSubviews
进行重新缩放/定位UIPickerView
UIPopover
UIPickerView
pickerView viewForRow
来撤消subViews的转换子类化UIPickerView并使用以下代码覆盖这两种方法。它结合了子类化,固定高度和变换方法。
#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;
}
更改选择器视图的可见高度的一种简单方法是将选择器嵌入UIView中,将父视图的高度调整为您想要看到的选择器的高度,然后在父UIView的Interface Builder中启用“剪辑子视图”或view.clipsToBounds = true
在代码中设置。
Clip Subviews
。的大小也UIPickerView
必须更高-并且您必须将自己的中心对准UIPickerView
父母内部可见UIView
UIPickerView
从代码创建的)。
这在iOS 9中发生了很大变化(在iOS 8中,这与我们在此处看到的内容非常相似)。如果您只能以iOS 9为目标,则可以调整UIPickerView
通过设置的框架来。好!
这是来自iOS 9发行说明
UIPickerView和UIDatePicker现在可以调整大小和自适应-以前,即使您尝试调整它们的大小,这些视图也将强制使用默认大小。现在,这些视图在所有设备上的默认宽度均为320点,而不是在iPhone上的宽度。
为iOS 9编译时,依赖默认大小的旧版本的接口可能会看起来错误。可以通过将选择器视图完全约束或调整为所需的大小而不是依靠隐式行为来解决遇到的问题。
我正在使用ios 7,Xcode5。我可以通过将其封装在视图中来间接调整日期选择器的高度。容器视图的高度可以调整。
用IB或代码创建视图。将选择器添加为该视图的子视图。调整视图大小。这在IB中最容易做到。从视图到其父视图以及从选择器到此新视图创建约束。
由于Picker周围的曲线会溢出到视图的顶部和底部。当您在选择器中向视图中添加顶部和底部约束时,您可以在IB中看到它显示了标准空间,例如在Superview容器上方和下方的16点。如果您不希望出现这种情况,请将视图设置为对其进行裁剪(难看的警告)。
这就是iPhone 5上高96点的样子。带有溢出效果的选择器高约130点。很瘦!
我在项目中使用了此选项,以防止选择器散布到不必要的高度。此技术将其修整并迫使溢出更紧密。实际上看起来更光滑一些。
这是显示溢出效果的视图图像。
这是我添加的IB约束。
好吧,在iOS 4中愚蠢的pickerview苦苦挣扎了很长时间之后,我决定将控件更改为简单表:这是代码:
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
这是.h文件:
//
// 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];
就是这样,现在剩下的唯一一件事就是在组合框视图中创建一个成员变量,该成员变量将保存当前行选择,而我们很高兴。
享受大家。
通常不能在xib中进行编程,也不能以编程方式设置框架,但是如果打开其父xib作为源并从那里更改高度,则可以正常工作。右键单击包含pickerview的xib,搜索pickerview即可找到高度,宽度等在该标签中,更改高度然后保存文件。
<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>
据我所知,缩小UIPickerView是不可能的。我实际上还没有在任何地方看到过使用更短的产品。我的猜测是,如果他们设法缩小它,那将是一个自定义实现。
Swift:您需要添加一个带限界的子视图
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)
这应该在视图控制器的顶部添加一个裁剪的100高度日期选择器。
我的技巧:使用datepicker的mask层使datePicker的某些部分可见。如您所见,就像更改日期选择框一样。
- (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;
}
如上所述,UIPickerView
现在可以调整大小。我只是想补充一下,如果您想在tableView Cell中更改pickerView的高度,则无法将高度锚定为常数。但是,使用lessThanOrEqualToConstant
似乎有效。
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)
}
}
经过一整天的挠挠,我发现了一些对我有用的东西。每当用户更改手机方向时,以下代码将重新创建UIDatePicker。这将消除方向更改后UIDatePicker产生的任何故障。
由于我们正在重新创建UIDatePicker,因此我们需要一个实例变量,该实例变量将保留选定的日期值。以下代码在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
对于iOS 5:
如果您快速浏览一下《UIPickerView协议参考》
你会找到
– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
我想是您要寻找的第一个
pickerView:rowHeightForComponent:
是确定每行高度的委托方法-而不是选择器视图的高度。