web-dev-qa-db-ja.com

UIPickerViewの高さを変更する方法

UIPickerViewの高さを変更することはできますか?一部のアプリケーションはPickerViewsが短いように見えますが、より小さいフレームを設定しても機能しないようで、フレームはInterface Builderでロックされています。

113
Steven Canfield

AppleがUIPickerViewのデフォルトの高さをいじるのを特に勧めないことは明らかなようですが、heightの変更を達成できることがわかりました完全な制御を取得し、作成時に目的のフレームサイズを渡すことによってビュー

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

さまざまな高さと幅で、視覚的な不具合があることがわかります。明らかに、これらのグリッチは何らかの方法で回避するか、それらを表示しない別のサイズを選択する必要があります。

54
danielpunkass

上記のアプローチはいずれもiOS 4.0では機能しません。

PickerViewの高さはサイズ変更できなくなりました。 4.0でピッカーのフレームを変更しようとすると、コンソールにダンプされるメッセージがあります。

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

私は、OS 3.xxとOS 4.0の両方で動作する小さなピッカーの効果を得るために、かなり急進的なことをしました。 SDKが決定するサイズにピッカーを残し、代わりにピッカーが表示される背景画像にカットスルー透明ウィンドウを作成しました。次に、背景UIImageViewの背後にピッカーを(Zオーダーごとに)配置するだけで、ピッカーの一部のみが表示され、背景の透明なウィンドウによって指示されます。

46
bhavinb

UIPickerView (162.0, 180.0 and 216.0)の有効な高さは3つだけです。

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)位置に再配置します。

43
JRSee

試してください:

pickerview.transform = CGAffineTransformMakeScale(.5, 0.5);
40
vijay adhikari

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高さの日付ピッカーにも起こります。

どちらがバグですか?あなたの推測は私のものと同じくらい良いです。

また、UIDatePicker(およびUIPickerView)162.0、180.0、および216.0には3つの有効な高さがあります。 UIPickerViewの高さを他の値に設定すると、iOSデバイスでデバッグするときにコンソールに次のように表示されます。

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

IOS 9では、UIPickerViewの幅と高さを自由に変更できます。上記の変換ハックを使用する必要はありません。

14
rounak

私はあなたがcan UIPickerViewのサイズを編集することを発見しました-インターフェースビルダーではありません。テキストエディターで.xibファイルを開き、ピッカービューのサイズを任意に設定します。インターフェイスビルダーはサイズをリセットせず、動作するようです。 Appleは何らかの理由でサイズをロックしているので、異なるサイズを試して、何が機能するかを確認する必要があります。

10

利点:

  1. UIPickerViewのsetFrameが本来の動作をするようにします
  2. UIViewController内に変換コードはありません
  3. viewWillLayoutSubviews内で機能して、UIPickerViewの再スケーリング/配置を行います。
  4. UIPopoverなしでiPadで動作します
  5. スーパークラスは常に有効な高さを受け取ります
  6. IOS 5で動作します

短所:

  1. UIPickerViewをサブクラス化する必要があります
  2. サブビューの変換を元に戻すには、pickerView viewForRowを使用する必要があります
  3. UIAnimationsが機能しない可能性があります

解決:

UIPickerViewをサブクラス化し、次のコードを使用して2つのメソッドを上書きします。サブクラス化、高さ固定、変換アプローチを組み合わせています。

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

ピッカービューの表示高さを変更する簡単な方法は、ピッカーをUIViewに埋め込み、親ビューの高さをピッカーの見たい高さに調整してから、親UIViewのInterface Builderで「Clip Subviews」を有効にすることです。または、コードでview.clipsToBounds = trueを設定します。

Clip Subviews in IB

7
svarrall

上記のアドバイスのいずれにも従うことができませんでした。

複数のチュートリアルを見て、 this oneが最も有益であることがわかりました。

次のコードを追加して、アプリで機能する「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;

これがお役に立てば幸いです!

5
erran

これはiOS 9で大きく変わりました(iOS 8では、ここで見ているものとかなり似ています)。 iOS 9のみをターゲットとする余裕がある場合は、フレームを設定することにより、UIPickerViewのサイズを適切に変更します。良い!

