UITableViewCell 中的 UITextField 使用自动布局
Posted
技术标签:
【中文标题】UITableViewCell 中的 UITextField 使用自动布局【英文标题】:UITextField within UITableViewCell using auto layout 【发布时间】:2013-11-11 02:48:04 【问题描述】:我有一个UITableViewController
,它显示一个部分和一个单元格(测试用例)。
在那个单元格中,我有一个UITextField
,它应该跨越单元格contentView
的长度,两边各有20 个点(即H:|-20-[field]-20-|
)并垂直居中。
当我使用带有必要约束的笔尖时,它可以完美地工作,但是当我以编程方式添加约束时,它似乎没有遵循它们。 (见图片。)
-tableView:willDisplayCell:forRowAtIndexPath:
中的NSLog()
在两种情况下打印完全相同的约束。
FOOAppDelegate.m:
#import "FOOAppDelegate.h"
#import "FOORootViewController.h"
@implementation FOOAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController *controller = [[UINavigationController alloc] initWithRootViewController:[[FOORootViewController alloc] initWithStyle:UITableViewStyleGrouped]];
self.window.rootViewController = controller;
[self.window makeKeyAndVisible];
return YES;
@end
FOORootViewController.m:(注意:被声明为 UITextFieldDelegate)
#import "FOORootViewController.h"
enum kFOOTextFieldTag = 0xFEED /* Arbitrary. */ ;
@implementation FOORootViewController
- (id)initWithStyle:(UITableViewStyle)style
self = [super initWithStyle:style];
if (self)
self.title = @"Foo";
self.navigationItem.rightBarButtonItem = self.editButtonItem;
return self;
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
[super setEditing:editing animated:animated];
[self.tableView reloadData];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return 1;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"FooCell";
/* Uncomment the following line when using nib. */
//[self.tableView registerNib:[UINib nibWithNibName:@"FooCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:CellIdentifier];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
/* Comment this if block when using nib. */
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
/* Comment this if block when using nib. */
if (self.editing && ([cell.contentView viewWithTag:kFOOTextFieldTag] == nil))
UITextField *field = [[UITextField alloc] init];
field.autocapitalizationType = UITextAutocapitalizationTypeSentences;
field.borderStyle = UITextBorderStyleLine;
field.delegate = self;
field.placeholder = @"New";
field.tag = kFOOTextFieldTag;
field.translatesAutoresizingMaskIntoConstraints = NO;
field.userInteractionEnabled = YES;
[cell.contentView addSubview:field];
NSDictionary *objs = NSDictionaryOfVariableBindings(cell.contentView, field);
cell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-7-[field]"
options:0
metrics:nil
views:objs]];
[cell.contentView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[field]-6-|"
options:0
metrics:nil
views:objs]];
[cell.contentView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-20-[field]"
options:0
metrics:nil
views:objs]];
[cell.contentView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:[field]-20-|"
options:0
metrics:nil
views:objs]];
return cell;
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
UITextField *field = (UITextField *)[cell.contentView viewWithTag:kFOOTextFieldTag];
if (self.editing)
field.hidden = NO;
NSLog(@"field: %@", field);
else
field.hidden = YES;
NSLog(@"cell.contentView: %@", cell.contentView);
NSLog(@"constraints: %@", cell.contentView.constraints);
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
return YES;
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
return UITableViewCellEditingStyleInsert;
这是我不使用笔尖时得到的结果(横向时没有区别):
这就是我用笔尖得到的(适合横向缩放):
【问题讨论】:
我在单元格约束方面遇到了类似的问题,并通过在 tableView:willDisplayCell:forRowAtIndexPath: 中设置约束来解决它:而不是 tableView:cellForRowAtIndexPath:。似乎他们正在对尚未完全初始化的值进行操作。 【参考方案1】:你应该删除这行,它会正常工作:
cell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
您只需为自己添加的子视图将其设置为 NO。
另外,我注意到您在 cellForRowAtIndexPath 中注册了 nib(如果您使用的是 nib)——您不应该这样做,因为 cellForRowAtIndexPath 被多次调用。您应该将该代码放在 viewDidLoad 中。
另一件事——你应该简化你的约束代码。使用可视化格式语言的一大优势是可以在同一个语句中设置多个约束,因此可以将你的 4 个语句组合成 2 个:
cell.contentView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-7-[field]-6-|"
options:0
metrics:nil
views:objs]];
cell.contentView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-20-[field]-20-|"
options:0
metrics:nil
views:objs]];
【讨论】:
以上是关于UITableViewCell 中的 UITextField 使用自动布局的主要内容,如果未能解决你的问题,请参考以下文章
从 UIText 字段的用户输入更改 UIView 框架的高度和宽度
如何从 UITextfields UIMenuController 中删除不需要的 UIMenuItems?