gpt4 book ai didi

ios - AutoLayout 未将 subview 固定到 super View

转载 作者:行者123 更新时间:2023-12-01 19:27:33 24 4
gpt4 key购买 nike

我正在尝试将自定义 UITableViewCell 类内的 subview 固定到单元格 contentView 的左侧。我将 subview 添加到子类的 initWithStyle 方法内部的 contentView 中,并在该方法内部添加约束。不幸的是,我有两个问题:

  1. subview 没有固定到 contentView 的左边缘,即使我使用以下代码来执行此操作:

    [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_animatedView]-[_aTextField][_rightImageView]|"
    options:NSLayoutFormatDirectionLeftToRight
    metrics:nil views:viewDictionary]];

    对我来说,该格式字符串应该将 _animatedView 固定到 contentView 的左侧,然后尽可能靠近地附加其他后续 View 。相反,所有三个 View 以正确的顺序一起显示在 contentView 的中间,而不是在左边缘。我刚开始使用自动布局,因此这可能会导致我对格式字符串的工作方式感到困惑。

  2. 已解决:感谢 Guillaume 的建议,我能够进行一些测试,并发现当我滚动表格时单元格内容发生剧烈移位的原因是我没有重写 UITableViewCell 方法 prepareForReuse。当 UITableViewCell 准备重用以显示 UITableView 中另一个对象的信息时,会调用此方法,这在滚动发生时会偶然发生。解决方案非常简单,只需将以下代码插入到我的 UITableViewCell 子类中即可:

    -(void) prepareForReuse
    {
    [self setNeedsUpdateConstraints];
    }

另一个问题是,在我选择使用自定义单元格的 TableView 行之前,约束似乎不会强制执行。除了 initWithStyle 之外,我是否应该在其他地方设置约束,或者这是一个不同的问题?

更新:

CustomTableCell.m

@interface ListTableCell ()
{
NSDictionary *_viewsForConstraints; // Used inside updateConstraints method.
NSArray *_animatedViewSizeConstraints;
NSArray *_centeringConstraints;
NSArray *_horizontalConstraints;
}
@end

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// Set up the cell elements.
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

self.animatedView = [[AnimatedView alloc] initWithFrame:CGRectZero];
self.animatedView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.animatedView];

self.aTextField = [[UITextField alloc] initWithFrame:CGRectZero];
self.aTextField.textColor = [UIColor whiteColor];
self.aTextField.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.aTextField];

self.rightImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
self.rightImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.rightImageView];

_viewForConstraints = NSDictionaryOfVariableBindings(_animatedView,
_aTextField, _rightImageView);

// Add height/width constraints to the animated view.
NSLayoutConstraint *heightConstraint =
[NSLayoutConstraint constraintWithItem:self.animatedView attribute:NSLayoutAttributeHeight relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:self.contentView.frame.size.height];
NSLayoutConstraint *aspectRatioConstraint = [NSLayoutConstraint constraintWithItem:self.animatedView attribute:NSLayoutAttributeHeight relatedBy:0 toItem:self.animatedview attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];

_animatedViewSizeConstraints = @[heightConstraint, aspectRatioConstraint];

// Center elements vertically.

NSLayoutConstraint *animatedViewVerticalCenterConstraint =
[NSLayoutConstraint constraintWithItem:self.animatedView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.contentView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0];
NSLayoutConstraint *aTextFieldVerticalCenterConstraint =
[NSLayoutConstraint constraintWithItem:self.aTextField
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.contentView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0];
NSLayoutConstraint *rightImageVerticalCenterConstraint =
[NSLayoutConstraint constraintWithItem:self.rightImageView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.contentView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0];

_centeringConstraints = @[animatedViewVerticalCenterConstraint,
aTextFieldVerticalCenterConstraint, rightImageVerticalCenterConstraint];

_horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[_animatedView]-[_aTextField][_rightImageView]|"
options:NSLayoutFormatDirectionLeftToRight metrics:nil views:viewDictionary]];
self.backgroundColor = [UIColor greenColor];
self.editingAccessoryType = UITableViewCellAccessoryNone;
self.accessoryType = UITableViewCellAccessoryNone;
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.aTextField.userInteractionEnabled = NO;

[self setNeedsUpdateConstraints];
}

-(void) updateConstraints
{
[super updateConstraints];

[self.contentView addConstraints:_animatedViewSizeConstraints];
[self.contentView addConstraints:_centeringConstraints];
[self.contentView addConstraints:_horizontalConstraints];
}

TableViewController.m

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
CustomTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

// Configure the cell.
cell.aTextField.text = @"Test Text";
cell.aTextField.delegate = self;

return cell;
}

我可以确认 initWithStyle 正在被调用,因为背景始终为绿色并且 subview 始终显示,它们只是最初显示的间隔非常奇怪。

感谢您对此提供的任何帮助!

最佳答案

您应该在 updateConstraints 中设置约束方法。来自文档:

Custom views that set up constraints themselves should do so by overriding this method.

这应该至少解决你的第二个问题。

关于ios - AutoLayout 未将 subview 固定到 super View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17126943/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com