- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我很难弄清楚如何在约束条件下获得我想要的结果。我可以通过编程方式执行此操作,但似乎应该有更好的方法。
基本上我有一个键盘。
最左边的键(Q)和最右边的键(P)应该从左右两边相隔3个点。
Q 和 P 键之间的 8 个键应该在 Q 和 P 键之间等距
键的宽度应拉伸(stretch)以填满 Q 键和 P 键之间的整个宽度,同时仍保持彼此之间的间距相等。
基本上,当横向旋转时,键盘应该执行 Apple 原生键盘的操作。
这可以在有约束的情况下完成吗,还是我需要在没有约束的情况下以编程方式执行此操作?
最佳答案
是的。自动布局可以做到这一点。
如果您希望布局在横向和纵向方向上保持相同(我很确定您这样做),那么一旦设置好约束,一切都应该正常工作。如果您希望它们发生变化,那是可能的,但我不打算解决这个问题,因为它似乎没有必要。
在你的问题中,你说:
Can this be done with constraints or do I need to do this programmatically without constraints?
我不确定,但我想确认您是否理解自动布局不仅仅是界面构建器。您还可以通过操作 NSLayoutConstraint
并将它们添加到 View 中,从代码中非常自然地使用自动布局。因此,您可能至少有三种选择:
layoutSubviews:
或类似的东西中移动您的 View 。您可以在 IB 中设置所有这些。每个键都需要两个水平约束和两个垂直约束,因此您将为 26 键键盘管理至少 104 个约束。加上数字。和符号。 手动执行此操作会非常痛苦,当您正确执行此操作时,您团队中的某个人(甚至可能是您)将决定键间距只需要多一个像素即可。
键盘网格具有如此多的规律性和如此多的约束,因此只需使用一些代码来设置约束会容易得多。
明确一点:您仍将使用自动布局,但您将使用代码创建约束,而不是手动维护它们。
我假设您希望键具有相同的大小。您可以强加这一点,以及它们之间相等的(指定的)间距以及父 View 左右两侧的固定边距,并具有如下约束:
// Substitute your view names here.
UIButton *q, *w, *e, *r, *t, *y, *u, *i, *o, *p;
NSDictionary *const metrics = @{@"margin": @(3), @"gap": @(4)};
NSDictionary *const views = NSDictionaryOfVariableBindings(q,w,e,r,t,y,u,i,o,p);
NSArray *const constraints =
[NSLayoutConstraint
constraintsWithVisualFormat:
@"H:|-margin-[q]-gap-[w(q)]-gap-[e(q)]-gap-[r(q)]-gap-[t(q)]-gap-[y(q)]-gap-[u(q)]-gap-[i(q)]-gap-[o(q)]-gap-[p(q)]-margin-|"
options: NSLayoutFormatDirectionLeadingToTrailing
metrics: metrics
views: views];
// Add constraints to your container view so that they do something.
UIView *const container = [self view];
[container addConstraints: constraints];
但我很想构建一个辅助方法,该方法采用一组 View 并从中生成约束。它会像这样:
-(NSArray *) constraintsForEqualSizeViews: (NSArray *) keys
withSuperviewMargin: (CGFloat) margin
andSpace: (CGFloat) space
{
NSMutableArray *const constraints = [NSMutableArray new];
// Note: the keys must be in a superview by now so that
// a constraint can be set against its edge.
UIView *const leftKey = [keys firstObject];
[constraints addObject:
[NSLayoutConstraint constraintWithItem: leftKey
attribute: NSLayoutAttributeLeft
relatedBy: NSLayoutRelationEqual
toItem: [leftKey superview]
attribute: NSLayoutAttributeLeft
multiplier: 0
constant: margin]];
UIView *const rightKey = [keys firstObject];
[constraints addObject:
[NSLayoutConstraint constraintWithItem: rightKey
attribute: NSLayoutAttributeRight
relatedBy: NSLayoutRelationEqual
toItem: [rightKey superview]
attribute: NSLayoutAttributeRight
multiplier: 0
constant: margin]];
UIView *const templateKeyForEqualSizes = leftKey;
NSDictionary *const metrics = @{@"space": @(space)};
for(NSUInteger i=1; i<[keys count]; ++i)
{
NSDictionary *const views = @{@"previousKey": keys[i-1],
@"thisKey": keys[i],
@"templateKey": templateKeyForEqualSizes};
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat: @"H:[previousKey]-space-[thisKey(templateKey)]"
options: NSLayoutFormatDirectionLeftToRight
metrics: metrics
views: views]];
}
NSArray *const immutableArrayToReturn = [constraints copy];
return immutableArrayToReturn;
}
自动布局语言在Apple's documentation 中描述。 .
UIView
框架您无需考虑为键的 View 设置原始框架——这是远离用于描述键的界面生成器的另一个原因。您可以像这样创建 View :
-(NSArray*) keyRowArray: (NSString*) keyNamesString
{
const NSUInteger keyCount = [keyNamesString length];
NSMutableArray *const keys = [NSMutableArray arrayWithCapacity: keyCount];
for(NSUInteger i=0; i<keyCount; ++i)
{
NSString *const keyName = [keyNamesString substringWithRange:NSMakeRange(i, 1)];
// Look! No frame needed!
XXYourCustomKeyView *const key = [XXYourCustomKeyView new];
// Do key setup – you probably want to add button actions, and such.
[key setName: keyName];
[keys addObject: keyName];
}
return [keys copy];
}
UIView
所有权我不会直接在 UIViewController 中管理所有这些键。我将它们封装在一个 XXYourCustomKeyboardView
类中,该类可以接受键盘描述(类似于键盘行的字符串数组)。您的 Controller 可以创建它,传递配置,将自己设置为委托(delegate)和快乐的日子。
您也可以使用混合方法,在 IB 中设置一些键和约束:
然后您可以使用与上述类似的代码在这些键之间添加键。
根据我上面给出的约束创建方法,如果将它拆分为 NSLayoutConstraint
类别中的单独方法,您可能会发现它更灵活:
@interface NSLayoutConstraint (Keyboard)
// This is what it constraint method currently creates in the for loop.
+(NSArray*) constraintsForViews: (NSArray*) views imposingEqualSpace: (CGFloat) space;
+(NSArray*) constraintsForViewsImposingEqualWidth: (NSArray*) views;
// This will also be useful to align a whole row.
+(NSArray*) constraintsForViewsImposingSameTopAndBottom: (NSArray*) views;
@end
如果有任何不清楚的地方,请在评论中告诉我。如有必要,我会添加说明。
关于ios - 如何让约束自动调整大小和重新定位横向键盘键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24788261/
这个问题在这里已经有了答案: C sizeof a passed array [duplicate] (7 个回答) 8年前关闭。 在一个函数中,我声明了一个数组: int char_count_ar
简而言之,文件系统如何与 block 设备通信? 最佳答案 我对 block 大小不太了解。我认为 ext4(Linux)的文件系统的 block 大小是 4KB,考虑到现代处理器的页面大小(4KB)
我知道 tinyint(1) 和 tinyint(2) 具有相同的存储空间范围。 唯一的区别是显示宽度不同。这是否意味着 tinyint(1) 将存储所有类型的整数但只正确显示 0 到 9 的范围?而
今晚我已经研究了以下代码几个小时,但我只是摸不着头脑。 当使用函数从标准输入填充数组时,我不断收到“大小 8 的无效写入”和“大小 8 的无效读取”。 如有任何帮助,我们将不胜感激...我知道 Sta
我有一个 valgrind 错误,我不知道如何摆脱它们: ==5685== Invalid read of size 8 ==5685== at 0x4008A1: main (in /home
我对 Hadoop 的概念有点困惑。 Hadoop block 大小、拆分大小和 block 大小 之间有什么区别? 提前致谢。 最佳答案 block 大小和 block 大小相同。 拆分大小 可能与
我想不出一个好的标题,所以希望可以。 我正在做的是创建一个离线 HTML5 webapp。 “出于某些原因”我不希望将某些文件放在缓存 list 中,而是希望将内容放在 localStorage 中。
无法将 xamarin apk 大小减少到 80 MB 以下,已执行以下操作: 启用混淆器 配置:发布 平台:事件(任何 CPU)。 启用 Multi-Dex:true 启用开发人员检测(调试和分析)
我正在开发一个程序,需要将大量 csv 文件(数千个)加载到数组中。 csv 文件的尺寸为 45x100,我想创建一个尺寸为 nx45x100 的 3-d 数组。目前,我使用 pd.read_csv(
Hello World 示例的 React Native APK 大小约为 20M (in recent versions),因为支持不同的硬件架构(ARMv7、ARMv8、X86 等),而同一应用程
我有一个包含 n 个十进制元素的列表,其中每个元素都是两个字节长。 可以说: x = [9000 , 5000 , 2000 , 400] 这个想法是将每个元素拆分为 MSB 和 LSB 并将其存储在
如何设置 GtKTextView 的大小?我想我不能使用 gtk_widget_set_usize。 最佳答案 您不能直接控制小部件的大小,而是由其容器完成。您可以使用 gtk_widget_set_
这个问题在这里已经有了答案: c++ sizeof() of a class with functions (7 个答案) 关闭 5 年前。 结果是 12。 foobar 函数存储在内存中的什么位置
当我在 ffmpeg(或任何其他程序)中使用这样的命令时: ffmpeg -i input.mp4 image%d.jpg 所有图像的组合文件大小总是比视频本身大。我尝试减少每秒帧数、降低压缩设置、模
我是 clojurescript 的新手。 高级编译后出现“77 KB”的javascript文件是否正常? 我有一个 clojurescript 文件: 我正在使用 leinigen: lein c
我想要一个 QPixmap尺寸为 50 x 50。 我试过 : QPixmap watermark(QSize(50,50)); watermark.load(":/icoMenu/preparati
我正在尝试从一篇研究论文中重新创建一个 cnn,但我对深度学习还是个新手。 我得到了一个大小为 32x32x7 的 3d 补丁。我首先想执行一个大小为 3x3 的卷积,具有 32 个特征和步幅为 2。
我一直在尝试调整 View Controller 内的 View 大小,但到目前为止没有运气。基本上,我的 View 最底部有一个按钮,当方向从纵向更改为横向时,该按钮不再可见,因为它现在太靠下了。
如何使用此功能检查图像的尺寸?我只是想在上传之前检查一下... $("#LINK_UPLOAD_PHOTO").submit(function () { var form = $(this);
我用 C++ 完成了这个,因为你可以通过引用传递参数。我无法弄清楚如何在 JavaScript 中执行此操作。我的代码需要更改什么?我的输出是1 this.sizeOfBst = function()
我是一名优秀的程序员,十分优秀!