以编程方式更改视图以对齐左对齐

时间:2016-03-29 23:45:43

标签: swift interface-builder ios9 xcode7 nslayoutconstraint

我一直在建立这个聊天,我陷入了一些我无法弄清楚的事情。

我根据场景尝试左右对齐视图但未成功,但我还没有得到预期的结果。

基本上,我在界面构建器中构建了单元格并固定在左侧,并根据内部标签的内容使其宽度和高度可变。

我一直尝试做的是重复使用同一个单元格并在我发送消息的那个时向右对齐(黄色),因为默认情况下,当其他人向我发送消息时,它将与左边对齐(灰色) )见下图:

enter image description here

我想要的是:

其他消息--------

--------------我的留言

为了实现这一目标,根据TroyT的建议,我根据自己的需要激活和停用了前导/尾随约束。

所以我做的是。

  1. 在我的UITableViewCell类中,我为我的两个约束创建了两个@IBoulet:

    @IBOutlet var bubbleViewLeading:NSLayoutConstraint!

    @IBOutlet var bubbleViewTrailing:NSLayoutConstraint!

  2. 稍后,在方法 cellForRowAtIndexPAth 的tableViewController中,我根据需要激活或停用其中一个约束。

  3. cell.bubbleViewTrailing.active = true cell.bubbleViewLeading.active = false

    或相反的

    cell.bubbleViewTrailing.active = false cell.bubbleViewLeading.active = true

    其中约束设置为“True”设置为0.正如我之前提到的,这适用于除第一个之外的所有单元格。

    1. 这部分可行,因为由于某种原因它不会影响第一行,并且两个约束都会保持激活状态,因此行会延伸到tableview的宽度,如下所示:。
    2. enter image description here

      我尝试了几件事:

      • 使用我的UITableViewCell类中的init方法更改约束
      • 从我的UITableViewCell
      • 中的awakeFromNib方法更改约束
      • 使用故事板左侧第3个选项卡上的“用户定义的运行时属性”,添加名为“active”的密钥路径,将类型设置为Bool,并将值设置为false。
      • 在故事板中选择约束时,在属性检查器中取消“已安装”

      但是,这些方法都不会影响第一个单元格的约束,但我可以轻松更改其他所有内容,例如单元格背景或单元格内标签中的文本对齐方式。它只是第一次使用单元格时不会改变的约束。即使我向下滚动屏幕边界以“强制”重复使用单元格,第一个单元格也会固定:

      enter image description here

      我一直试图将这个问题弄清楚几天,但收效甚微。因此,我决定在这个问题上给予赏金。

3 个答案:

答案 0 :(得分:1)

不推荐使用

removeConstraint:,而是使用active属性(或NSLayoutConstraint的{​​{1}})。虽然deactivateConstraints:通常仍有效,但将其与设置约束“removeConstraint:属性相结合会使情况变得更糟。使用全部激活和停用(首选)或使用添加和删除。

因此,请使用此代码而不是active

cell.removeConstraint:

我可能注意到的一件事是你的领先和尾随是相反的。除了从右到左的本地化之外,领先位于左侧,尾随位于右侧。

答案 1 :(得分:1)

你解释的内容对我来说没什么意义,但如果它只发生在第一行,那么我会尝试通过这样做来强制重新布局:

cell.setNeedsLayout() cell.layoutIfNeeded()

来自cellForRowAtIndexPath

BTW,我认为更好的方法是注册2个不同的单元格,并在IB中创建它们。这种方法可以缩短你的代码,并且不仅可以修改尾随/前导,还可以修改颜色,字体或任何你需要的代码。你给他们2个不同的ID,但是保持相同的实现类,你只需要在cellForRowAtIndexPath上使用你需要的那个。

每种风格保持不同的单元格是使用IB执行这些操作的标准方法。

答案 2 :(得分:0)

以下是我为您实现的自定义ChatMessageCell,其中我已使用KVConstraintExtensionsMaster库以编程方式约束应用我已实施的约束。

我已更新领先&尾随约束常量值而不是激活/取消激活约束或删除/添加约束。

我希望这对你有所帮助。

将以下代码放在ChatMessageCell.h标题文件

typedef NS_ENUM(NSUInteger, Type) {
    TypeSender,
    TypeReceiver,
};

@interface ChatMessageCell : UITableViewCell

@property (assign, nonatomic) Type cellType;
@property (strong, nonatomic) UIView *msgBackgroundView;
@property (strong, nonatomic) UILabel *messageLabel;

