设为首页 加入收藏

TOP

snapkit equalto和multipliedby方法(一)
2019-08-31 01:05:07 】 浏览:147
Tags:snapkit equalto multipliedby 方法

最近在使用snapkit过程中遇到一个问题,在github上搜索之后发现另外一个有趣的问题

frameImageContainer.snp.makeConstraints({ (make) in 
    make.width.equalTo(295).multipliedBy(0.2) 
    make.height.equalTo(355).multipliedBy(0.2) 
    make.top.equalToSuperview().offset(self.view.frame.height/8) 
    make.centerX.equalToSuperview(); 
})

看起来很理所当然的,明显不可以这样写,但是具体是什么原因呢,明明没有报任何错误和警告,但是.multipliedBy()方法却没有效果,那我们来看一下snapkit源码。

1.首先点进equalTo()方法,代码是这样的:

@discardableResult
    public func equalTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
        return self.relatedTo(other, relation: .equal, file: file, line: line)
    }

再点进relatedTo()方法:

internal func relatedTo(_ other: ConstraintRelatableTarget, relation: ConstraintRelation, file: String, line: UInt) -> ConstraintMakerEditable {
        let related: ConstraintItem
        let constant: ConstraintConstantTarget
        
        if let other = other as? ConstraintItem {
            guard other.attributes == ConstraintAttributes.none ||
                  other.attributes.layoutAttributes.count <= 1 ||
                  other.attributes.layoutAttributes == self.description.attributes.layoutAttributes ||
                  other.attributes == .edges && self.description.attributes == .margins ||
                  other.attributes == .margins && self.description.attributes == .edges else {
                fatalError("Cannot constraint to multiple non identical attributes. (\(file), \(line))");
            }
            
            related = other
            constant = 0.0
        } else if let other = other as? ConstraintView {
            related = ConstraintItem(target: other, attributes: ConstraintAttributes.none)
            constant = 0.0
        } else if let other = other as? ConstraintConstantTarget {
            related = ConstraintItem(target: nil, attributes: ConstraintAttributes.none)
            constant = other
        } else if #available(iOS 9.0, OSX 10.11, *), let other = other as? ConstraintLayoutGuide {
            related = ConstraintItem(target: other, attributes: ConstraintAttributes.none)
            constant = 0.0
        } else {
            fatalError("Invalid constraint. (\(file), \(line))")
        }
        
        let editable = ConstraintMakerEditable(self.description)
        editable.description.sourceLocation = (file, line)
        editable.description.relation = relation
        editable.description.related = related
        editable.description.constant = constant
        return editable
    }

可以看到上面红色部分,此时other可以转换为ConstraintConstantTarget类型,设置related的target为nil,attributes为none,constant设置为other,最后将这些变量赋值给description属性保存。

2.multipliedBy()方法:

@discardableResult
    public func multipliedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable {
        self.description.multiplier = amount
        return self
    }

可以看到,multipliedBy方法中只是简单的赋值,将amout值复制到description中保存。

3.再来看一下makeConstraints()方法:

internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
        let maker = ConstraintMaker(item: item)
        closure(maker)
        var constraints: [Constraint] = []
        for description in maker.descriptions {
            guard let constraint = description.constraint else {
                continue
            }
            constraints.append(constraint)
        }
        for constraint in constraints {
            constraint.activateIfNeeded(updatingExisting: false)
        }
    }

首先将要添加约束的对象封装成ConstraintMaker对象,再把它作为参数调用closure,开始添加约束。closure中的每条语句会先被解析ConstraintDescription对象,添加到maker的descripti

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【OC底层】OC对象本质,如 isa, su.. 下一篇snapkit更新约束崩溃的问题

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目