如何使用 NSLayoutConstraints 以编程方式将 UIView 中的 UIButtons 限制为成比例的宽度 [英] How can I programatically constrain UIButtons in a UIView to proportional widths using NSLayoutConstraints

查看:63
本文介绍了如何使用 NSLayoutConstraints 以编程方式将 UIView 中的 UIButtons 限制为成比例的宽度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试以编程方式创建自定义键盘.我已经设法使键盘的功能正常工作,但正在努力以编程方式设置约束.

I am trying to create a custom keyboard programatically. I have managed to get the functionality of the keyboard working but am struggling with setting the constraints programatically.

我已经设法找到代码来限制按钮在它们的行中的大小相等,但无法对其进行足够的自定义以设置某些按钮的宽度(或比例宽度).

I have managed to find code to constrain the buttons to be equal sizes in their rows but cannot customise it enough to set the width (or proportional width) of certain buttons.

这是当前键盘的图片

每一行都是一个单独的 UIView,填充了与每个键对应的 UIButton.然后我将每个视图中的按钮限制为它们的超级视图.

Each row is a separate UIView filled with UIButtons corresponding to each key. I then constrain the buttons inside each view to their superview.

问题是我希望空格按钮是屏幕的固定比例,并且第 4 行按钮的宽度相同(目前它们稍微宽一些,只有 9 个按钮而不是 10 个按钮)

The issue is that I want the space button to be a set proportion of the screen and also the 4th row buttons to be the same width (currently they are very slightly wider only having 9 buttons instead of 10 across)

虽然它是为 swift 编写的,但我已经改编了自定义键盘教程中的大量代码:这里

Although it is written for swift I have adapted quite a bit of code from the Custom Keyboard tutorial: 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]];
    }
}

这是当前限制按钮宽度相等的代码.

This is the code currently constraining the buttons to be equal widths.

主要问题是,虽然有很多关于如何使用 NSlayoutConstraint 的教程",但它们主要是为少量视图提供的.然后他们使用 then 名称并设置约束.

The main problem is that although there is lots of 'tutorials' on how to use NSlayoutConstraint they are mainly provided for a small number of views. They then use then names and set the constraints.

这个可能是最好的,这个有问题我提到过,每个按钮都被分配并用作局部变量.这个问题很相似,但略有不同,观看次数少得多.

This one is probably the best, this one has the problem that I mentioned, each button is allocated and used as a local variable. This question is similar but subtly different and for a much smaller number of views.

为此,因为我们要添加更多的视图,所以将每个按钮作为自己的变量会过于复杂.如果我能弄清楚,那么在循环中使用几个 if 语句会更优雅.

For this as we are adding a much larger number of views then having each button as its own variable would be much too complex. Instead using a couple of if statements inside the loop would be much more elegant if I can figure it out.

我真正希望它能够将某些按钮设置为固定宽度或比例宽度.例如,shift 按钮和delete 按钮各占屏幕的15%,或者shift 和delete 按钮固定为48 像素.

What I really want it to be able to set certain buttons to either fixed widths or proportional widths. Eg the shift button and delete button to be 15% of the screen each or the shift and delete button to be fixed at 48 pixels.

任何帮助将不胜感激

推荐答案

感谢@rdelmar 帮助我解决这个问题

Thanks to @rdelmar for helping me toward this solution

虽然网上有很多关于 NSLayoutConstraints 的信息,但他们需要一点时间来适应.在这种情况下,我想得太多了,需要有人指出显而易见的问题.

Although there is lots of information on NSLayoutConstraints online they take a bit of time to get used to. In this case I was over thinking the problem and needed someone to point out the obvious.

所以在这种情况下,我试图改变按钮的宽度,所以我需要担心的是宽度约束.其余的可以忽略.

So in this case I am trying to change the widths of the buttons so all I need to worry about is the width constraint. The rest can be ignored.

调整从其他来源获得的代码以满足我的需要的难度.

The difficulty of this case adjusting the code gained from other sources to suit my need.

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 语句更改它们的约束.然后使用乘数,您可以将它们的宽度设置为视图中其他按钮的乘数.

As I am adjusting certain specific buttons I need to make sure I only change the constraints of them with the if statements. Then using the multiplier you can set their width as a multiplier of the other buttons in the view.

希望这对将来的人有所帮助,即使只是将自定义键盘代码从 swift 转换为objective c

Hopefully this helps someone in the future even if it just the custom keyboard code translated from swift to objective c

注意:请记住为您要约束的视图设置 translatesAutoresizingMaskIntoConstraints.例如

NOTE: Remember to set the translatesAutoresizingMaskIntoConstraints for the view you are constraining. eg

view.translatesAutoresizingMaskIntoConstraints = NO;

如果你忽略这一点,即使你的约束都是正确的,它也不会工作

If you leave this out then it won't work even if your constraints are all correct

这篇关于如何使用 NSLayoutConstraints 以编程方式将 UIView 中的 UIButtons 限制为成比例的宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