UIPickerViewの高さを変更することはできますか?一部のアプリケーションはPickerViewsが短いように見えますが、より小さいフレームを設定しても機能しないようで、フレームはInterface Builderでロックされています。
AppleがUIPickerView
のデフォルトの高さをいじるのを特に勧めないことは明らかなようですが、heightの変更を達成できることがわかりました完全な制御を取得し、作成時に目的のフレームサイズを渡すことによってビュー
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が決定するサイズにピッカーを残し、代わりにピッカーが表示される背景画像にカットスルー透明ウィンドウを作成しました。次に、背景UIImageViewの背後にピッカーを(Zオーダーごとに)配置するだけで、ピッカーの一部のみが表示され、背景の透明なウィンドウによって指示されます。
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)位置に再配置します。
試してください:
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高さの日付ピッカーにも起こります。
どちらがバグですか?あなたの推測は私のものと同じくらい良いです。
また、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
IOS 9では、UIPickerView
の幅と高さを自由に変更できます。上記の変換ハックを使用する必要はありません。
私はあなたがcan UIPickerViewのサイズを編集することを発見しました-インターフェースビルダーではありません。テキストエディターで.xibファイルを開き、ピッカービューのサイズを任意に設定します。インターフェイスビルダーはサイズをリセットせず、動作するようです。 Appleは何らかの理由でサイズをロックしているので、異なるサイズを試して、何が機能するかを確認する必要があります。
UIPickerView
のsetFrameが本来の動作をするようにしますUIViewController
内に変換コードはありませんviewWillLayoutSubviews
内で機能して、UIPickerView
の再スケーリング/配置を行います。UIPopover
なしでiPadで動作しますUIPickerView
をサブクラス化する必要がありますpickerView viewForRow
を使用する必要があります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;
}
ピッカービューの表示高さを変更する簡単な方法は、ピッカーをUIViewに埋め込み、親ビューの高さをピッカーの見たい高さに調整してから、親UIViewのInterface Builderで「Clip Subviews」を有効にすることです。または、コードでview.clipsToBounds = true
を設定します。
上記のアドバイスのいずれにも従うことができませんでした。
複数のチュートリアルを見て、 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;
これがお役に立てば幸いです!
これはiOS 9で大きく変わりました(iOS 8では、ここで見ているものとかなり似ています)。 iOS 9のみをターゲットとする余裕がある場合は、フレームを設定することにより、UIPickerView
のサイズを適切に変更します。良い!
ここから iOS 9リリースノート
UIPickerViewとUIDatePickerはサイズ変更と適応が可能になりました。以前は、これらのビューは、サイズを変更しようとしてもデフォルトのサイズを強制していました。これらのビューは、iPhoneのデバイス幅ではなく、すべてのデバイスのデフォルトの幅が320ポイントになりました。
IOS 9用にコンパイルされた場合、デフォルトサイズの古い適用に依存するインターフェイスは間違って見える可能性があります。発生した問題は、暗黙の動作に依存するのではなく、ピッカービューを完全に制約またはサイズ変更することで解決できます。
IOS 7、Xcode 5で作業しています。日付ピッカーをビューで囲むことで、日付ピッカーの高さを間接的に調整できました。コンテナビューの高さを調整できます。
通常、プログラムで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>
さて、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];
それだけです。現在残っているのは、コンボボックスビューに現在の行選択を保持するメンバー変数を作成することだけです。
みんなお楽しみください。
サイズを変更していないと思っても、UIPickerが画面の下部にある場合に別のトリックが役立つ場合があります。
少し下に動かしてみることができますが、中央の行は表示されたままです。これにより、下の行が画面外に表示されるため、ピッカーの上のスペースが明らかになります。
これはUIPickerビューの高さを変更する方法ではなく、他のすべての試みが失敗した場合に何ができるかについてのアイデアです。
IBまたはコードでビューを作成します。このビューのサブビューとしてピッカーを追加します。ビューのサイズを変更します。これは、IBで行うのが最も簡単です。ビューからそのスーパービュー、およびピッカーからこの新しいビューへの制約を作成します。
ピッカーがカーブしているため、ビューの上下にピッカーが飛び出します。 IBで、ピッカーからビューに上下の制約を追加すると、スーパービューコンテナーの上下16ポイントのような標準のスペースが表示されます。この動作が望ましくない場合は、ビューをクリップするように設定します(警告)。
IPhone 5の96ポイントの高さは次のようになります。スピルオーバーのあるピッカーの高さは約130ポイントです。かなり細い!
これをプロジェクトで使用して、ピッカーが不必要な高さまで広がるのを防ぎます。この技術はそれを切り詰め、よりきつい流出を強制します。実際には少しコンパクトに見えるように見えます。
波及効果を示すビューの画像を次に示します。
追加したIB制約は次のとおりです。
私の知る限り、UIPickerViewを縮小することは不可能です。また、実際にどこかで使用されている短いものを見たことがありません。私の推測では、もし彼らがそれをなんとか縮小できたなら、それはカスタム実装だったと思います。
前述のように、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)
}
}
この質問に対する私の答えを参照してください: IPickerの横長モードでのサイジング
マスクレイヤーを使用して表示サイズを変更します
// 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
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のクリップされた日付ピッカーが追加されます。
IBでピッカーを作成したい場合は、それを後のサイズに変更することができます。しかし、それが凶暴に見えるポイントが来るので、それがまだ正しく描画することを確認してください。
私の秘:: 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;
}
スタックビューに埋め込みます。スタックビューは、iOS SDKのAppleによって最近追加されたコンポーネントで、ブートストラップなどのWebベースのフロントエンドライブラリJavaのグリッドベースの実装を反映します。