当我改变方向时,我的视图的高度和宽度没有改变
When i changing orientation my view's height and width are not changed
我在默认视图的子视图中使用了一个视图。我试图将它的高度和宽度设置为与超级视图相同,当它在应用程序加载纵向模式时更改 orientation.First 时,则此子视图采用完美的高度 - 宽度但是当我们第二次更改为纵向模式时它没有改变高度和宽度。
加载中:-
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
方法:-
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
NSLog(@"Portrait");
NSLog(@"View Height %f",self.view.frame.size.height);
NSLog(@"View Width%f",self.view.frame.size.width);
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
NSLog(@"View1 Height %f",view1.frame.size.height);
NSLog(@"View1 Width%f",view1.frame.size.width);
break;
case UIDeviceOrientationLandscapeRight:
NSLog(@" LanScapRight");
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.height, self.view.frame.size.width);
break;
case UIDeviceOrientationLandscapeLeft:
NSLog(@" LandScapLeft");
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
default:
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
NSLog(@"Default");
//view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.height, self.view.frame.size.width);
break;
};
}
输出:-(问题)
2016-02-20 01:29:15.907 Editing[4999:95632] Portrait
[![2016-02-20 01:29:15.910 Editing\[4999:95632\] View Height 568.000000
2016-02-20 01:29:15.910 Editing\[4999:95632\] View Width320.000000
2016-02-20 01:29:15.911 Editing\[4999:95632\] View1 Height 568.000000
2016-02-20 01:29:15.912 Editing\[4999:95632\] View1 Width320.000000
2016-02-20 01:29:39.090 Editing\[4999:95632\] LanScapRight
2016-02-20 01:29:40.364 Editing\[4999:95632\] Default
2016-02-20 01:29:41.645 Editing\[4999:95632\] LandScapLeft
2016-02-20 01:29:41.646 Editing\[4999:95632\] Default
2016-02-20 01:29:43.316 Editing\[4999:95632\] Portrait
2016-02-20 01:29:43.317 Editing\[4999:95632\] View Height 320.000000
2016-02-20 01:29:43.317 Editing\[4999:95632\] View Width568.000000
2016-02-20 01:29:43.317 Editing\[4999:95632\] View1 Height 320.000000
2016-02-20 01:29:43.318 Editing\[4999:95632\] View1 Width568.000000]
[self.view setNeedsDisplay];
在上面的开关盒上使用这个,这段代码用于重新加载
视图,以便您获得更新的视图宽度和高度。
如果您只想让视图准确地具有其父视图的边界而不使用自动布局,则只要父视图的边界发生变化,具有灵活高度和宽度的自动调整大小掩码应该简单地设置正确的框架。
编辑
您正在将子视图的框架原点设置为父视图的原点 - 我怀疑这不是故意的。如果父视图从 (0,0) 移动,这会将子视图的原点相对于 window.
移动两倍
由于界面方向的变化,更新 UI 是一项相当常见的任务,因此有一个很好的支持方法来执行此操作。
解决方案 1:
如果您使用的是基于框架的布局(如示例代码中所示),建议将框架设置代码放入视图的 layoutSubviews
中,正如 Jan Greve 评论的那样。为此,您必须继承 UIView。 layoutSubviews
方法将在每次视图边界发生变化时调用,因此您不必观察有关界面方向的通知,并且您还可以对其他大小变化事件做出反应,例如多任务拆分视图。这是一个如何子类化 UIView 和实现布局的超小示例:
// MyView.h
#import <UIKit/UIKit.h>
@interface MyView : UIView
@property (strong) UIView* view1;
@property (strong) UIView* calendar;
@end
// MyView.m
#import "MyView.h"
@implementation MyView
- (instancetype)init {
self = [super init];
if (self) {
self.view1 = [[UIView alloc] init];
self.view1.backgroundColor = [UIColor grayColor];
[self addSubview:self.view1];
self.calendar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
self.calendar.backgroundColor = [UIColor redColor];
[self.view1 addSubview:self.calendar];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.view1.frame = self.bounds;
self.calendar.center = self.view1.center;
}
@end
如果您将 MyView 实例设置为 viewcontroller 的视图 属性 它就可以正常工作。
解决方案 2:
通常可以使用解决方案 1,但在您的特定情况下,可以通过 autoresizingmasks 来完成布局。 (在这里我不得不再次提到 Jan Greve,他在他的回答中推荐了这个。)现在你不需要子类 UIView 一切都可以从 viewcontroller 处理。您可以将这样的内容插入 viewDidLoad
UIView* view1 = [[UIView alloc] initWithFrame:self.view.frame];
view1.backgroundColor = [UIColor grayColor];
[self.view addSubview:view1];
view1.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
UIView* calendar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
calendar.backgroundColor = [UIColor redColor];
[view1 addSubview:calendar];
calendar.center = view1.center;
calendar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
我在默认视图的子视图中使用了一个视图。我试图将它的高度和宽度设置为与超级视图相同,当它在应用程序加载纵向模式时更改 orientation.First 时,则此子视图采用完美的高度 - 宽度但是当我们第二次更改为纵向模式时它没有改变高度和宽度。 加载中:-
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
方法:-
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
NSLog(@"Portrait");
NSLog(@"View Height %f",self.view.frame.size.height);
NSLog(@"View Width%f",self.view.frame.size.width);
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
NSLog(@"View1 Height %f",view1.frame.size.height);
NSLog(@"View1 Width%f",view1.frame.size.width);
break;
case UIDeviceOrientationLandscapeRight:
NSLog(@" LanScapRight");
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.height, self.view.frame.size.width);
break;
case UIDeviceOrientationLandscapeLeft:
NSLog(@" LandScapLeft");
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
default:
view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
NSLog(@"Default");
//view1.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.height, self.view.frame.size.width);
break;
};
}
输出:-(问题)
2016-02-20 01:29:15.907 Editing[4999:95632] Portrait
[![2016-02-20 01:29:15.910 Editing\[4999:95632\] View Height 568.000000
2016-02-20 01:29:15.910 Editing\[4999:95632\] View Width320.000000
2016-02-20 01:29:15.911 Editing\[4999:95632\] View1 Height 568.000000
2016-02-20 01:29:15.912 Editing\[4999:95632\] View1 Width320.000000
2016-02-20 01:29:39.090 Editing\[4999:95632\] LanScapRight
2016-02-20 01:29:40.364 Editing\[4999:95632\] Default
2016-02-20 01:29:41.645 Editing\[4999:95632\] LandScapLeft
2016-02-20 01:29:41.646 Editing\[4999:95632\] Default
2016-02-20 01:29:43.316 Editing\[4999:95632\] Portrait
2016-02-20 01:29:43.317 Editing\[4999:95632\] View Height 320.000000
2016-02-20 01:29:43.317 Editing\[4999:95632\] View Width568.000000
2016-02-20 01:29:43.317 Editing\[4999:95632\] View1 Height 320.000000
2016-02-20 01:29:43.318 Editing\[4999:95632\] View1 Width568.000000]
[self.view setNeedsDisplay];
在上面的开关盒上使用这个,这段代码用于重新加载 视图,以便您获得更新的视图宽度和高度。
如果您只想让视图准确地具有其父视图的边界而不使用自动布局,则只要父视图的边界发生变化,具有灵活高度和宽度的自动调整大小掩码应该简单地设置正确的框架。
编辑
您正在将子视图的框架原点设置为父视图的原点 - 我怀疑这不是故意的。如果父视图从 (0,0) 移动,这会将子视图的原点相对于 window.
移动两倍由于界面方向的变化,更新 UI 是一项相当常见的任务,因此有一个很好的支持方法来执行此操作。
解决方案 1:
如果您使用的是基于框架的布局(如示例代码中所示),建议将框架设置代码放入视图的 layoutSubviews
中,正如 Jan Greve 评论的那样。为此,您必须继承 UIView。 layoutSubviews
方法将在每次视图边界发生变化时调用,因此您不必观察有关界面方向的通知,并且您还可以对其他大小变化事件做出反应,例如多任务拆分视图。这是一个如何子类化 UIView 和实现布局的超小示例:
// MyView.h
#import <UIKit/UIKit.h>
@interface MyView : UIView
@property (strong) UIView* view1;
@property (strong) UIView* calendar;
@end
// MyView.m
#import "MyView.h"
@implementation MyView
- (instancetype)init {
self = [super init];
if (self) {
self.view1 = [[UIView alloc] init];
self.view1.backgroundColor = [UIColor grayColor];
[self addSubview:self.view1];
self.calendar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
self.calendar.backgroundColor = [UIColor redColor];
[self.view1 addSubview:self.calendar];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.view1.frame = self.bounds;
self.calendar.center = self.view1.center;
}
@end
如果您将 MyView 实例设置为 viewcontroller 的视图 属性 它就可以正常工作。
解决方案 2:
通常可以使用解决方案 1,但在您的特定情况下,可以通过 autoresizingmasks 来完成布局。 (在这里我不得不再次提到 Jan Greve,他在他的回答中推荐了这个。)现在你不需要子类 UIView 一切都可以从 viewcontroller 处理。您可以将这样的内容插入 viewDidLoad
UIView* view1 = [[UIView alloc] initWithFrame:self.view.frame];
view1.backgroundColor = [UIColor grayColor];
[self.view addSubview:view1];
view1.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
UIView* calendar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
calendar.backgroundColor = [UIColor redColor];
[view1 addSubview:calendar];
calendar.center = view1.center;
calendar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;