首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >重写继承类中的NSLayoutConstraint

重写继承类中的NSLayoutConstraint
EN

Stack Overflow用户
提问于 2018-06-19 00:13:55
回答 2查看 176关注 0票数 1

我的代码中有两个类,一个是NameCell,它包含一个带有文本的简单UILabel。第二个是继承自该类的NameValueCell,但也添加了属性UIView *valueView

需要更改一个布局约束。我正在寻找一种方法来覆盖:

H:|[nameView]| - nameView应在NameCell中占据全角

使用

NameValueCell中,H:|[nameView][valueView(==nameView)]| - nameViewvalueView的宽度比例应为1:1

覆盖NSLayoutConstraint的最佳实践是什么?我必须在代码中坚持继承,因为我的应用程序需要许多不同的UITableViewCell专门化。

NameCell.h

代码语言:javascript
复制
@interface NameCell : UITableViewCell

@property (nonatomic, retain) IBOutlet UIView *nameView;
@property (nonatomic, retain) IBOutlet UILabel *nameLabel;

@end

名称ValueCell.h:

代码语言:javascript
复制
@interface NameValueCell : NameCell

@property (nonatomic, retain) IBOutlet UIView *valueView;

@end

NameCell.com:

代码语言:javascript
复制
@implementation NameCell

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

        UIView *nameView = [[UIView alloc] init];
        self.nameView = nameView;
        [self.contentView addSubview:self.nameView];

        UILabel *nameLabel = [[UILabel alloc] init];
        self.nameLabel = nameLabel;
        [self.nameView addSubview:self.nameLabel];

        NSDictionary *views = NSDictionaryOfVariableBindings(nameView, nameLabel);
        NSArray *constraints;

        // The constraint that should be overridden
        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameView]|"
                                                              options: 0
                                                              metrics:nil
                                                                views:views];

        [self.contentView addConstraints:constraints];        
    }
    return self;
}

@end

NameValueCell.m:

代码语言:javascript
复制
@implementation NameValueCell

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

        UIView *valueView = [[UIView alloc] init];
        self.valueView = valueView;
        [self.contentView addSubview:self.valueView];

        NSDictionary *views = @{
                                @"nameView": self.nameView,
                                @"nameLabel": self.nameLabel,
                                @"valueView": self.valueView
                                };
        NSArray *constraints;

        // The overriding constraint
        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameView][valueView(==nameView)]|"
                                                                       options: 0
                                                                       metrics:nil
                                                                         views:views];

        [self.contentView addConstraints:constraints];        
    }
    return self;
}

@end
EN

回答 2

Stack Overflow用户

发布于 2018-06-19 01:17:04

子类希望增强超类行为,例如,通过添加额外的子视图;但它也希望在创建约束时覆盖超类。要做到这两点,最好的方法是分解视图创建和约束创建代码,然后在子类中,通过有选择地调用super来控制是增强还是覆盖。

首先,考虑因素...

代码语言:javascript
复制
// in NameCell.m initWithStyle
// super initWithStyle..., if (self) { ...
[self addCustomSubviews];
[self addCustomConstraints];

NameCell中,这些新方法应该完全按照问题中的内联方式实现,但在子类中实现:(1)根本不实现init,允许超类init调用分解后的代码,以及(2)覆盖分解后的代码,如下所示……

代码语言:javascript
复制
// NameValueCell.m
- (void)addCustomSubviews {
    // augmenting super here, so call super...
    [super addCustomSubviews];

    // add the value view
    UIView *valueView = [[UIView alloc] init];
    // and so on
}

- (void)addCustomConstraints {
    // overriding super here, so don't call super, just add constraints
    NSDictionary *views = @{
       // and so in
}

代码语言:javascript
复制
// in NameValueCell.m, in the initWithStyle method, before creating constraints
[self removeConstraints:self.constraints];  // then ...
NSDictionary *views = @{ // and so on...

我不认为这是一种最佳的(甚至是好的)实践,但我认为它应该是可行的。

票数 1
EN

Stack Overflow用户

发布于 2018-06-19 07:30:07

第一:不要添加约束;激活它们。它要简单得多,也不容易出错。

那好吧。只需在NSArray实例变量中保留对可能需要替换的约束的引用:

代码语言:javascript
复制
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameView]|"
                                                      options: 0
                                                      metrics:nil
                                                        views:views];
self.removeableConstraints = constraints; // an instance property
[NSLayoutConstraint activateConstraints: constraints];

现在,子类要做的就是停用self.removeableConstraints并激活它的替换约束。

代码语言:javascript
复制
[NSLayoutConstraint deactivateConstraints: self.removeableConstraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameView][valueView(==nameView)]|"
                                                      options: 0
                                                      metrics:nil
                                                        views:views];
[NSLayoutConstraint activateConstraints: constraints];

这是换出约束的一般模式,这里的类/子类关系没有理由不使用它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50913608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档