如何更改UIPickerView高度

时间:2009-02-22 00:04:26

标签: ios iphone cocoa-touch uikit uipickerview

是否可以更改UIPickerView的高度?有些应用程序似乎有较短的PickerViews,但设置较小的框架似乎不起作用,框架在Interface Builder中被锁定。

28 个答案:

答案 0 :(得分:54)

很明显Apple并没有特别邀请UIPickerView的默认高度,但我发现你可以通过以下方式改变视图的高度在创建时完全控制并传递所需的帧大小,例如:

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

你会发现,在不同的高度和宽度,有视觉故障。显然,这些故障要么需要以某种方式解决,要么选择另一种不显示它们的尺寸。

答案 1 :(得分:46)

上述方法均不适用于iOS 4.0

pickerView的高度不再重新调整大小。如果您尝试在4.0中更改选择器的框架,则会有一条消息被转储到控制台:

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

我最终做了一些相当激进的事情,以获得在OS 3.xx和OS 4.0中都能运行的较小选择器的效果。我把选择器留给了SDK决定它应该是什么尺寸,而是在我的背景图像上做了一个直通透明窗口,拾取器变得可见。然后简单地将选择器放在后面(Z顺序)我的背景UIImageView,这样只有一部分选择器可见,这是由我背景中的透明窗口决定的。

答案 2 :(得分:43)

UIPickerView (162.0, 180.0 and 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));

上面的代码将选择器视图的高度更改为一半,并将其重新定位到确切的(Left-x1,Top-y1)位置。

答案 3 :(得分:40)

尝试:

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

答案 4 :(得分: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)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

答案 5 :(得分:14)

从iOS 9开始,您可以自由更改match的宽度和高度。无需使用上述变换黑客。

答案 6 :(得分:10)

我发现你可以编辑UIPickerView的大小 - 而不是使用界面构建器。使用文本编辑器打开.xib文件,并将选择器视图的大小设置为您想要的任何值。接口构建器不会重置大小,它似乎工作。我确定苹果锁定尺寸是有原因的,所以你必须尝试不同的尺寸才能看到它的作用。

答案 7 :(得分:7)

更改选取器视图的可见高度的简单方法是将选取器嵌入到UIView中,将父视图的高度调整为要查看选取器的高度,然后在Interface Builder中启用“剪辑子视图”父UIView或在代码中设置view.clipsToBounds = true

Clip Subviews in IB

答案 8 :(得分:7)

优点:

  1. 使UIPickerView的setFrame表现得像
  2. UIViewController
  3. 中没有转换代码
  4. viewWillLayoutSubviews内工作以重新定位/定位UIPickerView
  5. 在没有UIPopover
  6. 的iPad上工作
  7. 超类始终收到有效高度
  8. 适用于iOS 5
  9. 缺点:

    1. 要求您继承UIPickerView
    2. 需要使用pickerView viewForRow来撤消子视图的转换
    3. UIAnimations可能不起作用
    4. 解决方案:

      使用以下代码子类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;
      }
      

答案 9 :(得分:5)

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

我观看了多个教程,发现this最有益:

我添加了以下代码来设置“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;

希望这有用!

答案 10 :(得分:4)

这在iOS 9中发生了很大的变化(在iOS 8中,它与我们在这里看到的非常相似)。如果您能够承担仅针对iOS 9的费用,则可以根据需要调整UIPickerView的大小,方法是设置其框架。好!

来自iOS 9 Release Notes

  

UIPickerView和UIDatePicker现在可以调整大小   自适应先前,即使这些视图也强制执行默认大小   你试图调整它们的大小。这些视图现在也默认为宽度   所有设备上的320点,而不是设备宽度   iPhone。

     

依赖于旧的默认大小强制执行的接口将会   在为iOS 9编译时可能看起来不对。遇到任何问题   可以通过完全约束或调整选择器视图的大小来解决   期望的大小,而不是依赖隐含的行为。

