如何在设备旋转后以编程方式创建的 UIButtons 保持在屏幕底部?
Posted
技术标签:
【中文标题】如何在设备旋转后以编程方式创建的 UIButtons 保持在屏幕底部?【英文标题】:How to keep programmatically created UIButtons at the bottom of the screen after device rotation? 【发布时间】:2014-02-02 09:34:40 【问题描述】:出于某种原因,我必须以编程方式而不是在 .xib/.storyboard 文件中创建两个 UIButton,并且我希望它们始终位于屏幕底部。我发现如果我想让按钮处于完全相同的位置,如果它们是在 Interface Builder 中创建的,我必须像这样定义它们的框架:
CGRect captureCodeFrame = [[self captureCodeButton] frame];
CGRect captureReceiptFrame = [[self captureReceiptButton] frame];
captureCodeFrame.origin.x = MARGIN;
captureCodeFrame.origin.y = [[UIScreen mainScreen] bounds].size.height - [[UIApplication sharedApplication] statusBarFrame].size.height - [[[self navigationController] navigationBar] frame].size.height - BUTTON_HEIGHT - MARGIN;
captureReceiptFrame.origin.x = [[UIScreen mainScreen] bounds].size.width - BUTTON_WIDTH - MARGIN;
captureReceiptFrame.origin.y = [[UIScreen mainScreen] bounds].size.height - [[UIApplication sharedApplication] statusBarFrame].size.height - [[[self navigationController] navigationBar] frame].size.height - BUTTON_HEIGHT - MARGIN;
[[self captureCodeButton] setFrame:captureCodeFrame];
[[self captureReceiptButton] setFrame:captureReceiptFrame];
换句话说,我基本上是取整个屏幕的高度,减去状态和导航栏的高度,然后这些按钮的高度和屏幕底端的空间来设置Y
坐标两个按钮。我正在使用类似的技术来确定右侧按钮的X
坐标。三个宏定义如下:
#define MARGIN 20
#define BUTTON_HEIGHT 30
#define BUTTON_WIDTH 136
最后,我有方法(void)didRotate:(NSNotification *)notification
,每当用户旋转设备时都会调用该方法,并且我知道我需要为按钮设置新框架以供他们重绘(或者我可以吗?也许它是通过一些转换来完成的? ) 但无论我尝试将新框架分配给什么值,我都无法正确处理。我最近的尝试是这样的(缩短为仅包括左横向模式):
- (void)didRotate:(NSNotification *)notification
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
CGSize newSize = [[self view] bounds].size;
CGRect captureCodeFrame = [[self captureCodeButton] frame];
CGRect captureReceiptFrame = [[self captureReceiptButton] frame];
[CATransaction begin];
[CATransaction setAnimationDuration:0.0];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[self previewLayer] setPosition:CGPointMake(0.5 * newSize.width, 0.5 * newSize.height)];
switch (deviceOrientation)
case UIDeviceOrientationPortrait:
captureCodeFrame.origin.x = MARGIN;
captureCodeFrame.origin.y = [[UIScreen mainScreen] bounds].size.height - [[UIApplication sharedApplication] statusBarFrame].size.height - [[[self navigationController] navigationBar] frame].size.height - BUTTON_HEIGHT - MARGIN;
captureReceiptFrame.origin.x = [[UIScreen mainScreen] bounds].size.width - BUTTON_WIDTH - MARGIN;
captureReceiptFrame.origin.y = [[UIScreen mainScreen] bounds].size.height - [[UIApplication sharedApplication] statusBarFrame].size.height - [[[self navigationController] navigationBar] frame].size.height - BUTTON_HEIGHT - MARGIN;
[[self captureCodeButton] setFrame:captureCodeFrame];
[[self captureReceiptButton] setFrame:captureReceiptFrame];
[[self view] setTransform:CGAffineTransformMakeRotation(0)];
[[self previewLayer] setAffineTransform:CGAffineTransformMakeRotation(0)];
break;
case UIDeviceOrientationLandscapeLeft:
captureCodeFrame.origin.x = [[UIScreen mainScreen] bounds].size.width - BUTTON_WIDTH - MARGIN;
captureCodeFrame.origin.y = MARGIN;
// TODO: adjust captureReceiptFrame here
[[self captureCodeButton] setFrame:captureCodeFrame];
[[self view] setTransform:CGAffineTransformMakeRotation((CGFloat) (M_PI / 2))];
[[self previewLayer] setAffineTransform:CGAffineTransformMakeRotation((CGFloat) (-M_PI / 2))];
break;
case UIDeviceOrientationLandscapeRight:
// TODO: something should be here
[[self view] setTransform:CGAffineTransformMakeRotation((CGFloat) (-M_PI / 2))];
[[self previewLayer] setAffineTransform:CGAffineTransformMakeRotation((CGFloat) (M_PI / 2))];
break;
default:
break;
[CATransaction commit];
但无论我尝试为origin.x
和origin.y
分配什么值,按钮总是出现在屏幕外或完全奇怪的位置。奇怪的是,如果我为这两个属性都设置了100
的值,则按钮不会出现在距屏幕左上角大约 100 点的位置,而是在我看来完全随机的地方。似乎我不知道当设备旋转时坐标系会发生什么……嗯……这就是我想请你介入并保存我的应用程序的地方! :-)
PS:状态和导航栏从纵向(客户需求,客户获得)保持在其位置,这就是为什么它们不包括在新的原点计算中。
【问题讨论】:
你在使用自动布局吗?可能是负责任的。 在这个应用程序中没有任何地方(我还没有习惯“新”技术,即故事板和自动布局,没有时间阅读它们,并且不建议使用它们)我工作的公司因为其他程序员处于同样的情况——没有时间阅读新东西),加上这个视图控制器显然没有附加.xib,它主要只是相机输出(在AVCaptureVideoPreviewLayer
层) 和这两个按钮。
另外,如果您缺少 .xib 并以编程方式创建所有内容,我什至不确定您是否可以使用自动布局?不知道:o
UIView autoresizingMask - Interface Builder to Code - Programmatically create struts and springs的可能重复
【参考方案1】:
您需要为您的按钮设置适当的 UIViewAutoresizingMask 看到这个answer
【讨论】:
我明白了,我是否正确地认为左侧按钮的正确掩码是UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin
,因为我希望按钮扩大宽度并保持在屏幕的左下角?它以某种方式起作用,但现在按钮在纵向模式下绝对距离屏幕底部超过 20 点。我想知道约束是否可以解决这个问题……
如果答案在另一个问题中可用,最好将此问题标记为重复。以上是关于如何在设备旋转后以编程方式创建的 UIButtons 保持在屏幕底部?的主要内容,如果未能解决你的问题,请参考以下文章