Spe*_*tak 3 objective-c ios autolayout nslayoutconstraint ios8
我很难弄清楚如何通过约束来获得我想要的结果.我可以通过编程方式执行此操作,但似乎应该有更好的方法.
基本上我有一个键盘.
最左边的键(Q)和最右边的键(P)应该是从左侧和右侧的3个点.
Q键和P键之间的8个键应在Q和P键之间等间隔
键应该在宽度上拉伸以填充Q和P键之间的整个空间宽度,同时仍然保持彼此之间的相等空间.
基本上键盘应该像Apple的原生键盘在横向旋转时那样做.
这可以通过约束来完成,还是我需要在没有约束的情况下以编程方式执行此操作?
是.自动布局可以做到这一点.
如果您希望布局在横向和纵向方向上保持相同(我很确定您这样做),那么一旦设置了约束,一切都应该正常工作.如果你想让它们改变,那是可能的,但我不打算解决这个问题,因为它似乎并不需要.
在你的问题中,你说:
这可以通过约束来完成,还是我需要在没有约束的情况下以编程方式执行此操作?
我不确定,但我想检查一下,你知道Auto Layout不仅仅是一个界面构建器.您也可以通过操作NSLayoutConstraints并将它们添加到视图中,自然地使用代码中的自动布局.所以,你可能至少有三个选择:
layoutSubviews:或类似的东西.您可以在IB中设置所有这些.每个键需要两个水平约束和两个垂直约束,因此您将为26键键盘管理至少104个约束.加数字.和符号.手动执行此操作将非常令人难以忍受,当您做对了,团队中的某个人(甚至可能是您)将决定键间距只需要多一个像素.
键盘网格具有如此多的规律性和许多约束条件,因此使用一些代码来设置约束会更容易.
需要说明的是:您仍将使用自动布局,但您将使用代码创建约束,而不是手动维护它们.
我假设您希望键具有相同的大小.您可以将它们与它们之间的相等(指定)间距和超级视图的左侧和右侧的固定边距强加,并使用如下约束:
// 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];
Run Code Online (Sandbox Code Playgroud)
但是我很想构建一个辅助方法,它可以获取一系列视图并从中生成约束.它会是这样的:
-(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;
}
Run Code Online (Sandbox Code Playgroud)
Apple的文档中描述了自动布局语言.
UIView 框架您不需要考虑为键的视图设置原始帧 - 这是远离接口构建器来描述键的另一个原因.您可以像这样创建您的视图:
-(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];
}
Run Code Online (Sandbox Code Playgroud)
UIView 所有权我不会直接在UIViewController中管理所有这些键.我将它们封装在一个XXYourCustomKeyboardView可以进行键盘描述的类中(类似于键盘行的字符串数组).您的控制器可以创建它,传递配置,将自己设置为委托和快乐的日子.
您也可以使用混合方法在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
Run Code Online (Sandbox Code Playgroud)
如果有任何不清楚的地方,请在评论中告诉我.如有必要,我会加上澄清.
| 归档时间: |
|
| 查看次数: |
544 次 |
| 最近记录: |