是自动布局有用的处理碎片的屏幕大小在iOS?为什么Android中没有相应的工具?< / h1 >



我对iOS中的自动布局很陌生。我读了它的论文,在WWDC上看了两个视频。我知道它在处理UI小部件之间的关系方面非常有效。然而,我仍然不太明白它为什么比传统的弹簧和结构好。正如iOS 7 UI过渡指南中所述!:

如果你没有使用自动布局,现在可能是开始的最佳时机,特别是如果你需要支持一个应用程序的多个版本。如果你使用手动或编程布局技术,你有责任确保布局适当调整当文本大小的变化。

是否有任何例子比较使用字符串/struts和自动布局布局的实现?

另外,Android中的相对布局和自动布局有什么比较吗?它们都以一种相对的方式处理布局问题。它们之间的主要区别是什么?

另一方面,在Android中采用AutoLayout来解决碎片化问题是否有用?我知道Google有自己的一套解决方案来处理碎片化,例如,使用dp代替px,使用RelativeLayout。但是,程序员仍然需要为布局使用不同的xml。自动布局是否有助于减少XML文件的数量?

我认为你的问题很广泛,我有点同意两个票数接近的人,但我可以给你一些关于iOS中的自动布局的观点。

我开始为iPhone编写应用程序时,iPad还不存在,iPhone OS 3是最新最好的。是的,有一段时间了!: -)

那时候,Interface Builder是一个独立于Xcode的工具,故事板还不存在。弹簧,支柱和手动框架操作是游戏的名称。我了解了这个系统,并且喜欢上了它。特别是因为3.5英寸的屏幕是唯一的一个(然后iPad出现了),它使UI设计和实现变得非常容易。

当自动布局被引入时,我并不是很喜欢它。最初,我并不认为它是非常可靠或健壮的,在Xcode的(现在集成的)Interface Builder中设计约束是很困难的,而且通常是反直觉的,整个过程比我以前的过程要困难得多。

一年后,我重新审视了这个话题。现在,Xcode能够在Interface Builder中非常可靠和快速地生成约束。仅有的两种屏幕尺寸分别是3.5" Retina, 4.0" Retina和iPad(两者的点数),所以屏幕设计基本上是相同的),所以屏幕设计仍然相当直接。

然后是iPhone 6/6 Plus。和大小类。Size Classes不是自动实现的,所以你必须转换所有旧的故事板,这当然有意义,但在现有的应用程序中对我来说似乎太痛苦了。除此之外,我发现使用Size Classes很容易把事情搞砸(等等,这个约束是安装在所有Size中还是只安装在这个Size中?)另外,字体大小对我来说尤其是个糟糕的问题。可以说,从头开始。 这是我最近开始做的事情。这是非常有效的,我相信大致相同的初始努力,但随后的更改/调整UI进行得非常快。
  1. 我摆脱了所有的故事板和xib。是的。每一个。单身。一个。我不久前读了这篇文章。我讨厌它。我是说,这真的让我很生气。我想,"这家伙太蠢了!Interface Builder真的加快了我的开发周期!他一定是做错了!"然后我开始注意到,对我的50多个屏幕故事板的任何调整都需要2-3分钟来编译以进行测试,这开始让我感到困扰。我想过将单一的故事板分解成多个,这确实加快了速度,但屏幕大小的碎片化仍然使UI设计和执行变得比必要时更加困难,所以我抛弃了所有的故事板(当然,慢慢地,同时有条不紊地遵循这些步骤的其余部分)。
  2. 我学会了喜欢用代码编写NSLayoutConstraint。我的意思是,不只是"不讨厌"它,而是"喜欢"它!一旦你开始大量写作,就很容易形成一种特定的模式,它们几乎最终会自己写作。另外,小心的话,复制和粘贴一个控件的约束并为你在屏幕上布局的所有其他按钮调整它是非常容易的。
  3. 现在一切都在代码中设置(顺便说一下,这使得推动新的UIViewController超级容易;现在,无论平台或屏幕大小,它总是,总是就像[[ViewController alloc] init]一样简单,它会照顾剩下的!),我想出了一种方法,可以将UI布局过程划分为几个独立的部分。

