热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

以编程方式更改视图以使其向左或向右对齐-Changingaviewprogrammaticallytoalignleftorright

IhavebeenbuildingthischatandIamstuckinsomethingthatIcantfigureoutyet.我一直在做这个聊天,我被

I have been building this chat and I am stuck in something that I can't figure out yet.

我一直在做这个聊天,我被困在一个我还不知道的事情上。

I have been unsuccessfully trying to align the same view left or right according to the scenario but I haven't gotten the desired result yet.

我一直试图根据场景将相同的视图向左或向右对齐,但没有成功,但我还没有得到预期的结果。

Basically, I built the cell in interface builder and pinned to the left and made its width and height variable according to the contents of the labels inside.

基本上,我在interface builder中构建了单元格,并将其固定在左侧,并根据内部标签的内容来设置其宽度和高度变量。

What I have been trying to do is reusing the same cell and align to the right when the I am the one sending the message (yellow) because by default it will be aligned to the left when others send me a message (gray) see the following image for illustration:

我一直在做的是重复使用相同的单元格,当I是发送消息的那个人(黄色)时向右对齐,因为默认情况下,当其他人向我发送消息(灰色)时,它将向左对齐,请参见下面的图片来说明:

enter image description here

What I want is:

我想要的是:

others messages--------

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

--------------my message

- - - - - - - - - - - - - - - -我的信息

To accomplish this, and under TroyT's suggestion, I activated and deactivated the leading/trailing constraints according to my needs.

为了实现这一目标,在TroyT的建议下,我根据自己的需要激活并停用了前导/后导限制。

So what I did was.

我所做的是。

  1. On my UITableViewCell Class, I created two @IBoulets for my two constraints like so:

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

    @IBOutlet var bubbleViewLeading: NSLayoutConstraint!

    @IBOutlet var bubbleViewLeading:NSLayoutConstraint !

    @IBOutlet var bubbleViewTrailing: NSLayoutConstraint!

    @IBOutlet var bubbleViewTrailing:NSLayoutConstraint !

  2. Later, in my tableViewController on the method cellForRowAtIndexPAth , I activate or deactivate one of the constraints according to my needs doing the following.

    后来,在我的tableViewController中,在方法cellForRowAtIndexPAth中,我根据需要执行以下操作,激活或停用其中一个约束。

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

cell.bubbleViewTrailing。= true cell.bubbleViewLeading活跃。积极= false

or the opposite

或者是相反的

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

cell.bubbleViewTrailing。= false cell.bubbleViewLeading活跃。积极= true

where the constraint set to "True" is set to 0. As I mentioned before, this work well for all cells except the first one.

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

  1. This works PARTIALLY, because for some reason it does not affect the first row and both constraints stay activated, hence the row is stretched through the tableview's width like so:.
  2. 这部分是有效的,因为出于某种原因,它不会影响第一行,并且两个约束都被激活,因此这一行被拉伸到tableview的宽度,就像这样:。

enter image description here

I tried several things like:

我尝试了几件事:

  • Using the init method from my UITableViewCell class to change the constraints
  • 使用我的UITableViewCell类中的init方法来更改约束
  • Changing the constraints from the awakeFromNib method within my UITableViewCell
  • 在UITableViewCell中修改awakeFromNib方法中的约束
  • Using the "User Defined Runtime Attributes" on the 3rd tab from the left on the storyboard, add a key path named "active", set the type to Bool, and set the value to false.
  • 使用故事板左侧第三个选项卡上的“用户定义的运行时属性”,添加名为“active”的关键路径,将类型设置为Bool,并将值设置为false。
  • unticking "installed" in the attribute inspector when I select the constraints in the storyboard
  • 当我在故事板中选择约束时,取消属性检查器中的“已安装”

However, none of these methods affect the constraints on the first cell but I can easily change everything else like the cell background or the text alignment in a label within the cell. It just the constraint that will not change for that first time that I use the cell. Even when I scroll down past the boundaries of the screen to "force" the cell reuse, the first cell becomes fixed:

但是,这些方法都不会影响第一个单元格上的约束,但是我可以很容易地更改单元格背景或单元格内标签中的文本对齐。它只是第一次使用单元格时不会改变的约束。甚至当我向下滚动屏幕边界以“强制”单元格重用时,第一个单元格也变得固定:

enter image description here

I have been trying to figure this one out for days with little success. Hence, I decided to put a bounty on this question.

我一直试着把这一天弄清楚,但收效甚微。因此,我决定悬赏这个问题。

3 个解决方案

#1


1  

What you explain makes little sense to me, but if it is happening only with the first row, then I would try forcing the layout to redraw by doing:

你的解释对我来说没有什么意义,但是如果它只发生在第一行,那么我将尝试通过以下操作来迫使布局重新绘制:

cell.setNeedsLayout() cell.layoutIfNeeded()

cell.layoutIfNeeded cell.setNeedsLayout()()

from the cellForRowAtIndexPath

从cellForRowAtIndexPath

BTW, I think a better approach would be to register 2 different cells, and create them both in IB. This approach will keep your code shorter and will allow you to modify not only the trailing/leading but also colors, fonts or whatever you need. You give them 2 different IDs, but keep the same implementation class, and you just deque the one you need on your cellForRowAtIndexPath.

顺便说一句,我认为更好的方法是注册两个不同的单元格,并在IB中创建它们。这种方法将使您的代码更短,不仅允许您修改尾随/引导,还可以修改颜色、字体或任何您需要的东西。您给它们两个不同的id,但是保持相同的实现类,并且您只需要在cellForRowAtIndexPath上做一个您需要的。

Keeping a different cell per style is the standard way to do these things with IB.

每个样式都保留一个不同的单元格是处理IB的标准方法。

#2


1  

removeConstraint: is deprecated, in favor of using the active property instead (or NSLayoutConstraint's deactivateConstraints:). While removeConstraint: still usually works, combining that with setting your constraints' active property makes this worse. Either use all activate and deactivate (preferred) or use add and remove.

removeConstraint:已弃用,改为使用活动属性(或NSLayoutConstraint的反激活约束:)。虽然removeConstraint:仍然正常工作,但是结合设置约束的活动属性会使情况变得更糟。要么使用所有激活和停用(首选),要么使用添加和删除。

So instead of cell.removeConstraint:, use this:

而不是细胞。removeConstraint:用这个:

cell.bubbleViewTrailing.active = false

One thing I may note is that your leading and trailing is reversed. Leading is on the left and trailing is on the right, except for right-to-left localization.

有一件事我可能会注意到,你的领先和落后是颠倒的。前导在左边,尾在右边,除了从右到左定位。

#3


0  

Here is the Custom ChatMessageCell that I have implemented for you in which I have applied programmatically constrains using the KVConstraintExtensionsMaster library to apply constraints that I have implemented.

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

I have update the leading & trailing constraints Constant value instead of activate/deactivate constraint or remove/add constraint.

我更新了引导和跟踪约束常量值,而不是激活/停用约束或删除/添加约束。

I hope this may help you.

我希望这能对你有所帮助。

Put below code in ChatMessageCell.h header file

在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

Put below code in ChatMessageCell.m file

在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

Put the below code in the viewDidLoad method ofyour ViewController is:

在视图控制器的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;

Now implement UITableView DataSource in your ViewController

现在在视图控制器中实现UITableView数据源

- (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;
}

推荐阅读
author-avatar
49897801g9Iq
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有