Чи можливо змінити висоту UIPickerView? Деякі програми, здається, мають більш короткі PickerView, але, здається, встановлення меншого кадру не працює, і кадр заблокований у Interface Builder.
Чи можливо змінити висоту UIPickerView? Деякі програми, здається, мають більш короткі PickerView, але, здається, встановлення меншого кадру не працює, і кадр заблокований у 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
Я в кінцевому підсумку робив щось досить радикальне, щоб отримати ефект меншого вибору, який працює як в ОС 3.xx, так і в ОС 4.0. Я залишив вибирач будь-якого розміру, SDK вирішив, що він має бути, і замість цього зробив прозоре прозоре вікно на моєму фоновому зображенні, через яке вибирач стає видимим. Потім просто помістив вибирач позаду (Z Order Мудрий) мій фон 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));
Вищевказаний код змінює висоту вибору вибору на половину і переставляє його в точне (лівий-x1, верхній-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];
У мене є додаток, який знаходиться в магазині додатків із засобом вибору дати 3 рядка. Я подумав, що зміна висоти може бути запобіжена, оскільки ви бачите текст під межею вибору дати, але це трапляється і зі звичайним вибором дат 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 за допомогою текстового редактора та встановіть розмір вибору вибору у будь-який момент, що вам потрібно. Інтерфейс-конструктор не скидає розмір і, здається, працює. Я впевнений, що яблуко заблокувало розмір чомусь, тому вам доведеться експериментувати з різними розмірами, щоб побачити, що працює.
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, коли ви додаєте обмеження верхнього та нижнього пунктів від вибору до виду, він показує стандартний простір, подібний до 16 точок вище та нижче контейнера для перегляду. Встановіть вигляд, щоб вирізати його, якщо ви не хочете такої поведінки (потворне попередження).
Ось як це виглядає на 96 балів у iPhone 5. Вибір з переливом становить близько 130 балів. Досить худий!
Я використовую це у своєму проекті, щоб запобігти розповсюдженню на непотрібну висоту. Ця техніка скорочує її і змушує більш сильно пролитись. Це насправді стрункіше, щоб бути трохи більш компактним.
Ось зображення виду, що показує перелив.
Ось обмеження, які я додав.
Навіть думаючи, що він не змінює розмір, ще одна хитрість може допомогти в ситуації, коли 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];
це все, тепер залишається лише створити змінну членів у вікні комбінації, яка буде містити поточний вибір рядків, і нам добре піти.
Радують усіх.
Як правило, це не можна зробити в xib або встановити кадр програмно, але якщо ви відкриєте його батьківський xib як джерело і зміните висоту звідти, то він працює. у цьому тезі, Змініть там висоту, а потім збережіть файл.
<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 у свій iOS SDK для відображення сіткових реалізацій у веб-бібліотеках переднього кінця 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
У 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 Reference
ти знайдеш
– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
Я думаю, це перший, який ти шукаєш
pickerView:rowHeightForComponent:
- це метод делегування для визначення висоти кожного ряду, а не висоти вибору вибору.