Как изменить высоту UIPickerView


можно ли изменить высоту UIPickerView? Некоторые приложения, похоже, имеют более короткие PickerViews, но установка меньшего фрейма, похоже, не работает, и фрейм заблокирован в Interface Builder.

27 111

27 ответов:

Кажется очевидным, что Apple не особенно приглашает mucking с высотой по умолчанию 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 порядок мудрый) мой фон 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];

у меня есть приложение в AppStore с 3 строку выбора даты. Я думал, что изменение высоты, возможно, было предотвращено, потому что вы видите текст под границей выбора даты, но это происходит и с обычным выбором даты высоты 216.

что это за ошибка? Ваша догадка так же хороша, как и моя.

также есть 3 допустимые высоты для UIDatePickerUIPickerView) 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

начиная с iOS 9, вы можете свободно менять UIPickerView's ширина и высота. Нет необходимости использовать вышеупомянутые хаки преобразования.

Я обнаружил, что вы can изменить размер UIPickerView-просто не с помощью interface builder. открывай .xib-файл с текстовым редактором и установите размер представления выбора на все, что вы хотите. Interface builder не сбрасывает размер и, похоже, работает. Я уверен, что apple заблокировала размер по какой-то причине, поэтому вам придется экспериментировать с разными размерами, чтобы увидеть, что работает.

плюсы:

  1. делает setFrame из UIPickerView ведите себя как следует
  2. нет кода преобразования в вашем UIViewController
  3. работает в viewWillLayoutSubviews для масштабирования / позиционирования UIPickerView
  4. работает на iPad без UIPopover
  5. суперкласс всегда получает допустимую высоту
  6. работает с iOS 5

недостатки:

  1. требуется подкласс UIPickerView
  2. требует использования pickerView viewForRow чтобы отменить преобразование для подпанелей
  3. UIAnimations может не работать

устранение:

подкласс 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 in IB

Я не смог следовать ни одному из вышеперечисленных советов.

Я смотрел несколько учебников и нашли этой один из самых полезных:

Я добавил следующий код, чтобы установить новую высоту внутри метода "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 точек на всех устройствах, а не к ширине устройства на айфон.

интерфейсы, которые полагаются на старое применение размера по умолчанию, будут вероятно, выглядеть неправильно при компиляции для iOS 9. Любые возникшие проблемы может быть разрешен путем полного ограничения или изменения размеров представлений выбора нужного размера вместо того, чтобы полагаться на неявное поведение.

Я работаю с ios 7, Xcode 5. Я смог настроить высоту выбора даты косвенно, заключив его в представление. Высоту видов контейнеров можно регулировать.

даже думал, что это не изменение размера, другой трюк может помочь в ситуации, когда UIPicker находится в нижней части экрана.

можно попробовать переместить его немного вниз, но центральная строка должна оставаться видимой. Это поможет выявить некоторое пространство над сборщиком, так как нижние строки будут за кадром.

Я повторяю, что это не способ изменения высоты uipicker view, но некоторая идея о том, что вы можете сделать, если все остальные попытки потерпят неудачу.

ОК, после долгой борьбы с глупым pickerview в 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>

создать представление В IB или коде. Добавьте средство выбора в качестве подвида этого представления. Изменить мнение. Это проще всего сделать в IB. Создайте ограничения от представления к его супервизору и от средства выбора к этому новому представлению.

Так как выбор кривых вокруг него разливается по верхней и нижней части вида. Вы можете видеть в IB, когда вы добавляете верхние и нижние ограничения из средства выбора в представление, оно показывает стандартное пространство примерно на 16 точек выше и ниже контейнера superview. Набор вид, чтобы обрезать его, если вы не хотите такого поведения (уродливое предупреждение).

вот как это выглядит на 96 точек выше на iPhone 5. Подборщик с переливом составляет около 130 баллов. Довольно тощий!

Я использую это в своем проекте, чтобы предотвратить распространение сборщика на ненужную высоту. Этот метод уравновешивает его вниз и принуждает более плотный расслоину сверх. Это на самом деле выглядит дождевик, чтобы быть немного более компактным.

enter image description here

вот изображение показывает перелив.

enter image description here

вот ограничения IB, которые я добавил.

enter image description here

насколько я знаю, невозможно уменьшить UIPickerView. Я также на самом деле не видел более короткого, используемого где-либо. Я предполагаю, что это была пользовательская реализация, если им удалось ее сжать.

смотрите мой ответ на этот вопрос: UIPicker размеров в ландшафтном режиме

Если вы хотите создать свой выбор в IB, вы можете изменить его размер до меньшего размера. Проверьте, чтобы убедиться, что он по-прежнему рисует правильно, хотя, как наступает момент, когда он выглядит отвратительно.

Свифт: вам нужно добавить подвид с клипом в границы

    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 маски, чтобы отмечать какую-то часть видимого. как вы видите, так же, как изменить кадр 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;
}

Я использую слой маски, чтобы изменить его размер отображения

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

встроить в представление стека. Stack view-это компонент, недавно добавленный Apple в свой iOS SDK для отражения реализаций на основе сетки в интерфейсных библиотеках java script, таких как bootstrap.

после долгого дня чесалась голова, я нашел то, что работает для меня. Ниже коды будут воссоздавать 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. Выше код, безусловно, будет работать для u.

в 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:

Если вы взглянем на!--4-->Протокол UIPickerView ссылка

вы можете найти

– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:

Я думаю, что это первый, который вы ищете