2017-05-19 53 views
0

我想这样做:如何从开关盒中获取NSLayoutAnchor?

public enum LayoutEdge 
{ 
    case top 
    case right 
    ... 
} 

func anchorForLayoutEdge(_ edge : LayoutEdge) -> NSLayoutAnchor { 
    switch edge 
    { 
    case .top:  return topAnchor 
    case .right: return rightAnchor 
    ... 
    } 
} 

public func constrain_edge(_ edge : LayoutEdge, 
          toEdge : LayoutEdge, 
          view : UIView) -> NSLayoutConstraint{ 
    let a1 = anchorForLayoutEdge(edge) 
    let a2 = anchorForLayoutEdge(toEdge) 
    return a1.constraint(equalTo: a2)) 
} 

但是,这并不编译。它在anchorForLayoutEdge中失败。 Xcode建议将返回类型更改为NSLayoutAnchor,这似乎是错误的。我怎样才能使它返回正确的NSLayoutXAxisAnchorNSLayoutYAxisAnchor,具体取决于指定的边缘?

回答

1

斯威夫特需要能够确定类型在编译时间,但你试图返回根据 传递edge参数要么 NSLayoutAnchor<NSLayoutXAxisAnchor>NSLayoutAnchor<NSLayoutYAxisAnchor>对象。

什么你要做的就是在您的边缘分成与x轴和y轴的边缘:

extension UIView 
{ 
    public enum XLayoutEdge { 
     case right 
     // ... 
    } 

    public enum YLayoutEdge { 
     case top 
     // ... 
    } 

    func anchor(for edge: XLayoutEdge) -> NSLayoutAnchor<NSLayoutXAxisAnchor> { 
     switch edge 
     { 
     case .right: return rightAnchor 
     // ... 
     } 
    } 

    func anchor(for edge: YLayoutEdge) -> NSLayoutAnchor<NSLayoutYAxisAnchor> { 
     switch edge 
     { 
     case .top: return topAnchor 
     // ... 
     } 
    } 

    public func constrain(edge edge1: XLayoutEdge, to edge2: XLayoutEdge, of view: UIView) -> NSLayoutConstraint { 
     return anchor(for: edge1).constraint(equalTo: view.anchor(for: edge2)) 
    } 

    public func constrain(edge edge1: YLayoutEdge, to edge2: YLayoutEdge, of view: UIView) -> NSLayoutConstraint { 
     return anchor(for: edge1).constraint(equalTo: view.anchor(for: edge2)) 
    } 

    func useEdges(view: UIView) 
    { 
     _ = constrain(edge: .right, to: .right, of: view) 
     _ = constrain(edge: .top, to: .top, of: view) 
    } 
} 

它会变得更糟,因为你将不得不考虑NSLayoutDimension了。你可以玩泛型 ,但你可能最终会以某种方式复制Apple已经为你设置的地方:)。

这就是为什么我认为你在这里对付系统。退后一步,为什么不直接使用锚?

extension UIView 
{ 
    func useAnchors(view: UIView) 
    { 
     _ = rightAnchor.constraint(equalTo: view.rightAnchor) 
     _ = topAnchor.constraint(equalTo: view.bottomAnchor) 
    } 
} 

如果你想写自己方便的功能,你可以做这样的:

extension UIView 
{ 
    public func constrain<T>(_ anchor1: NSLayoutAnchor<T>, to anchor2: NSLayoutAnchor<T>) -> NSLayoutConstraint { 
     return anchor1.constraint(equalTo: anchor2) 
    } 

    func useYourOwnFunctions(view: UIView) 
    { 
     _ = constrain(rightAnchor, to: view.rightAnchor) 
     _ = constrain(topAnchor, to: view.bottomAnchor) 
    } 
}