如何使用 NSLayoutConstraints 以编程方式将 UIView 中的 UIButtons 限制为比例宽度
How can I programatically constrain UIButtons in a UIView to proportional widths using NSLayoutConstraints
我正在尝试以编程方式创建自定义键盘。我已经设法让键盘的功能正常工作,但我正在努力以编程方式设置约束。
我已经设法找到代码来限制按钮在它们的行中大小相等,但无法对其进行足够的自定义以设置某些按钮的宽度(或比例宽度)。
这是当前键盘的图片
每一行都是一个单独的 UIView,其中填充了与每个键对应的 UIButton。然后我将每个视图内的按钮限制到它们的超级视图。
问题是我希望 space 按钮是屏幕的固定比例,并且第 4 行按钮的宽度相同(目前它们稍微宽一点,只有 9 个按钮而不是10 个)
虽然它是为 swift 编写的,但我已经从自定义键盘教程中改编了大量代码:here
- (void)addConstraintsToView: (UIView *)view {
NSArray * buttons = view.subviews;
for (UIButton * button in buttons) {
NSInteger index = [view.subviews indexOfObject:button];
NSLayoutConstraint * topConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1.0f constant:1.0f];
NSLayoutConstraint * bottomConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-1.0f];
NSLayoutConstraint * leftConstraint;
// If the first button in the row
if (!index) {
leftConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:1.0f];
}
else {
leftConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:buttons[index-1] attribute:NSLayoutAttributeRight multiplier:1.0f constant:1.0f];
NSLayoutConstraint * widthConstraint = [NSLayoutConstraint constraintWithItem:buttons[0] attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0];
[view addConstraint:widthConstraint];
}
NSLayoutConstraint * rightConstraint;
// If the last button in the row
if (index == buttons.count - 1) {
rightConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeRight multiplier:1.0f constant:-1.0f];
}
else {
rightConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:buttons[index+1] attribute:NSLayoutAttributeLeft multiplier:1.0f constant:-1.0f];
}
[view addConstraints:@[topConstraint, bottomConstraint, rightConstraint, leftConstraint]];
}
}
这是当前将按钮限制为等宽的代码。
主要问题是,虽然有很多关于如何使用 NSlayoutConstraint 的'tutorials',但它们主要是为少数视图提供的。然后他们使用 then names 并设置约束。
This one is probably the best, this one has the problem that I mentioned, each button is allocated and used as a local variable. 相似但略有不同,而且观看次数要少得多。
为此,因为我们要添加更多的视图,然后将每个按钮作为其自己的变量会太复杂。如果我能弄明白的话,在循环中使用几个 if 语句会更优雅。
我真正希望它能够将某些按钮设置为固定宽度或比例宽度。例如,shift 按钮和删除按钮各占屏幕的 15%,或者 shift 和 delete 按钮固定为 48 像素。
如有任何帮助,我们将不胜感激
感谢@rdelmar 帮助我实现这个解决方案
虽然网上有很多关于 NSLayoutConstraints 的信息,但他们需要一些时间来适应。在这种情况下,我过度思考了问题,需要有人指出明显的问题。
所以在这种情况下,我试图改变按钮的宽度,所以我需要担心的是宽度限制。其他可以忽略。
这种情况下调整从其他来源获得的代码以满足我的需要的困难。
NSLayoutConstraint * widthConstraint;
if ([button.titleLabel.text isEqualToString:@"SHFT"] || [button.titleLabel.text isEqualToString:@"DEL"]) {
// Make sure to set the button it is in relation to - in this case we can set it with relation to any of this middle buttons so buttons[1] is fine
widthConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:buttons[1] attribute:NSLayoutAttributeWidth multiplier:1.5f constant:0];
}
else if ([button.titleLabel.text isEqualToString:@"space"]) {
widthConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:buttons[1] attribute:NSLayoutAttributeWidth multiplier:3.0f constant:0];
}
else {
widthConstraint = [NSLayoutConstraint constraintWithItem:buttons[1] attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0];
}
[view addConstraint:widthConstraint];
当我调整某些特定按钮时,我需要确保我只使用 if 语句更改它们的约束。然后使用倍增器,您可以将它们的宽度设置为视图中其他按钮的倍增器。
希望这对以后的人有所帮助,即使它只是将自定义键盘代码从 swift 翻译成 objective c
注意:请记住为要约束的视图设置 translatesAutoresizingMaskIntoConstraints。例如
view.translatesAutoresizingMaskIntoConstraints = NO;
如果你遗漏了它,那么即使你的约束条件都是正确的,它也不会起作用
我正在尝试以编程方式创建自定义键盘。我已经设法让键盘的功能正常工作,但我正在努力以编程方式设置约束。
我已经设法找到代码来限制按钮在它们的行中大小相等,但无法对其进行足够的自定义以设置某些按钮的宽度(或比例宽度)。
这是当前键盘的图片
每一行都是一个单独的 UIView,其中填充了与每个键对应的 UIButton。然后我将每个视图内的按钮限制到它们的超级视图。
问题是我希望 space 按钮是屏幕的固定比例,并且第 4 行按钮的宽度相同(目前它们稍微宽一点,只有 9 个按钮而不是10 个)
虽然它是为 swift 编写的,但我已经从自定义键盘教程中改编了大量代码:here
- (void)addConstraintsToView: (UIView *)view {
NSArray * buttons = view.subviews;
for (UIButton * button in buttons) {
NSInteger index = [view.subviews indexOfObject:button];
NSLayoutConstraint * topConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1.0f constant:1.0f];
NSLayoutConstraint * bottomConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-1.0f];
NSLayoutConstraint * leftConstraint;
// If the first button in the row
if (!index) {
leftConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:1.0f];
}
else {
leftConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:buttons[index-1] attribute:NSLayoutAttributeRight multiplier:1.0f constant:1.0f];
NSLayoutConstraint * widthConstraint = [NSLayoutConstraint constraintWithItem:buttons[0] attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0];
[view addConstraint:widthConstraint];
}
NSLayoutConstraint * rightConstraint;
// If the last button in the row
if (index == buttons.count - 1) {
rightConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeRight multiplier:1.0f constant:-1.0f];
}
else {
rightConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:buttons[index+1] attribute:NSLayoutAttributeLeft multiplier:1.0f constant:-1.0f];
}
[view addConstraints:@[topConstraint, bottomConstraint, rightConstraint, leftConstraint]];
}
}
这是当前将按钮限制为等宽的代码。
主要问题是,虽然有很多关于如何使用 NSlayoutConstraint 的'tutorials',但它们主要是为少数视图提供的。然后他们使用 then names 并设置约束。
This one is probably the best, this one has the problem that I mentioned, each button is allocated and used as a local variable.
为此,因为我们要添加更多的视图,然后将每个按钮作为其自己的变量会太复杂。如果我能弄明白的话,在循环中使用几个 if 语句会更优雅。
我真正希望它能够将某些按钮设置为固定宽度或比例宽度。例如,shift 按钮和删除按钮各占屏幕的 15%,或者 shift 和 delete 按钮固定为 48 像素。
如有任何帮助,我们将不胜感激
感谢@rdelmar 帮助我实现这个解决方案
虽然网上有很多关于 NSLayoutConstraints 的信息,但他们需要一些时间来适应。在这种情况下,我过度思考了问题,需要有人指出明显的问题。
所以在这种情况下,我试图改变按钮的宽度,所以我需要担心的是宽度限制。其他可以忽略。
这种情况下调整从其他来源获得的代码以满足我的需要的困难。
NSLayoutConstraint * widthConstraint;
if ([button.titleLabel.text isEqualToString:@"SHFT"] || [button.titleLabel.text isEqualToString:@"DEL"]) {
// Make sure to set the button it is in relation to - in this case we can set it with relation to any of this middle buttons so buttons[1] is fine
widthConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:buttons[1] attribute:NSLayoutAttributeWidth multiplier:1.5f constant:0];
}
else if ([button.titleLabel.text isEqualToString:@"space"]) {
widthConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:buttons[1] attribute:NSLayoutAttributeWidth multiplier:3.0f constant:0];
}
else {
widthConstraint = [NSLayoutConstraint constraintWithItem:buttons[1] attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0];
}
[view addConstraint:widthConstraint];
当我调整某些特定按钮时,我需要确保我只使用 if 语句更改它们的约束。然后使用倍增器,您可以将它们的宽度设置为视图中其他按钮的倍增器。
希望这对以后的人有所帮助,即使它只是将自定义键盘代码从 swift 翻译成 objective c
注意:请记住为要约束的视图设置 translatesAutoresizingMaskIntoConstraints。例如
view.translatesAutoresizingMaskIntoConstraints = NO;
如果你遗漏了它,那么即使你的约束条件都是正确的,它也不会起作用