为什么使用 Autolayout/Constraints 而不是 frame 和 layoutSubviews?
Why use Autolayout/Constraints instead of frame and layoutSubviews?
我已经为我的应用程序的启动屏幕实现了一个视图控制器,如下所示。我决定使用框架而不是自动布局,我想知道是否有任何理由在这里使用 autolayout/constraints。
我不允许在我的应用程序上旋转,所以我看不出我可以从约束中获得什么好处,而且由于我不喜欢使用界面生成器,我认为代码是 cleaner/easier 创建和布置框架。
感谢任何意见 - 请在下面找到代码。
#import "LaunchViewController.h"
#import "RegisterTableViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface LaunchViewController ()
@property (nonatomic) UILabel *appLabel;
@property (nonatomic) UIButton *signUpButton;
@property (nonatomic) UIButton *loginButton;
@end
@implementation LaunchViewController
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor standardBlackColor];
[self layoutViews];
}
- (void)viewDidAppear {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UIView
- (void)layoutViews
{
self.appLabel.frame = [self _appLabelFrame];
self.loginButton.frame = [self _loginButtonFrame];
self.signUpButton.frame = [self _signUpButtonFrame];
[self.view addSubview:self.appLabel];
[self.view addSubview:self.loginButton];
[self.view addSubview:self.signUpButton];
}
#pragma mark - Layout
- (CGRect)_appLabelFrame
{
CGFloat x_offset = 0;
CGFloat y_offset = (self.view.frame.size.height / 10);
CGFloat width =self.view.frame.size.width;
CGFloat height = 50;
return CGRectMake(x_offset, y_offset, width, height);
}
- (CGRect)_signUpButtonFrame
{
CGFloat height = self.view.frame.size.height/14;
CGFloat x_offset = self.view.frame.size.width / 24;
CGFloat y_offset = self.view.frame.size.height - ((height + x_offset));
CGFloat width = self.view.frame.size.width - (2 * x_offset);
return CGRectMake(x_offset, y_offset, width, height);}
- (CGRect)_loginButtonFrame
{
CGFloat height = self.view.frame.size.height/14;
CGFloat x_offset = self.view.frame.size.width / 24;
CGFloat y_offset = self.view.frame.size.height - ((2 * height)+(2 * x_offset));
CGFloat width = self.view.frame.size.width - (2 * x_offset);
return CGRectMake(x_offset, y_offset, width, height);
}
#pragma mark - Getters and Setters
- (UILabel *)appLabel
{
if (!_appLabel){
_appLabel = [[UILabel alloc] init];
_appLabel.text = @"iOS APP";
_appLabel.textAlignment = NSTextAlignmentCenter;
[_appLabel setFont:[UIFont appThinTitleFont]];
_appLabel.textColor = [UIColor whiteColor];
}
return _appLabel;
}
- (UIButton *)signUpButton
{
if (!_signUpButton){
_signUpButton = [[UIButton alloc] init];
_signUpButton.backgroundColor = [UIColor darkBlueColor];
[_signUpButton setTitle:@"SIGN UP" forState:UIControlStateNormal];
[_signUpButton.titleLabel setFont:[UIFont largeRegularButtonFont]];
[_signUpButton addTarget:self action:@selector(signupPageSegue) forControlEvents:UIControlEventTouchUpInside];
}
return _signUpButton;
}
- (UIButton *)loginButton
{
if (!_loginButton){
_loginButton = [[UIButton alloc] init];
_loginButton.backgroundColor = [UIColor clearColor];
_loginButton.layer.borderColor = [[UIColor whiteColor] CGColor];
_loginButton.layer.borderWidth =1.0f;
[_loginButton setTitle:@"LOGIN" forState:UIControlStateNormal];
[_loginButton.titleLabel setFont:[UIFont largeRegularButtonFont]];
[_loginButton addTarget:self action:@selector(loginPageSegue) forControlEvents:UIControlEventTouchUpInside];
}
return _loginButton;
}
#pragma mark - Targets
- (void)signupPageSegue
{
[self performSegueWithIdentifier:@"SignUpSegue" sender:self];
}
- (void)loginPageSegue
{
[self performSegueWithIdentifier:@"LoginSegue" sender:self];
}
@end
花点时间学习自动布局。你会很高兴你做到了。
您展示的布局可以在 Interface Builder 中更简单地表达,更重要的是,随着新需求的出现,将更容易更新。
虽然这个特定的屏幕确实可以正常工作。随着您的应用程序的发展,您会很快了解到用代码表达所有内容太费力了。
另请注意,如果您想要在 iPad 上 运行 此应用,该应用将无法支持多任务处理。
你应该使用约束因为:
1)他们就是"frames"
2)不同的屏幕分辨率4s/5s,5,5c/会有问题
如果您不使用自动布局,您的应用程序会自动增加屏幕(6/6+)和具有一定经验的人。会注意到这个错误,因为它确实是错误的,专业人士不会这样做。
3)你的代码会减少两次。
4) 你说"I don't like to use interface builder"那是什么? like/not喜欢吗?你应该使用 UIKit 的所有力量,你不能随心所欲,你应该有效地工作......而且你应该使用 IB + 约束......
请花时间学习如何使用约束,这真的不难。
开始一个新项目并使用故事板中的自动布局构建此屏幕需要 3 分钟。
我已经为我的应用程序的启动屏幕实现了一个视图控制器,如下所示。我决定使用框架而不是自动布局,我想知道是否有任何理由在这里使用 autolayout/constraints。
我不允许在我的应用程序上旋转,所以我看不出我可以从约束中获得什么好处,而且由于我不喜欢使用界面生成器,我认为代码是 cleaner/easier 创建和布置框架。
感谢任何意见 - 请在下面找到代码。
#import "LaunchViewController.h"
#import "RegisterTableViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface LaunchViewController ()
@property (nonatomic) UILabel *appLabel;
@property (nonatomic) UIButton *signUpButton;
@property (nonatomic) UIButton *loginButton;
@end
@implementation LaunchViewController
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor standardBlackColor];
[self layoutViews];
}
- (void)viewDidAppear {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UIView
- (void)layoutViews
{
self.appLabel.frame = [self _appLabelFrame];
self.loginButton.frame = [self _loginButtonFrame];
self.signUpButton.frame = [self _signUpButtonFrame];
[self.view addSubview:self.appLabel];
[self.view addSubview:self.loginButton];
[self.view addSubview:self.signUpButton];
}
#pragma mark - Layout
- (CGRect)_appLabelFrame
{
CGFloat x_offset = 0;
CGFloat y_offset = (self.view.frame.size.height / 10);
CGFloat width =self.view.frame.size.width;
CGFloat height = 50;
return CGRectMake(x_offset, y_offset, width, height);
}
- (CGRect)_signUpButtonFrame
{
CGFloat height = self.view.frame.size.height/14;
CGFloat x_offset = self.view.frame.size.width / 24;
CGFloat y_offset = self.view.frame.size.height - ((height + x_offset));
CGFloat width = self.view.frame.size.width - (2 * x_offset);
return CGRectMake(x_offset, y_offset, width, height);}
- (CGRect)_loginButtonFrame
{
CGFloat height = self.view.frame.size.height/14;
CGFloat x_offset = self.view.frame.size.width / 24;
CGFloat y_offset = self.view.frame.size.height - ((2 * height)+(2 * x_offset));
CGFloat width = self.view.frame.size.width - (2 * x_offset);
return CGRectMake(x_offset, y_offset, width, height);
}
#pragma mark - Getters and Setters
- (UILabel *)appLabel
{
if (!_appLabel){
_appLabel = [[UILabel alloc] init];
_appLabel.text = @"iOS APP";
_appLabel.textAlignment = NSTextAlignmentCenter;
[_appLabel setFont:[UIFont appThinTitleFont]];
_appLabel.textColor = [UIColor whiteColor];
}
return _appLabel;
}
- (UIButton *)signUpButton
{
if (!_signUpButton){
_signUpButton = [[UIButton alloc] init];
_signUpButton.backgroundColor = [UIColor darkBlueColor];
[_signUpButton setTitle:@"SIGN UP" forState:UIControlStateNormal];
[_signUpButton.titleLabel setFont:[UIFont largeRegularButtonFont]];
[_signUpButton addTarget:self action:@selector(signupPageSegue) forControlEvents:UIControlEventTouchUpInside];
}
return _signUpButton;
}
- (UIButton *)loginButton
{
if (!_loginButton){
_loginButton = [[UIButton alloc] init];
_loginButton.backgroundColor = [UIColor clearColor];
_loginButton.layer.borderColor = [[UIColor whiteColor] CGColor];
_loginButton.layer.borderWidth =1.0f;
[_loginButton setTitle:@"LOGIN" forState:UIControlStateNormal];
[_loginButton.titleLabel setFont:[UIFont largeRegularButtonFont]];
[_loginButton addTarget:self action:@selector(loginPageSegue) forControlEvents:UIControlEventTouchUpInside];
}
return _loginButton;
}
#pragma mark - Targets
- (void)signupPageSegue
{
[self performSegueWithIdentifier:@"SignUpSegue" sender:self];
}
- (void)loginPageSegue
{
[self performSegueWithIdentifier:@"LoginSegue" sender:self];
}
@end
花点时间学习自动布局。你会很高兴你做到了。
您展示的布局可以在 Interface Builder 中更简单地表达,更重要的是,随着新需求的出现,将更容易更新。
虽然这个特定的屏幕确实可以正常工作。随着您的应用程序的发展,您会很快了解到用代码表达所有内容太费力了。
另请注意,如果您想要在 iPad 上 运行 此应用,该应用将无法支持多任务处理。
你应该使用约束因为:
1)他们就是"frames"
2)不同的屏幕分辨率4s/5s,5,5c/会有问题 如果您不使用自动布局,您的应用程序会自动增加屏幕(6/6+)和具有一定经验的人。会注意到这个错误,因为它确实是错误的,专业人士不会这样做。
3)你的代码会减少两次。
4) 你说"I don't like to use interface builder"那是什么? like/not喜欢吗?你应该使用 UIKit 的所有力量,你不能随心所欲,你应该有效地工作......而且你应该使用 IB + 约束......
请花时间学习如何使用约束,这真的不难。
开始一个新项目并使用故事板中的自动布局构建此屏幕需要 3 分钟。