如何改变UIPickerView的高度。

118

能否更改UIPickerView的高度?一些应用程序似乎具有较短的PickerViews,但设置较小的框架似乎无效,而且在界面构建器中锁定了框架。


1
更多答案可以在类似的问题中找到:如何在iPhone上缩小选择器视图? - Brad Larson
https://dev59.com/TXNA5IYBdhLWcg3wbNQ4 - baste
27个回答

54

显而易见的是,苹果公司并不特别欢迎更改 UIPickerView 的默认高度,但我发现您可以通过完全控制并在创建时传递所需的框架大小来实现对视图高度的更改,例如:

smallerPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)];

您将发现,在不同的高度和宽度下,会出现视觉故障。显然,这些故障要么需要以某种方式加以解决,要么选择另一种不会出现它们的大小。


2
这对你有用吗?我实例化的所有UIPickerViews似乎都被锁定在高度215上... - Andy Bourassa
有没有任何第三方控件可以进行调整大小? - cfischer
1
这个可行。4.3。我在第一次出现之前用frame和setframe进行了初始化。 - griotspeak
2
我曾经在这个问题上卡了一段时间。重要的是要注意,在第一次出现之前,必须使用init with frame或setframe进行初始化,否则会出现视觉故障。 - w.donahue
糟糕...是否有任何替代控件可以提供相同的功能,并仍然可用? - vir us
显示剩余3条评论

46

以上所有方法都不适用于iOS 4.0。

pickerView的高度不再可调整。如果尝试在4.0中更改picker的框架,控制台会输出一条消息:

-[UIPickerView setFrame:]: invalid height value 66.0 pinned to 162.0 

为了实现一个既能在 OS 3.xx 和 OS 4.0 上工作的较小的 picker 效果,我采取了一种相当激进的方法。我让 picker 保持 SDK 决定的任何大小,并在我的背景图像上制作了一个透明的窗口,通过这个窗口可以看到 picker。然后只需将 picker 放在我的背景 UIImageView 的后面(按 Z Order 排序),这样只有部分 picker 是可见的,这是由我的背景中透明窗口决定的。


44

UIPickerView 只有三个有效的高度 (162.0、180.0 和 216.0)。

您可以使用 CGAffineTransformMakeTranslationCGAffineTransformMakeScale 函数来适当地调整选择器以符合您的需求。

示例:

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)位置。


1
很好的答案。只是需要注意的是,要改变选择器的高度,您不需要使用翻译:pickerview.transform = CGAffineTransformMakeScale(1.0, 0.5); - Borzh
2
谢谢。这似乎是正确的,但是否有任何苹果文档关于有效高度? - Eric Chen

40

尝试:

pickerview.transform = CGAffineTransformMakeScale(.5, 0.5);

2
我知道我来晚了 - 或许现在有更好的方法来做这件事,但这对我有效。 - Hanny
1
非常好!对于Swift(iOS 10),它是: statePicker.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) - Meshach

25
在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)有3个有效的高度:162.0、180.0和216.0。如果将UIPickerView的高度设置为其他任何值,则在iOS设备上进行调试时在控制台中将会看到以下内容。

2011-09-14 10:06:56.180 DebugHarness[1717:707] -[UIPickerView setFrame:]: invalid height value 300.0 pinned to 216.0

15

从iOS 9开始,您可以自由更改UIPickerView的宽度和高度,无需使用上述提到的变换技巧。


需要确定如何将inputAccessoryView添加到增加大小的UIPickerView中。 - DogCoffee
2
怎么做呢? - chaytan

10
我发现你可以编辑UIPickerView的大小 - 只是不能使用界面构建器。用文本编辑器打开.xib文件,并将选择器视图的大小设置为所需大小。界面构建器不会重置大小,而且似乎也能正常工作。我相信苹果之所以锁定了大小,肯定有原因,所以你需要尝试不同的大小来看看哪个大小适合。

7

优点:

  1. 使UIPickerViewsetFrame方法表现得像它应该的那样
  2. 你的UIViewController中没有变换代码
  3. 可以在viewWillLayoutSubviews中工作,以重新缩放/定位UIPickerView
  4. 在iPad上工作,无需使用UIPopover
  5. 超类始终接收到有效高度
  6. 适用于iOS 5

缺点:

  1. 需要你子类化UIPickerView
  2. 需要使用pickerView viewForRow来撤消子视图的转换
  3. UIAnimations可能无法正常工作

解决方案:

子类化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;
}

7

改变选择器视图的可见高度的简单方法是将选择器嵌入到一个UIView中,调整父视图的高度以显示您想要看到的选择器高度,然后在Interface Builder上启用“剪切子视图”或在代码中设置view.clipsToBounds = true

Clip Subviews in IB


你能确认这个实际上可行吗?在Xcode上看起来没问题,但在设备上运行时,它会显示pickerview覆盖在uiview上。 - nhenrique
1
它可以工作 @nhenrique,但你不能忘记 Clip Subviews。此外,UIPickerView 的大小必须更高 - 你必须将你的 UIPickerView 的中心对准父级 UIView 中可见的位置。 - new2ios
这个好像不起作用,@new2ios,你能确认一下在iOS8以上的版本中是否可以工作吗?我正在尝试以编程方式做同样的事情。 - Hemang
抱歉,@hagile,但我放弃了那个想法 - 我无法确认。我使用Storyboard(没有从代码中创建UIPickerView)。 - new2ios
@new2ios,谢谢你的回复。没问题 :) - Hemang
显示剩余2条评论

5

我无法遵循以上任何建议。

我观看了多个教程,发现这个对我最有帮助:

我在“viewDidLoad”方法中添加了以下代码来设置新高度,在我的应用程序中有效。

UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)]; 
[self.view addSubview:picker];
picker.delegate = self;
picker.dataSource = self;

希望这对你有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接