答案 11 :(得分:2)

我正在使用ios 7,Xcode 5.我能够通过将日期选择器封闭在视图中来间接调整日期选择器的高度。容器视图高度可以调整。

答案 12 :(得分:1)

在IB或代码中创建视图。添加您的选择器作为此视图的子视图。调整视图大小。这在IB中最容易做到。从视图到其超级视图以及从选取器到此新视图创建约束。

由于它周围的Picker曲线溢出了视图的顶部和底部。您可以在IB中看到,当您从选择器向视图添加顶部和底部约束时,它会显示一个标准空间,例如superview容器上方和下方的16个点。如果您不想要此行为,请将视图设置为剪辑(丑陋警告)。

这是iPhone 5上96点高的样子。带有溢出效应的选择器高约130点。很瘦!

我在我的项目中使用它来防止拾取器扩散到不必要的高度。这种技术将其削减并迫使更严重的溢出。它实际上看起来更加紧凑。

enter image description here

这是显示溢出效果的视图图像。

enter image description here

这是我添加的IB约束。

enter image description here

答案 13 :(得分:1)

你通常不能在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>

答案 14 :(得分:1)

即使认为它没有调整大小,当UIPicker位于屏幕底部时,另一个技巧可能会有所帮助。

可以尝试稍微向下移动,但中央行应保持可见。这将有助于揭示拾取器上方的一些空间,因为底行将在屏幕外。

我再说一遍,这不是改变UIPicker视图高度的方法,但是如果所有其他尝试失败,你可以做些什么。

答案 15 :(得分:1)

好的,在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];

就是这样,现在唯一剩下的就是在组合框视图中创建一个成员变量来保存当前行选择,我们很高兴。

享受每个人。

答案 16 :(得分:0)

我的诀窍:使用datepicker的遮罩层使datePicker的某些部分可见。如你所见,就像更改datepicke的框架一样。

- (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;
}

答案 17 :(得分:0)

据我所知,缩小UIPickerView是不可能的。我还没有看到任何地方使用过的较短的一个。我的猜测是,如果他们设法缩小它,那是一个自定义实现。

答案 18 :(得分:0)

如上所述,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)
     }

 }

答案 19 :(得分:0)

我使用遮罩层来改变它的显示尺寸

// 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

答案 20 :(得分:0)

嵌入堆栈视图。堆栈视图是Apple最近在其iOS SDK中添加的组件,用于反映基于java脚本Web的前端库(如bootstrap)中基于网格的实现。

答案 21 :(得分:0)

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高度日期选择器。

答案 22 :(得分:0)

如果您想在IB中创建选择器,可以将其重新调整为较小的尺寸。检查以确保它仍然正确绘制,因为有一点看起来令人发指。

答案 23 :(得分:0)

请参阅我对此问题的回答:UIPicker sizing in landscape mode

答案 24 :(得分:-1)

iOS 5的

如果您快速查看UIPickerView Protocol参考

你会找到

– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:

我认为这是你要找的第一个

答案 25 :(得分:-1)

在iOS 5.0中,我有以下工作:

UIDatePicker *picker = [[UIDatePicker alloc] init];
picker.frame = CGRectMake(0.0, 0.0, 320.0, 160.0);

在横向模式下创建新事件时,这会创建一个类似Apple在日历应用中使用的日期选择器。 (3行高而不是5)。当我在initWithFrame:方法中设置帧时,这不起作用,但到目前为止,使用单独的方法设置它时仍然有效。

答案 26 :(得分:-1)

经过漫长的一天挠头之后,我发现了一些对我有用的东西。每次用户更改电话方向时,以下代码都会重新创建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

答案 27 :(得分:-1)

stockPicker = [[UIPickerView alloc] init];
stockPicker.frame = CGRectMake(70.0,155, 180,100);

如果要设置UiPickerView的大小。上面的代码肯定会适合你。