基本思路
- 设置约束:使用自动布局约束(
NSLayoutConstraint
)来定义视图之间的关系和位置,确保视图在不同屏幕方向下能正确布局。约束应具有足够的灵活性,以适应不同的宽高比。
- 响应旋转通知:监听设备旋转的系统通知,当接收到旋转通知时,更新约束或触发布局更新,使视图根据新的屏幕方向重新布局。
关键代码步骤
- 设置约束:
// 创建视图
UIView *view = [[UIView alloc] init];
view.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:view];
// 创建宽度约束
NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:200.0];
// 创建高度约束
NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:100.0];
// 创建中心X约束
NSLayoutConstraint *centerXConstraint = [NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0];
// 创建中心Y约束
NSLayoutConstraint *centerYConstraint = [NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0];
// 添加约束到视图
[self.view addConstraints:@[widthConstraint, heightConstraint, centerXConstraint, centerYConstraint]];
- **使用`Visual Format Language`创建约束**:
UIView *view = [[UIView alloc] init];
view.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:view];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(view);
// 创建水平方向约束
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[view]-|"
options:0
metrics:nil
views:viewsDictionary]];
// 创建垂直方向约束
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[view]-|"
options:0
metrics:nil
views:viewsDictionary]];
- 响应旋转通知:
- 注册通知:在视图控制器的
viewDidLoad
方法中注册设备旋转通知。
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- **实现通知处理方法**:在该方法中更新约束或触发布局更新。
- (void)deviceOrientationDidChange:(NSNotification *)notification {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (UIInterfaceOrientationIsLandscape(orientation)) {
// 横屏处理,例如更新约束
// 假设之前有一个宽度为200的约束,横屏时改为300
NSArray *constraints = self.view.constraints;
for (NSLayoutConstraint *constraint in constraints) {
if (constraint.firstItem == someView && constraint.firstAttribute == NSLayoutAttributeWidth) {
constraint.constant = 300;
}
}
} else if (UIInterfaceOrientationIsPortrait(orientation)) {
// 竖屏处理,例如更新约束
NSArray *constraints = self.view.constraints;
for (NSLayoutConstraint *constraint in constraints) {
if (constraint.firstItem == someView && constraint.firstAttribute == NSLayoutAttributeWidth) {
constraint.constant = 200;
}
}
}
// 强制布局更新
[self.view layoutIfNeeded];
}
- 移除通知观察者:在视图控制器销毁时移除通知观察者,防止内存泄漏。
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIDeviceOrientationDidChangeNotification
object:nil];
}