@end

将以下代码放在ChatMessageCell.m文件

#import "ChatMessageCell.h"
#import "KVConstraintExtensionsMaster.h"

@implementation ChatMessageCell

- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self createAndConfigureViewHierarchy];
    }    
    return self;
}

- (void)createAndConfigureViewHierarchy
{
    _msgBackgroundView = [UIView prepareNewViewForAutoLayout];
    [self.contentView addSubview:_msgBackgroundView];

    _msgBackgroundView.backgroundColor = [UIColor clearColor];
    [_msgBackgroundView.layer setCornerRadius:6.0];

    _labelMessage = [UILabel prepareNewViewForAutoLayout];
    [_labelMessage setLineBreakMode:NSLineBreakByTruncatingTail];
    [_labelMessage setNumberOfLines:0];
    [_labelMessage setTextAlignment:NSTextAlignmentLeft];
    [_labelMessage setTextColor:[UIColor whiteColor]];
    self.labelMessage.backgroundColor = [UIColor clearColor];

    [_msgBackgroundView addSubview:_labelMessage];

    [self applyConstraints];
}

-(void)applyConstraints
{
    // now applying the constraints by using KVConstraintExtensionsMaster library
    CGFloat padding = 8.0;

    // adding Top and Bottom contraints of _msgBackgroundView
    [_msgBackgroundView applyTopAndBottomPinConstraintToSuperviewWithPadding:padding];

    // adding leading and trailing contraints of _msgBackgroundView
    [_msgBackgroundView applyLeadingAndTrailingPinConstraintToSuperviewWithPadding:padding];

    // adding Top and Bottom contraints of _msgBackgroundView
    [_labelMessage applyTopAndBottomPinConstraintToSuperviewWithPadding:padding];

    // adding leading and trailing contraints of _msgBackgroundView
    [_labelMessage applyLeadingAndTrailingPinConstraintToSuperviewWithPadding:padding];

}

-(void)setCellType:(Type)cellType
{
    switch (cellType) {
        case TypeSender:
        {
            [_msgBackgroundView setBackgroundColor:[UIColor redColor]];
            [_labelMessage setTextAlignment:NSTextAlignmentRight];

            // this method will change the Leading Pin Constraint Constant value by 100.0
            [_msgBackgroundView applyLeadingPinConstraintToSuperviewWithPadding:100.0];

            // this method will increase the Leading Pin Constraint Constant value with proper ratio only iPad
            [_msgBackgroundView updateAppliedConstraintConstantValueForIpadByAttribute:NSLayoutAttributeLeading];
            break;
        }

        case TypeReceiver:
        {
            [_msgBackgroundView setBackgroundColor:[UIColor redColor]];
            [_labelMessage setTextAlignment:NSTextAlignmentLeft];

            // this method will change the Trailing Pin Constraint Constant value by 100.0
            [_msgBackgroundView applyTrailingPinConstraintToSuperviewWithPadding:100.0];

            // this method will increase the Leading Pin Constraint Constant value with proper ratio only iPad
            [_msgBackgroundView updateAppliedConstraintConstantValueForIpadByAttribute:NSLayoutAttributeTrailing];
            break;
        }
    }

    [self.contentView setNeedsLayout];
    [self.contentView updateModifyConstraints];
}

-(void)prepareForReuse
{
    // this method will change the Leading And Trailing Pin Constraints Constant value by 8.0
    [_msgBackgroundView applyLeadingAndTrailingPinConstraintToSuperviewWithPadding:8.0];
    [super prepareForReuse];
}

@end

将以下代码放在ViewController的viewDidLoad方法中:

[self.tableView registerClass:ChatMessageCell.class forCellReuseIdentifier:@"KVChatMessageCell"];
self.tableView.rowHeight = UITableViewAutomaticDimension;
/* any estimated height but must be more than 2 */
self.tableView.estimatedRowHeight = 44.0;

现在在ViewController中实现UITableView DataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section{
    return messages.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath{
    static NSString *cellIdentifier = @"KVChatMessageCell";

    ChatMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    [cell.labelMessage setText:messages[indexPath.row]];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (indexPath.row%2 == 0) {
       // here all even cell are the sender type
        [cell setCellType:TypeSender];
    }
    else {
       // here all odd cell are the Receiver type
        [cell setCellType:TypeReceiver];
    }

    return cell;
}