¿Es posible cambiar la altura de UIPickerView? Algunas aplicaciones parecen tener PickerViews más cortos, pero establecer un marco más pequeño no parece funcionar y el marco está bloqueado en Interface Builder.
¿Es posible cambiar la altura de UIPickerView? Algunas aplicaciones parecen tener PickerViews más cortos, pero establecer un marco más pequeño no parece funcionar y el marco está bloqueado en Interface Builder.
Respuestas:
Parece obvio que Apple no invita particularmente a limpiar con la altura predeterminada de la UIPickerView
, pero he descubierto que puede lograr un cambio en la altura de la vista tomando el control completo y pasando un tamaño de fotograma deseado en el momento de la creación, por ejemplo:
smallerPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)];
Descubrirá que en varias alturas y anchos, hay fallas visuales. Obviamente, estos fallos tendrían que solucionarse de alguna manera o elegir otro tamaño que no los presente.
Ninguno de los enfoques anteriores funciona en iOS 4.0
La altura de pickerView ya no es redimensionable. Hay un mensaje que se descarga a la consola si intenta cambiar el marco de un selector en 4.0:
-[UIPickerView setFrame:]: invalid height value 66.0 pinned to 162.0
Terminé haciendo algo bastante radical para obtener el efecto de un selector más pequeño que funciona tanto en OS 3.xx como en OS 4.0. Dejé que el selector tuviera el tamaño que el SDK decida que debería ser y, en su lugar, hice una ventana transparente de corte en mi imagen de fondo a través de la cual el selector se vuelve visible. Luego, simplemente coloque el selector detrás (orden Z) de mi UIImageView de fondo para que solo una parte del selector sea visible, lo que está dictado por la ventana transparente en mi fondo.
Solo hay tres alturas válidas para UIPickerView (162.0, 180.0 and 216.0)
.
Puede utilizar las funciones CGAffineTransformMakeTranslation
y CGAffineTransformMakeScale
para ajustar correctamente el selector a su conveniencia.
Ejemplo:
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));
El código anterior cambia la altura de la vista del selector a la mitad y la vuelve a colocar en la posición exacta (Izquierda-x1, Arriba-y1) .
Tratar:
pickerview.transform = CGAffineTransformMakeScale(.5, 0.5);
En iOS 4.2 y 4.3 funciona lo siguiente:
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.frame = CGRectMake(0, 0, 320, 180);
[self addSubview:datePicker];
Lo siguiente no funciona:
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 320, 180)];
[self addSubview:datePicker];
Tengo una aplicación que está en la tienda de aplicaciones con un selector de fecha de 3 líneas. Pensé que el cambio de altura podría haberse evitado porque ve el texto debajo del borde del selector de fecha, pero esto también le sucede al selector de fecha de altura 216 normal.
Cual es el error? Tu invitado es tan bueno como el mío.
También hay 3 alturas válidas para UIDatePicker
(y UIPickerView
) 162.0, 180.0 y 216.0. Si establece una UIPickerView
altura para cualquier otra cosa, verá lo siguiente en la consola al depurar en un dispositivo iOS.
2011-09-14 10:06:56.180 DebugHarness[1717:707] -[UIPickerView setFrame:]: invalid height value 300.0 pinned to 216.0
Descubrí que puede editar el tamaño de UIPickerView, pero no con el generador de interfaces. abra el archivo .xib con un editor de texto y establezca el tamaño de la vista del selector como desee. El generador de interfaces no restablece el tamaño y parece funcionar. Estoy seguro de que Apple bloqueó el tamaño por una razón, así que tendrás que experimentar con diferentes tamaños para ver qué funciona.
UIPickerView
comporte como deberíaUIViewController
viewWillLayoutSubviews
para cambiar la escala / posicionarUIPickerView
UIPopover
UIPickerView
pickerView viewForRow
para deshacer la transformación de las subVistasSubclase UIPickerView y sobrescriba los dos métodos usando el siguiente código. Combina subclases, altura fija y el enfoque de transformación.
#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;
}
Una manera fácil de cambiar la altura visible de una vista de selector es incrustar el selector en una vista UIView, ajustar la altura de la vista principal a la altura que desea ver del selector y luego habilitar "Subvistas de clip" en Interface Builder en la vista UIView principal o establecido view.clipsToBounds = true
en código.
Clip Subviews
. también el tamaño del UIPickerView
debe ser más alto, y debe apuntar el centro de su UIPickerView
para que sea visible dentro del padreUIView
UIPickerView
partir del código).
No pude seguir ninguno de los consejos anteriores.
Vi varios tutoriales y encontré este el más beneficioso:
Agregué el siguiente código para establecer la nueva altura dentro del método "viewDidLoad", que funcionó en mi aplicación.
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 esto haya sido útil!
Esto ha cambiado mucho en iOS 9 (en iOS 8 es bastante similar a lo que estamos viendo aquí). Si puede permitirse apuntar solo a iOS 9, cambie el tamaño delUIPickerView
como mejor le parezca, configurando su marco. ¡Bueno!
Aquí está de las notas de la versión de iOS 9
UIPickerView y UIDatePicker ahora son redimensionables y adaptables; anteriormente, estas vistas imponían un tamaño predeterminado incluso si intentaba redimensionarlas. Estas vistas ahora también tienen un ancho predeterminado de 320 puntos en todos los dispositivos, en lugar del ancho del dispositivo en el iPhone.
Las interfaces que se basan en la aplicación anterior del tamaño predeterminado probablemente se verán mal cuando se compilen para iOS 9. Cualquier problema que se encuentre se puede resolver restringiendo completamente o dimensionando las vistas del selector al tamaño deseado en lugar de depender de un comportamiento implícito.
Estoy trabajando con ios 7, Xcode 5. Pude ajustar la altura del selector de fecha indirectamente encerrándolo en una vista. La altura de las vistas del contenedor se puede ajustar.
Cree una vista en IB o código. Agregue su selector como una subvista de esta vista. Cambiar el tamaño de la vista. Esto es más fácil de hacer en IB. Cree restricciones desde la vista a su supervista y desde el selector a esta nueva vista.
Dado que el selector se curva a su alrededor, se extiende por la parte superior e inferior de la vista. Puede ver en IB cuando agrega restricciones superior e inferior desde el selector a la vista, muestra un espacio estándar de algo así como 16 puntos por encima y por debajo del contenedor de supervista. Configure la vista para recortarla si no desea este comportamiento (advertencia fea).
Así es como se ve a 96 puntos de altura en un iPhone 5. El selector con el desbordamiento tiene aproximadamente 130 puntos de altura. ¡Bastante flaco!
Estoy usando esto en mi proyecto para evitar que el selector se extienda a una altura innecesaria. Esta técnica lo recorta y fuerza un derrame más apretado. En realidad, parece más elegante para ser un poco más compacto.
Aquí hay una imagen de la vista que muestra el desbordamiento.
Aquí están las restricciones de IB que agregué.
Incluso aunque no esté cambiando el tamaño, otro truco puede ayudar en la situación en la que el UIPicker se encuentra en la parte inferior de la pantalla.
Se puede intentar moverlo ligeramente hacia abajo, pero la fila central debe permanecer visible. Esto ayudará a revelar algo de espacio sobre el selector, ya que las filas inferiores estarán fuera de la pantalla.
Repito que esta no es la forma de cambiar la altura de la vista de UIPicker, sino una idea de lo que puede hacer si todos los demás intentos fallan.
Ok, después de luchar durante mucho tiempo con la estúpida vista del selector en iOS 4, he decidido cambiar mi control a una tabla simple: aquí está el 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
Aquí está el archivo .h para eso:
//
// 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];
eso es todo, ahora lo único que queda es crear una variable miembro en la vista del cuadro combinado que contendrá la selección de fila actual, y estamos listos para comenzar.
Disfruten a todos.
Por lo general, no puede hacerlo en xib o configurar el marco programáticamente, pero si abre su xib principal como fuente y cambia la altura desde allí, entonces funciona. en esa etiqueta, cambie la altura allí y luego guarde el archivo.
<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>
Hasta donde yo sé, es imposible encoger el UIPickerView. Tampoco he visto uno más corto usado en ninguna parte. Supongo que fue una implementación personalizada si lograron reducirla.
Si desea crear su selector en IB, puede redimensionarlo posteriormente a un tamaño más pequeño. Sin embargo, asegúrese de que todavía se dibuja correctamente, ya que llega un punto en el que se ve atroz.
Swift : debe agregar una subvista con clip a límites
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)
Esto debería agregar un selector de fecha recortado de 100 alturas en la parte superior del controlador de vista.
Mi truco: use la capa de máscara de datepicker para hacer que datePicker sea visible en alguna parte. como ves, como cambiar el marco del 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;
}
Incrustar en una vista de pila. La vista de pila es un componente agregado recientemente por Apple en su SDK de iOS para reflejar implementaciones basadas en cuadrículas en bibliotecas frontales basadas en web de scripts java, como bootstrap.
Como se mencionó anteriormente, UIPickerView
ahora es redimensionable. Sin embargo, solo quiero agregar que si desea cambiar la altura de pickerView en una celda de tableView, no tuve ningún éxito al establecer el ancla de altura en una constante. Sin embargo, el uso lessThanOrEqualToConstant
parece funcionar.
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)
}
}
Después de un largo día de rascarme la cabeza, encontré algo que funciona para mí. Los códigos a continuación volverán a crear el UIDatePicker cada vez que el usuario cambie la orientación del teléfono. Esto eliminará cualquier problema técnico que tenga el UIDatePicker después de un cambio de orientación.
Dado que estamos recreando el UIDatePicker, necesitamos una variable de instancia que mantendrá el valor de fecha seleccionado. Los siguientes códigos se prueban en 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
stockPicker = [[UIPickerView alloc] init];
stockPicker.frame = CGRectMake(70.0,155, 180,100);
Si desea establecer el tamaño de UiPickerView. El código anterior seguramente funcionará para ti.
En iOS 5.0, conseguí que funcionara lo siguiente:
UIDatePicker *picker = [[UIDatePicker alloc] init];
picker.frame = CGRectMake(0.0, 0.0, 320.0, 160.0);
Esto creó un selector de fecha como el que usa Apple en la aplicación Calendario al crear un nuevo evento en modo horizontal. (3 filas de altura en lugar de 5.) Esto no funcionó cuando configuré el marco dentro del initWithFrame:
método, pero hasta ahora funciona cuando lo configuré usando un método separado.
para iOS 5:
si echa un vistazo rápido al protocolo UIPickerView Referencia
encontrarás
– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
Creo que es el primero que estás buscando
pickerView:rowHeightForComponent:
es el método delegado para decidir la altura de cada fila, no la altura de la vista del selector.