我的基本UIViewController子类现在开始的生活看起来像这样:

@implementation ViewController
#pragma mark -
#pragma mark - View Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUserInterface];
}
#pragma mark -
#pragma mark - UI Setup
- (void)setupUserInterface {
[self createConstants];
[self createControls];
[self setupControls];
[self layoutControls];
// Optional
[self setupNavigationBar];
}
- (void)createConstants {
}
- (void)createControls {
}
- (void)setupControls {
}
- (void)layoutControls {
}
#pragma mark - 
#pragma mark - Optional UI Setup
- (void)setupNavigationBar {
}
@end

然后,这是一个非常简单,直接的过程来定义什么控件将出现在UI上,他们需要如何看,以及需要什么"常量"来完成。例如,假设我有一个表单要布局,并且有几个UITextFields,每个UILabel都有关联。我可能有以下属性(其中包括):

@property (assign, nonatomic) CGFloat  labelFontSize;
@property (assign, nonatomic) CGFloat  textFieldFontSize;
@property (strong, nonatomic) UIFont  *labelFont;
@property (strong, nonatomic) UIFont  *textFieldFontSize;

之后,在-createConstants中,我可以根据运行应用程序的设备上的屏幕确定字体大小值,然后可以使用该值实例化适当的字体。这样,我就有一个地方可以修改值,比如边距、控件间距、字体大小、文本字段高度等。然后,进行更改就像更改数字一样简单,重新编译以测试我的新UI只需要几秒钟(通常是10秒),而不是几分钟。

这个解决方案给了我更快的速度(由于既减少了编译时间,也减少了进行实际更改的时间)和更大的控制(我发现更容易立即看到代码中的精确像素精度,而不是必须单击控件,单击检查器并看到Xcode分配了任意值,或者我的视图最初偏离了4点,或类似的东西)。而且,这比传统的弹簧和struts更好,因为它使得在关系中布局元素变得非常容易。彼此之间,无需担心任何平台/屏幕上的确切框架尺寸,更不用说所有的了。

例如:

  1. 假设我有一个相当简单的屏幕,只有一个标题标签和5个按钮。
  2. 我想把它们都堆叠在一个垂直的列中。
  3. 我希望标签占用尽可能多的空间。
  4. 我想让按钮占用剩余空间。
  5. 我想让所有的按钮都是相同的高度

对于弹簧和结构体,你必须做大量的计算才能在所有平台/屏幕上完成。是的,你可以编写一个简单的方法来完成你需要的,但是使用自动布局会更容易。

我是这样做的(记住,这是一个完全以代码为中心的方法):

- (void)layoutControls {
[self.view addSubview:label];
[self.view addSubview:button1];
[self.view addSubview:button2];
[self.view addSubview:button3];
[self.view addSubview:button4];
[self.view addSubview:button5];
// Each of the 6 controls gets laid out horizontally with essentially
// an identical version of this (where margin is a "constant" I've defined):
[self.view addConstraints:
[NSLayoutConstraints 
constraintsWithVisualFormat:@"H:|-(margin)-[label]-(margin)-|"
options:0
metrics:@{@"margin": @(self.margin)}
views:@{@"label": self.label}
]
];
// Once all are laid out horizontally, here's how to do the vertical layout
[self.view addConstraints:
[NSLayoutConstraints
constraintsWithVisualFormat:@"V:|-(margin)-[label]-[button1]-[button2(==button1)]-[button3(==button1)]-[button4(==button1)]-[button5(==button1)]-(margin)-|"
options:0
metrics:@{@"margin": @(self.margin)}
views:@{@"label": self.label,
@"button1": self.button1,
@"button2": self.button2,
@"button3": self.button3, 
@"button4": self.button4, 
@"button5": self.button5}
]
];
}

就是这样。系统现在将为您计算所有精确的数学,它"只是工作"!对我来说,这比弄清楚手工框架之类的要容易得多。另外,如果你决定以后添加或删除一个按钮,这很容易"修复"与自动布局。

关于你问题的第二部分(Android布局),我希望找到一种方法来实现类似的方法,因为我开始学习在Android上编写应用程序。

最新更新