Можно ли изменить высоту UIPickerView? Некоторые приложения, кажется, имеют более короткие PickerViews, но установка меньшего фрейма не работает, и фрейм заблокирован в Interface Builder.
Можно ли изменить высоту UIPickerView? Некоторые приложения, кажется, имеют более короткие PickerViews, но установка меньшего фрейма не работает, и фрейм заблокирован в Interface Builder.
Ответы:
Кажется очевидным, что Apple особо не предлагает убирать с высотой по умолчанию UIPickerView
, но я обнаружил, что вы можете добиться изменения высоты представления, взяв полный контроль и передав желаемый размер кадра во время создания, например:
smallerPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)];
Вы обнаружите, что на разной высоте и ширине наблюдаются визуальные глюки. Очевидно, эти глюки нужно было либо как-то устранить, либо выбрать другой размер, который их не проявляет.
Ни один из вышеперечисленных подходов не работает в 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, чтобы была видна только часть средства выбора, что определяется прозрачным окном на моем фоне.
Есть только три допустимые высоты для UIPickerView (162.0, 180.0 and 216.0)
.
Вы можете использовать CGAffineTransformMakeTranslation
иCGAffineTransformMakeScale
функцию должным образом соответствовать подборщику для вашего удобства.
Пример:
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) .
Пытаться:
pickerview.transform = CGAffineTransformMakeScale(.5, 0.5);
В 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];
У меня есть приложение, которое находится в магазине приложений с трехстрочным выбором даты. Я думал, что изменение высоты могло быть предотвращено, потому что вы видите текст под рамкой средства выбора даты, но это также происходит и с обычным средством выбора даты высотой 216.
Какая ошибка? Твоя догадка так же хороша как и моя.
Также есть 3 допустимые высоты для UIDatePicker
(и UIPickerView
) 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
Я обнаружил, что вы можете редактировать размер UIPickerView - но не с помощью построителя интерфейса. откройте файл .xib с помощью текстового редактора и установите любой размер окна выбора. Конструктор интерфейсов не сбрасывает размер и вроде работает. Я уверен, что Apple заблокировала размер не зря, поэтому вам придется поэкспериментировать с разными размерами, чтобы увидеть, что работает.
UIPickerView
вести себя так, как должноUIViewController
viewWillLayoutSubviews
для изменения масштаба / положенияUIPickerView
UIPopover
UIPickerView
pickerView viewForRow
чтобы отменить преобразование для вложенных представленийПодкласс 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;
}
Простой способ изменить видимую высоту представления средства выбора - встроить средство выбора в UIView, отрегулировать высоту родительского представления до высоты, которую вы хотите видеть в средстве выбора, а затем включить «Вырезать подпредставления» в Interface Builder на родительском UIView. или установить view.clipsToBounds = true
в коде.
Clip Subviews
. также размер UIPickerView
должен быть выше - и вы должны нацелить центр вашего, UIPickerView
чтобы быть видимым внутри родителяUIView
UIPickerView
из кода).
Я не смог последовать ни одному из приведенных выше советов.
Я просмотрел несколько руководств и нашел это наиболее полезным:
Я добавил следующий код, чтобы установить новую высоту внутри метода "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;
Надеюсь, это было полезно!
Это сильно изменилось в iOS 9 (в iOS 8 это очень похоже на то, что мы видим здесь). Если вы можете позволить себе настроить таргетинг только на iOS 9, измените размерUIPickerView
своему усмотрению, установив его рамку. Хорошо!
Вот это из примечаний к выпуску iOS 9
UIPickerView и UIDatePicker теперь могут изменять размер и адаптироваться - ранее эти представления обеспечивали размер по умолчанию, даже если вы пытались изменить их размер. Эти представления также теперь по умолчанию имеют ширину 320 точек на всех устройствах, а не ширину устройства на iPhone.
Интерфейсы, которые полагаются на старое применение размера по умолчанию, скорее всего, будут выглядеть неправильно при компиляции для iOS 9. Любые возникающие проблемы могут быть решены путем полного ограничения или изменения размеров представлений средства выбора до желаемого размера вместо того, чтобы полагаться на неявное поведение.
Я работаю с ios 7, Xcode 5. Мне удалось косвенно настроить высоту средства выбора даты, включив его в представление. Высота просмотров контейнера может регулироваться.
Создайте представление в IB или коде. Добавьте средство выбора в качестве подвида этого представления. Измените размер представления. Проще всего это сделать в IB. Создайте ограничения от представления к его супервизору и от средства выбора к этому новому представлению.
Поскольку инструмент выбора изгибается вокруг него, он выходит за верхнюю и нижнюю границы представления. Вы можете видеть в IB, когда вы добавляете верхние и нижние ограничения из средства выбора в представление, оно показывает стандартное пространство примерно на 16 точек выше и ниже контейнера супервизора. Установите вид, чтобы обрезать его, если вы не хотите такого поведения (уродливое предупреждение).
Вот как это выглядит при высоте 96 пунктов на iPhone 5. Высота пикера с перетеканием составляет около 130 пунктов. Довольно худая!
Я использую это в своем проекте, чтобы сборщик не растягивался на ненужную высоту. Этот метод обрезает его и заставляет более плотное перетекать. На самом деле он выглядит немного компактнее.
Вот изображение вида, показывающее перетекание.
Вот ограничения IB, которые я добавил.
Даже если это не изменение размера, еще одна уловка может помочь в ситуации, когда UIPicker расположен в нижней части экрана.
Можно попробовать сдвинуть его немного вниз, но центральный ряд должен оставаться видимым. Это поможет открыть некоторое пространство над средством выбора, поскольку нижние строки будут за пределами экрана.
Я повторяю, что это не способ изменить высоту представления UIPicker, а некоторое представление о том, что вы можете сделать, если все другие попытки потерпят неудачу.
Хорошо, после долгой борьбы с глупым выбором в iOS 4, я решил изменить свой элемент управления на простую таблицу: вот код:
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];
вот и все, теперь осталось только создать переменную-член в представлении combobox, которая будет содержать текущий выбор строки, и мы готовы к работе.
Всем нравится.
Обычно вы не можете сделать это в xib или программно настроить фрейм, но если вы откроете его родительский xib в качестве источника и измените высоту оттуда, тогда он будет работать. Щелкните правой кнопкой мыши xib, в котором содержится pickerview, найдите 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>
Насколько мне известно, UIPickerView невозможно сжать. Я также нигде не видел более коротких. Я предполагаю, что это была индивидуальная реализация, если им удалось ее уменьшить.
Если вы хотите создать свой сборщик в IB, вы можете изменить его размер до меньшего размера. Убедитесь, что он по-прежнему правильно рисует, так как наступает момент, когда он выглядит ужасно.
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 в верхней части контроллера представления.
Мой трюк: используйте слой маски 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;
}
Вставить в стек. Представление стека - это компонент, недавно добавленный Apple в их SDK для iOS, для отражения реализаций на основе сетки в интерфейсных веб-библиотеках java-скриптов, таких как bootstrap.
Как упоминалось выше UIPickerView
, теперь можно изменять размер. Я просто хочу добавить, что если вы хотите изменить высоту pickerView в ячейке tableView, мне не удалось установить привязку высоты к константе. Однако использование, 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)
}
}
После долгого дня чесания в затылке я нашел кое-что, что мне подходит. Приведенные ниже коды воссоздают 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
stockPicker = [[UIPickerView alloc] init];
stockPicker.frame = CGRectMake(70.0,155, 180,100);
Если вы хотите установить размер UiPickerView. Приведенный выше код наверняка сработает для вас.
В iOS 5.0 у меня работало следующее:
UIDatePicker *picker = [[UIDatePicker alloc] init];
picker.frame = CGRectMake(0.0, 0.0, 320.0, 160.0);
Это создало средство выбора даты, подобное тому, которое Apple использует в приложении «Календарь» при создании нового события в ландшафтном режиме. (3 строки в высоту вместо 5.) Это не сработало, когда я установил рамку в initWithFrame:
методе, но пока работает при установке ее отдельным методом.
для iOS 5:
если вы быстро взглянете на протокол UIPickerView Справочник по
ты найдешь
– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
Я думаю, это первое, что ты ищешь
pickerView:rowHeightForComponent:
- это метод делегата, определяющий высоту каждой строки, а не высоту окна выбора.