如何更改UIPickerView高度

问题描述 投票:113回答:28

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

ios iphone cocoa-touch uikit uipickerview
28个回答
54
投票

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

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

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


5
投票

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

我观看了多个教程,发现view.clipsToBounds = true最有益:

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

this

希望这有用!


4
投票

这在iOS 9中发生了很大的变化(在iOS 8中,它与我们在这里看到的非常相似)。如果你能负担得起仅针对iOS 9,那么你可以通过设置框架来调整UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)]; [self.view addSubview:picker]; picker.delegate = self; picker.dataSource = self; 的大小。好!

这是来自UIPickerView

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

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


2
投票

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


1
投票

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

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

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


1
投票

好吧,经过iOS 4中愚蠢的pickerview挣扎了很长时间后,我决定将我的控制权改为简单表:这里是代码:

iOS 9 Release Notes

这是.h文件:

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

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

享受每一个人


1
投票

你通常不能在xib中或在程序上设置框架,但是如果你打开它的父xib作为源并从那里改变高度那么它就可以工作。右键单击包含pickerview的xib,搜索pickerview你可以找到高度,宽度等在该标签中,更改高度然后保存文件。

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

1
投票

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

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

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

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

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

这是我添加的IB约束。


0
投票

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


0
投票

看看我对这个问题的回答:<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>


0
投票

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


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,这样只有一部分拾取器可见,这是由我背景中的透明窗口决定的。


0
投票

Swift:您需要添加带有剪辑到边界的子视图

UIPicker sizing in landscape mode

这应该在视图控制器的顶部添加一个剪切的100高度日期选择器。


0
投票

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

    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)

0
投票

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

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

0
投票

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


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 现在可以调整大小。我只是想补充一下,如果你想在tableView Cell中更改pickerView的高度,我将高度锚设置为常量没有任何成功。但是,使用UIPickerView似乎有效。

lessThanOrEqualToConstant

-1
投票

经过漫长的一天挠头,我发现了一些对我有用的东西。每次用户更改电话方向时,以下代码都会重新创建UIDatePicker。这将删除方向更改后UIDatePicker所具有的任何故障。

由于我们正在重新创建UIDatePicker,因此我们需要一个保持所选日期值的实例变量。以下代码在iOS 4.0上进行测试。

 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)
     }

 }

-1
投票
    @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

如果要设置UiPickerView的大小。上面的代码肯定会对你有用。


-1
投票

在iOS 5.0中,我得到以下工作:

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

这创建了一个日期选择器,就像Apple在横向模式下创建新事件时在日历应用中使用的日期选择器。 (3行高而不是5)。当我在UIDatePicker *picker = [[UIDatePicker alloc] init]; picker.frame = CGRectMake(0.0, 0.0, 320.0, 160.0); 方法中设置帧时,这不起作用,但到目前为止使用单独的方法设置它时。


-1
投票

对于iOS 5:

如果你快速浏览一下initWithFrame: Reference

你会找到

UIPickerView Protocol

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


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


40
投票

尝试:

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

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

哪个是bug?你的猜测和我的一样好。

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

14
投票

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


10
投票

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


7
投票

好处:

  1. 使UIPickerView的setFrame表现得像它应该的那样
  2. 你的UIViewController中没有变换代码
  3. viewWillLayoutSubviews内工作以重新调整/定位UIPickerView
  4. 在没有UIPopover的iPad上工作
  5. 超类始终接收有效高度
  6. 适用于iOS 5

缺点:

  1. 要求你继承qa​​zxswpoi
  2. 需要使用UIPickerView来撤消子视图的转换
  3. UIAnimations可能不起作用

解:

子类UIPickerView并使用以下代码覆盖这两个方法。它结合了子类化,固定高度和转换方法。

pickerView viewForRow

7
投票

更改选取器视图的可见高度的简单方法是将选取器嵌入到UIView中,将父视图的高度调整为要查看选取器的高度,然后在父UIView上的Interface Builder中启用“剪辑子视图”或在代码中设置#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; }

© www.soinside.com 2019 - 2024. All rights reserved.