我正在尝试以编程方式确定我的应用程序的当前高度和宽度.我用这个:
CGRect screenRect = [[UIScreen mainScreen] bounds];
Run Code Online (Sandbox Code Playgroud)
但无论设备是纵向还是横向,这都会产生320的宽度和480的高度.如何确定主屏幕的当前宽度和高度(即取决于设备方向)?
Sam*_*Sam 164
您可以使用类似的方法UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)来确定方向,然后相应地使用尺寸.
但是,在UIViewController中的方向更改期间
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
Run Code Online (Sandbox Code Playgroud)
使用传入的方向,toInterfaceOrientation因为UIApplication的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
Run Code Online (Sandbox Code Playgroud)
要使用代码简单调用[UIApplication currentSize].此外,我运行上面的代码,所以我知道它的工作原理并报告所有方向的正确响应.请注意,我考虑状态栏.有趣的是,我不得不减去状态栏高度和宽度的MIN.
希望这可以帮助.:d
其他想法
您可以通过查看UIWindow的rootViewController属性来获取维度.我在过去看过这个,它同样在纵向和横向上报告相同的尺寸,除了它报告有旋转变换:
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] view]
<UILayoutContainerView:0xf7296f0; frame =(0 0; 320 480); transform = [0,-1,1,0,0,0]; autoresize = W + H; layer = <CALayer:0xf729b80 >>
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] view]
<UILayoutContainerView:0xf7296f0; frame =(0 0; 320 480); autoresize = W + H; layer = <CALayer:0xf729b80 >>
不确定你的应用程序是如何工作的,但是如果你没有使用某种类型的导航控制器,你可以在主视图下面有一个UIView,其中父级的最大高度/宽度与父级一起增长/缩小.然后你可以这样做:[[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame].在一条线上看起来非常激烈,但你明白了.
但是......在摘要下进行上述3个步骤仍然会更好.开始搞乱UIWindows,你会发现奇怪的东西,比如显示UIAlertView将改变UIApplication的keywindow指向UIAlertView创建的新UIWindow.谁知道?在找到依赖keyWindow的bug并发现它改变了之后我做了!
mon*_*jer 39
这是我的解决方案代码!此方法可以添加到NSObject类的Categroy,或者您可以定义Top自定义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 ;
}
Run Code Online (Sandbox Code Playgroud)
请注意,在IOS8之后,作为UIScreen的边界属性的Apple Document说:
讨论
此矩形在当前坐标空间中指定,该空间考虑了对设备有效的任何界面旋转.因此,当设备在纵向和横向之间旋转时,此属性的值可能会更改.
所以为了兼顾性,我们应该检测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 ;
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*aff 30
这是一个方便的宏:
#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)
Run Code Online (Sandbox Code Playgroud)
Mar*_*ngs 14
在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
}];
}
Run Code Online (Sandbox Code Playgroud)
这将替换不提供有关大小信息的弃用动画方法:
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
Run Code Online (Sandbox Code Playgroud)
A.B*_*ger 10
从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 ;
}
Run Code Online (Sandbox Code Playgroud)
如果您想要与方向相关的尺寸并且您有一个视图,您可以使用:
view.bounds.size
Run Code Online (Sandbox Code Playgroud)
我为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
Run Code Online (Sandbox Code Playgroud)
这是一种获取取向相关屏幕尺寸的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
}
Run Code Online (Sandbox Code Playgroud)
这些作为我的项目的标准功能包括在内:
https://github.com/goktugyil/EZSwiftExtensions
| 归档时间: |
|
| 查看次数: |
77555 次 |
| 最近记录: |