アプリケーションの現在の高さと幅をプログラムで決定しようとしています。私はこれを使います:
CGRect screenRect = [[UIScreen mainScreen] bounds];
ただし、デバイスの向きが縦向きか横向きかに関係なく、幅320と高さ480になります。メイン画面の現在の幅と高さ(つまり、デバイスの向きに依存)を確認するにはどうすればよいですか?
アプリケーションの現在の高さと幅をプログラムで決定しようとしています。私はこれを使います:
CGRect screenRect = [[UIScreen mainScreen] bounds];
ただし、デバイスの向きが縦向きか横向きかに関係なく、幅320と高さ480になります。メイン画面の現在の幅と高さ(つまり、デバイスの向きに依存)を確認するにはどうすればよいですか?
回答:
のようなものUIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)を使用して方向を決定し、それに応じて寸法を使用できます。
ただし、UIViewControllerのような方向変更中
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
toInterfaceOrientationUIApplicationのstatusBarOrientationはまだ変更されていないので(willイベントハンドラー内にいるため)古い方向を指すため、渡された方向を使用します。
概要
これにはいくつかの関連する投稿がありますが、それらのそれぞれはあなたがしなければならないことを示しているようです:
[[UIScreen mainScreen] bounds]て寸法を取得し、リンク集
作業コード
私は通常ここまで行かないが、あなたは私の興味をそそった。次のコードでうまくいくはずです。UIApplicationにカテゴリを作成しました。currentSizeまたは特定の方向のサイズを取得するためのクラスメソッドを追加しました。これは、UIViewControllerで呼び出すものですwillRotateToInterfaceOrientation:duration:。
@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end
@implementation UIApplication (AppDimensions)
+(CGSize) currentSize
{
return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
@end
コードを使用するには、単純な呼び出し[UIApplication currentSize]。また、上記のコードを実行したので、それが機能し、すべての方向で正しい応答を報告します。ステータスバーを考慮することに注意してください。興味深いことに、ステータスバーの高さと幅のMINを引く必要がありました。
お役に立てれば。:D
他の考え
UIWindowのrootViewControllerプロパティを確認することで、寸法を取得できます。私は過去にこれを見てきましたが、回転変換があることを報告することを除いて、縦と横の両方で同じ寸法を同様に報告します:
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] view]
<UILayoutContainerView:0xf7296f0; フレーム=(0 0; 320 480); 変換= [0、-1、1、0、0、0]; 自動サイズ変更= W + H; レイヤー= <CALayer:0xf729b80 >>
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] view]
<UILayoutContainerView:0xf7296f0; フレーム=(0 0; 320 480); 自動サイズ変更= W + H; レイヤー= <CALayer:0xf729b80 >>
アプリの動作はわかりませんが、何らかのナビゲーションコントローラーを使用していない場合は、メインビューの下に親の最大の高さ/幅を持つUIViewを配置し、親とともに拡大/縮小することができます。次に、次のことができます[[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame]。それは一行でかなり強そうに見えますが、あなたはアイデアを得ます。
しかし...要約の下で上記の3つのステップを実行する方が良いでしょう。UIWindowsをいじってみると、UIAlertViewがUIApplicationのキーウィンドウを変更して、UIAlertViewが作成した新しいUIWindowを指すようにするなど、奇妙なことがわかります。誰かわかったね?keyWindowに依存するバグを見つけ、それがそのように変化したことを発見した後、私はそうしました!
applicationFrame代わりにbounds(UIScreen上で)を使用する場合は、ステータスバーの高さを減算する必要はありません。
mainScreen().bounds.sizeは、iOS 8以降の方向に依存するようになりました
これが私のソリューションコードです!このメソッドはNSObjectクラスのCategroyに追加できます。または、トップカスタムUIViewControllerクラスを定義して、他のすべてのUIViewControllersにそれを継承させることができます。
-(CGRect)currentScreenBoundsDependOnOrientation
{
CGRect screenBounds = [UIScreen mainScreen].bounds ;
CGFloat width = CGRectGetWidth(screenBounds) ;
CGFloat height = CGRectGetHeight(screenBounds) ;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
screenBounds.size = CGSizeMake(width, height);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
screenBounds.size = CGSizeMake(height, width);
}
return screenBounds ;
}
注意 IOS8後、として、UIScreenのboundsプロパティのアップルドキュメントは言います:
討論
この長方形は現在の座標空間で指定され、デバイスに有効なインターフェースの回転を考慮に入れます。したがって、デバイスが縦向きと横向きの間で回転すると、このプロパティの値が変わる可能性があります。
互換性を考慮して、IOSバージョンを検出し、次のように変更する必要があります。
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
-(CGRect)currentScreenBoundsDependOnOrientation
{
CGRect screenBounds = [UIScreen mainScreen].bounds ;
if(IsIOS8){
return screenBounds ;
}
CGFloat width = CGRectGetWidth(screenBounds) ;
CGFloat height = CGRectGetHeight(screenBounds) ;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
screenBounds.size = CGSizeMake(width, height);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
screenBounds.size = CGSizeMake(height, width);
}
return screenBounds ;
}
ここに便利なマクロがあります:
#define SCREEN_WIDTH (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)
#define SCREEN_HEIGHT (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)
iOS 8以降では、次のviewWillTransitionToSize:withTransitionCoordinatorメソッドを使用する必要があります。
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
// You can store size in an instance variable for later
currentSize = size;
// This is basically an animation block
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Get the new orientation if you want
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
// Adjust your views
[self.myView setFrame:CGRectMake(0, 0, size.width, size.height)];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Anything else you need to do at the end
}];
}
これは、サイズに関する情報を提供しない非推奨のアニメーションメソッドを置き換えます。
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
iOS 8以降、画面の境界は現在の向きに対して正しく返されるようになりました。これは、iPadが横向き[UIScreen mainScreen] .boundsの場合、iOS <= 7では768、iOS 8では1024を返すことを意味します。
以下は、リリースされたすべてのバージョンで正しい高さと幅を返します。
-(CGRect)currentScreenBoundsDependOnOrientation
{
NSString *reqSysVer = @"8.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
return [UIScreen mainScreen].bounds;
CGRect screenBounds = [UIScreen mainScreen].bounds ;
CGFloat width = CGRectGetWidth(screenBounds) ;
CGFloat height = CGRectGetHeight(screenBounds) ;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
screenBounds.size = CGSizeMake(width, height);
NSLog(@"Portrait Height: %f", screenBounds.size.height);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
screenBounds.size = CGSizeMake(height, width);
NSLog(@"Landscape Height: %f", screenBounds.size.height);
}
return screenBounds ;
}
向きに依存するサイズが必要で、ビューがある場合は、次のように使用できます。
view.bounds.size
私はのカテゴリを作成しましたUIScreen。これはすべてのiOSバージョンで機能するため、次のように使用できます
[[UIScreen mainScreen] currentScreenSize]。
@implementation UIScreen (ScreenSize)
- (CGSize)currentScreenSize {
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBounds.size;
if ( NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1 ) {
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if ( UIInterfaceOrientationIsLandscape(interfaceOrientation) ) {
screenSize = CGSizeMake(screenSize.height, screenSize.width);
}
}
return screenSize;
}
@end
以下は、向きに依存する画面サイズを取得するSwiftの方法です。
var screenWidth: CGFloat {
if UIInterfaceOrientationIsPortrait(screenOrientation) {
return UIScreen.mainScreen().bounds.size.width
} else {
return UIScreen.mainScreen().bounds.size.height
}
}
var screenHeight: CGFloat {
if UIInterfaceOrientationIsPortrait(screenOrientation) {
return UIScreen.mainScreen().bounds.size.height
} else {
return UIScreen.mainScreen().bounds.size.width
}
}
var screenOrientation: UIInterfaceOrientation {
return UIApplication.sharedApplication().statusBarOrientation
}
これらは私のプロジェクトの標準機能として含まれています:
float msWidth = [[UIScreen mainScreen] bounds].size.width*(IS_RETINA?2.0f:1.0f);
float msHeight = [[UIScreen mainScreen] bounds].size.height*(IS_RETINA?2.0f:1.0f);
if ( UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ) {
os->setWidth(MIN(msWidth, msHeight));
os->setHeight(MAX(msWidth, msHeight));
} else {
os->setWidth(MAX(msWidth, msHeight));
os->setHeight(MIN(msWidth, msHeight));
}
NSLog(@"screen_w %f", os->getWidth());
NSLog(@"screen_h %f", os->getHeight());
ただし、iOS 8.0.2では:
+ (NSUInteger)currentWindowWidth
{
NSInteger width = 0;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
CGSize size = [UIScreen mainScreen].bounds.size;
// if (UIInterfaceOrientationIsLandscape(orientation)) {
// width = size.height;
// } else {
width = size.width;
// }
return width;
}