2015-04-11 3 views
1

У меня есть Subview (скажем, MainView) NSView с NSTextField внутри него.Выравнивание NSView внутри NSView с использованием VFL

Примечание: Этот код основан на этом github.repo

MainView назначил инициализатор следующим

init(title : String, layout :NSLayoutAttribute) { 
    innerView = self.createTextField(title)//Text field with stringValue = title 
    mainView.addSubview(innerView) 
    createViewConstrants(innerView, layout: layout) 
} 

компоновка может быть Left, Right или CenterX.
(Внутренний TextView будет центрирован всегда, только Горизонтальное выравнивание может варьироваться)


Следующая функция делает ограничение для целей

func createViewConstrants(view : NSView, layout :NSLayoutAttribute) { 

    let viewMap = ["innerView" : view, "superview" : mainView] 
    var constraints :[AnyObject]! 

    switch layout { 
    case .Left: 
     println("Left") 
     constraints = NSLayoutConstraint.constraintsWithVisualFormat(
      "H:[superview]-(<=1)-[innerView]", 
      options: NSLayoutFormatOptions.AlignAllCenterY, 
      metrics: nil, 
      views: viewMap) 
     mainView.addConstraints(constraints) 

    case .Right: 
     println("Right") 
     constraints = NSLayoutConstraint.constraintsWithVisualFormat(
      "H:[superview]-(<=1)-[innerView]-|", 
      options: NSLayoutFormatOptions.AlignAllCenterY, 
      metrics: nil, 
      views: viewMap) 
     mainView.addConstraints(constraints) 

    case .CenterX: 
     println("Center") 

     constraints = NSLayoutConstraint.constraintsWithVisualFormat(
      "V:[superview]-(<=1)-[innerView]", 
      options: NSLayoutFormatOptions.AlignAllCenterX, 
      metrics: nil, 
      views: viewMap) 
     mainView.addConstraints(constraints) 

     constraints = NSLayoutConstraint.constraintsWithVisualFormat(
      "H:[superview]-(<=1)-[innerView]", 
      options: NSLayoutFormatOptions.AlignAllCenterY, 
      metrics: nil, 
      views: viewMap) 
     mainView.addConstraints(constraints) 

    default: 
     fatalError("Invalid layout") 

    } 
} 

Юстировка Right и Center работают нормально, но Align left является не работает.

Также, поскольку вертикальное центрирование является общим для всех случаев, оно может быть выведено из корпуса коммутатора?

ответ

2

Несколько вопросов:

  1. Вы обычно не перечисляют в SuperView явно в VFL. Скорее, вы используете символ вертикальной линии (|). Это:

    H:[superview]-(<=1)-[innerView] 
    

    не означает, что передний край innerView «s меньше, чем 1 точка„после“переднего края SuperView в. Это означает, что передняя кромка innerView меньше, чем 1 балл после того, как верхняя граница супервизора заканчивается краеугольным камнем, который может помещать innerView вне пределов его супервизора, что приведет к его обрезанию.

  2. Если это единственные ограничения, которые вы добавляете, которые влияют на innerView, тогда ваш макет неоднозначен. Неравенство позволяет любому из возможных значений, и система не имеет надежного способа выбора одного из этих значений над любым другим.

  3. Вы не можете выразить центрирование в VFL. Вы можете передать флаг выравнивания в constraintsWithVisualFormat(_:options:metrics:views:) (как вам известно), но a) это не является частью языка визуального формата как такового, и b) вы не можете этого сделать, не создавая некоторые фиктивные, нежелательные ограничения в другая ориентация. То есть вы не можете использовать флаг выравнивания, чтобы центрировать вещи по вертикали, если вы также не создаете ложные горизонтальные ограничения. (И наоборот). Это связано с тем, что флаги выравнивания применимы только к представлениям, перечисленным в строке VFL, а строка VFL всегда подразумевает ограничения.

  4. Почему вы настаиваете на использовании VFL? Если вы используете init(item:attribute:relatedBy:toItem:attribute:multiplier:constant:), вы можете просто пройти по параметру layout, который получает ваш метод. Не было бы необходимости в switch с несколькими случаями. Вы бы просто сделали:

    var constraint = NSLayoutConstraint(item: innerView, 
               attribute: layout, 
               relatedBy: .Equal, 
                toItem: mainView, 
               attribute: layout 
               multiplier: 1, 
               constant: 0) 
    mainView.addConstraint(constraint) 
    constraint = NSLayoutConstraint(item: innerView, 
              attribute: .CenterY, 
              relatedBy: .Equal, 
               toItem: mainView, 
              attribute: .CenterY 
              multiplier: 1, 
              constant: 0) 
    mainView.addConstraint(constraint) 
    

    Это будет обрабатывать все три случая.

Смежные вопросы