Como alterar a altura do UIPickerView

É possível alterar a altura do UIPickerView? Alguns aplicativos parecem ter PickerViews mais curtos, mas definir um quadro menor parece não funcionar e o quadro está bloqueado no Interface Builder.

    Parece óbvio que a Apple não é particularmente convidada a usar a altura padrão do UIPickerView , mas descobri que é possível obter uma alteração na altura da visualização, assumindo o controle total e passando um tamanho de quadro desejado no momento da criação. :

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

    Você descobrirá que em várias alturas e larguras existem falhas visuais. Obviamente, esses problemas precisariam ser trabalhados de alguma forma, ou escolher outro tamanho que não os exibisse.

    Nenhuma das abordagens acima funciona no iOS 4.0

    A altura do pickerView não é mais redimensionável. Há uma mensagem que é despejada para o console se você tentar alterar o quadro de um selecionador no 4.0:

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

    Eu acabei fazendo algo bastante radical para obter o efeito de um picker menor que funciona tanto no OS 3.xx quanto no OS 4.0. Eu deixei o selecionador com o tamanho que o SDK decidir que deveria ser e, em vez disso, fiz uma janela transparente na minha imagem de fundo, através da qual o selecionador fica visível. Em seguida, simplesmente coloquei o selecionador para trás (Z Ordem sábia) meu background UIImageView para que apenas uma parte do selecionador seja visível, que é ditada pela janela transparente no meu plano de fundo.

    Existem apenas três alturas válidas para o UIPickerView (162.0, 180.0 and 216.0) .

    Você pode usar as funções CGAffineTransformMakeScale e CGAffineTransformMakeScale para ajustar-se adequadamente ao selecionador para sua conveniência.

    Exemplo:

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

    O código acima altera a altura da vista do picker para metade e reposiciona-a para a posição exacta (Left-x1, Top-y1) .

    Experimentar:

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

    No iOS 4.2 e 4.3, os seguintes trabalhos:

     UIDatePicker *datePicker = [[UIDatePicker alloc] init]; datePicker.frame = CGRectMake(0, 0, 320, 180); [self addSubview:datePicker]; 

    O seguinte não funciona:

     UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 320, 180)]; [self addSubview:datePicker]; 

    Eu tenho um aplicativo que está na loja de aplicativos com um seletor de data de 3 linhas. Eu pensei que a mudança de altura pode ter sido evitada porque você vê o texto sob a borda do selecionador de data, mas isso acontece com o selecionador de data de altura normal de 216 também.

    Qual é o bug? Seu palpite é tão bom quanto o meu.

    Também existem 3 alturas válidas para o UIDatePicker (e UIPickerView ) 162.0, 180.0 e 216.0. Se você definir uma altura UIPickerView para qualquer outra coisa, você verá o seguinte no console ao depurar em um dispositivo iOS.

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

    A partir do iOS 9, você pode alterar livremente a largura e a altura do UIPickerView . Não há necessidade de usar os hacks de transformação mencionados acima.

    Eu descobri que você pode editar o tamanho do UIPickerView – mas não com o construtor de interface. abra o arquivo .xib com um editor de texto e defina o tamanho da visualização do selecionador para o que você quiser. O construtor de interface não redefine o tamanho e parece funcionar. Tenho certeza que a Apple bloqueou o tamanho por um motivo, então você terá que experimentar diferentes tamanhos para ver o que funciona.

    Vantagens:

    1. Faz o setFrame do UIPickerView se comportar como deveria
    2. Nenhum código de transformação dentro do seu UIViewController
    3. Funciona com viewWillLayoutSubviews para resize / posicionar o UIPickerView
    4. Funciona no iPad sem o UIPopover
    5. A superclass sempre recebe uma altura válida
    6. Funciona com o iOS 5

    Desvantagens:

    1. Requer que você subclass UIPickerView
    2. Requer o uso de pickerView viewForRow para desfazer a transformação dos subViews
    3. UIAnimations pode não funcionar

    Solução:

    Subclass UIPickerView e substitua os dois methods usando o código a seguir. Ele combina subclasss, altura fixa e a abordagem de transformação.

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

    Uma maneira fácil de alterar a altura visível de uma visualização de selecionador é incorporar o selecionador em um UIView, ajustar a altura da visualização pai à altura desejada do selecionador e ativar “Subvisões de clipe” no Interface Builder no pai UIView ou defina view.clipsToBounds = true no código.

    Clip Subviews no IB

    Não consegui seguir nenhum dos conselhos acima.

    Eu assisti vários tutoriais e achei este o mais benéfico:

    Eu adicionei o seguinte código para definir a nova altura dentro do método “viewDidLoad”, que funcionava no meu aplicativo.

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

    Espero que isso tenha sido útil!

    Isso mudou muito no iOS 9 (no iOS 8 é bem parecido com o que estamos vendo aqui). Se você puder arcar somente com o iOS 9, redimensione o UIPickerView como quiser, definindo o quadro. Boa!

    Aqui está nas notas de versão do iOS 9

    O UIPickerView e o UIDatePicker agora são redimensionáveis ​​e adaptáveis ​​- anteriormente, esses modos de exibição reforçariam um tamanho padrão mesmo se você tentasse redimensioná-los. Essas exibições também agora têm como padrão uma largura de 320 pontos em todos os dispositivos, em vez de usar a largura do dispositivo no iPhone.

    As interfaces que dependem da antiga aplicação do tamanho padrão provavelmente parecerão erradas quando compiladas para o iOS 9. Quaisquer problemas encontrados podem ser resolvidos restringindo totalmente ou dimensionando as visualizações do selecionador para o tamanho desejado, em vez de depender do comportamento implícito.

    Eu estou trabalhando com ios 7, Xcode 5. Eu era capaz de ajustar a altura do selecionador de data indiretamente, colocando-o em uma visão. A altura das visualizações do contêiner pode ser ajustada.

    Mesmo achando que não está redimensionando, outro truque pode ajudar na situação em que o UIPicker está localizado na parte inferior da canvas.

    Pode-se tentar movê-lo levemente para baixo, mas a linha central deve permanecer visível. Isso ajudará a revelar algum espaço acima do selecionador, já que as linhas inferiores estarão fora da canvas.

    Repito que essa não é a maneira de alterar a altura da visualização do UIPicker, mas alguma idéia do que você pode fazer se todas as outras tentativas falharem.

    Ok, depois de lutar por um longo tempo com a pickerview estúpida no iOS 4, decidi mudar meu controle para uma tabela simples: aqui está o código:

     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 

    Aqui está o arquivo .h para isso:

     // // ComboBoxView.h // iTrophy // // Created by Gal Blank on 8/18/10. // #import  @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]; 

    é isso, agora a única coisa que resta é criar uma variável de membro na visualização da checkbox de combinação que manterá a seleção de linha atual, e estamos prontos para isso.

    Aproveite a todos.

    Você geralmente não pode fazê-lo no xib ou configurar o quadro de forma programática, mas se você abrir seu pai xib como fonte e alterar a altura de lá, então ele funciona.Right clique no xib dentro do qual pickerview está contido, Search pickerview e você pode encontrar altura, largura etc nessa tag, Altere a altura lá e salve o arquivo.

             

    Crie uma visão no IB ou no código. Adicione seu selecionador como uma subvisualização dessa visualização. Redimensione a exibição. Isso é mais fácil de fazer no IB. Crie restrições da vista para sua super visão e do selecionador para essa nova visão.

    Uma vez que o Picker se curva ao redor, ele se espalha pela parte superior e inferior da vista. Você pode ver no IB quando você adiciona as restrições de cima e de baixo do selecionador para a exibição, ele mostra um espaço padrão como 16 pontos acima e abaixo do contêiner da super visão. Defina a visão para cortá-lo se você não quiser esse comportamento (aviso feio).

    Aqui está o que parece em 96 pontos de altura em um iPhone 5. O selecionador com o transbordamento é de cerca de 130 pontos de altura. Muito magro!

    Estou usando isso no meu projeto para evitar que o selecionador se espalhe para uma altura desnecessária. Esta técnica reduz e força um derramamento mais apertado. Na verdade, parece mais leve para ser um pouco mais compacto.

    insira a descrição da imagem aqui

    Aqui está uma imagem da exibição mostrando o vazamento.

    insira a descrição da imagem aqui

    Aqui estão as restrições do IB que adicionei.

    insira a descrição da imagem aqui

    Tanto quanto sei, é impossível reduzir o UIPickerView. Eu também não vi um menor usado em qualquer lugar. Meu palpite é que foi uma implementação personalizada se eles conseguiram reduzi-la.

    Veja a minha resposta a esta pergunta: dimensionamento UIPicker no modo paisagem

    Se você quiser criar seu selecionador no IB, você pode pós-redimensioná-lo para um tamanho menor. Verifique se ainda desenha corretamente, pois chega um ponto em que parece hediondo.

    Swift : você precisa adicionar uma subvisualização com o clipe nos limites

      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) 

    Isso deve adicionar um selecionador de data de altura de 100 recortado na parte superior do controlador de visualização.

    Meu truque: use a camada de máscara do datepicker para tornar o datePicker alguma parte visível. como você vê, basta mudar o quadro do 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; } 

    Eu uso uma camada de máscara para alterar seu tamanho de exibição

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

    Incorporar em uma exibição de pilha. O modo de exibição de pilha é um componente adicionado recentemente pela Apple em seu SDK do iOS para refletir implementações baseadas em grade em bibliotecas front-end baseadas em web de script java, como o bootstrap.

    Depois de um longo dia coçando a cabeça, descobri algo que funciona para mim. Os códigos abaixo recriarão o UIDatePicker sempre que o usuário alterar a orientação do telefone. Isso removerá quaisquer falhas que o UIDatePicker tenha após uma mudança de orientação.

    Como estamos recriando o UIDatePicker, precisamos de uma variável de instância que mantenha o valor de data selecionado. Os códigos abaixo são testados no iOS 4.0.

      @interface AdvanceDateViewController : UIViewController { 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); 

    Se você deseja definir o tamanho do UiPickerView. O código acima certamente funcionará para você.

    No iOS 5.0, consegui o seguinte para funcionar:

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

    Isso criou um seletor de datas como o que a Apple usa no aplicativo Calendário ao criar um novo evento no modo paisagem. (3 linhas de altura em vez de 5.) Isso não funcionou quando eu definir o quadro dentro do método initWithFrame: mas até agora funciona ao configurá-lo usando um método separado.

    para iOS 5:

    se você der uma olhada rápida na referência do protocolo UIPickerView

    você encontrará

     – pickerView:rowHeightForComponent: – pickerView:widthForComponent: 

    Eu acho que é o primeiro que você está procurando