ここから iOS 9リリースノート

UIPickerViewとUIDatePickerはサイズ変更と適応が可能になりました。以前は、これらのビューは、サイズを変更しようとしてもデフォルトのサイズを強制していました。これらのビューは、iPhoneのデバイス幅ではなく、すべてのデバイスのデフォルトの幅が320ポイントになりました。

IOS 9用にコンパイルされた場合、デフォルトサイズの古い適用に依存するインターフェイスは間違って見える可能性があります。発生した問題は、暗黙の動作に依存するのではなく、ピッカービューを完全に制約またはサイズ変更することで解決できます。

4
Dan Rosenstark

IOS 7、Xcode 5で作業しています。日付ピッカーをビューで囲むことで、日付ピッカーの高さを間接的に調整できました。コンテナビューの高さを調整できます。

2
serverman

通常、プログラムで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>
1
iosdev1111

さて、iOS 4で愚かなpickerviewで長い間苦労していた後、私はコントロールをシンプルなテーブルに変更することにしました:ここにコードがあります:

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

それだけです。現在残っているのは、コンボボックスビューに現在の行選択を保持するメンバー変数を作成することだけです。

みんなお楽しみください。

1
Alex

サイズを変更していないと思っても、UIPickerが画面の下部にある場合に別のトリックが役立つ場合があります。

少し下に動かしてみることができますが、中央の行は表示されたままです。これにより、下の行が画面外に表示されるため、ピッカーの上のスペースが明らかになります。

これはUIPickerビューの高さを変更する方法ではなく、他のすべての試みが失敗した場合に何ができるかについてのアイデアです。

1
Sergey Lost

IBまたはコードでビューを作成します。このビューのサブビューとしてピッカーを追加します。ビューのサイズを変更します。これは、IBで行うのが最も簡単です。ビューからそのスーパービュー、およびピッカーからこの新しいビューへの制約を作成します。

ピッカーがカーブしているため、ビューの上下にピッカーが飛び出します。 IBで、ピッカーからビューに上下の制約を追加すると、スーパービューコンテナーの上下16ポイントのような標準のスペースが表示されます。この動作が望ましくない場合は、ビューをクリップするように設定します(警告)。

IPhone 5の96ポイントの高さは次のようになります。スピルオーバーのあるピッカーの高さは約130ポイントです。かなり細い!

これをプロジェクトで使用して、ピッカーが不必要な高さまで広がるのを防ぎます。この技術はそれを切り詰め、よりきつい流出を強制します。実際には少しコンパクトに見えるように見えます。

enter image description here

波及効果を示すビューの画像を次に示します。

enter image description here

追加したIB制約は次のとおりです。

enter image description here

1
smileBot

私の知る限り、UIPickerViewを縮小することは不可能です。また、実際にどこかで使用されている短いものを見たことがありません。私の推測では、もし彼らがそれをなんとか縮小できたなら、それはカスタム実装だったと思います。

0
NilObject

前述のように、UIPickerViewは現在サイズ変更可能です。ただし、tableViewセルでpickerViewの高さを変更する場合、高さアンカーを定数に設定しても成功しなかったことを付け加えます。ただし、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)
     }

 }
0
MH175

この質問に対する私の答えを参照してください: IPickerの横長モードでのサイジング

0
Can Berk Güder

マスクレイヤーを使用して表示サイズを変更します

// 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
0
John Lee

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)

これにより、View Controllerの上部に、高さ100のクリップされた日付ピッカーが追加されます。

0
Miika Pakarinen

IBでピッカーを作成したい場合は、それを後のサイズに変更することができます。しかし、それが凶暴に見えるポイントが来るので、それがまだ正しく描画することを確認してください。

0
Rob Winchester

私の秘:: 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;
}
0
frank

スタックビューに埋め込みます。スタックビューは、iOS SDKのAppleによって最近追加されたコンポーネントで、ブートストラップなどのWebベースのフロントエンドライブラリJavaのグリッドベースの実装を反映します。

0
user5590043