Search code examples
macoscocoanslayoutconstraint

macOS: Cannot center NSTextField inside custom NSView based class


I am creating a custom NSView based class with this code.

import Foundation
import AppKit

@IBDesignable
class MacBotaoMudaDeCor : NSView {

  lazy var etiqueta: NSTextField = {
    let etiquetax = NSTextField()
    etiquetax.textColor = corLigada


    let xConstraint = NSLayoutConstraint(item: etiquetax,
                                         attribute: .centerX,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .centerX,
                                         multiplier: 1,
                                         constant: 0)

    let yConstraint = NSLayoutConstraint(item: etiquetax,
                                         attribute: .centerY,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .centerX,
                                         multiplier: 1,
                                         constant: 0)
    self.addConstraint(xConstraint)
    self.addConstraint(yConstraint)

    etiquetax.integerValue = self.numeroBotao
    etiquetax.sizeToFit()

    self.addSubview(etiquetax)
    return etiquetax
  }()


  // creates a CALayer() and sets it to the layer property of the view
  var mainLayer: CALayer{
    get{
      if layer == nil{
        layer = CALayer()
      }
      return layer!
    }
  }

  @IBInspectable var cornerRadius: CGFloat = 0 {
    didSet {
      mainLayer.cornerRadius = cornerRadius
      mainLayer.masksToBounds = cornerRadius > 0
    }
  }

  @IBInspectable var borderWidth: CGFloat = 0 {
    didSet {
      mainLayer.borderWidth = borderWidth
    }
  }

  @IBInspectable var borderColor: NSColor? {
    didSet {
      mainLayer.borderColor = borderColor?.cgColor
    }
  }

  @IBInspectable var corDesligada: NSColor = NSColor.white
  @IBInspectable var corLigada: NSColor = NSColor.black


  @IBInspectable var ligado: Bool = false {
    didSet {
      self.ajustar(corFundo: ligado ? self.corLigada : self.corDesligada)
    }
  }

  @IBInspectable var numeroBotao: Int = 0 {
    didSet {
      etiqueta.integerValue = numeroBotao
    }
  }


  override init(frame frameRect: NSRect) {
    super.init(frame: frameRect)
    self.ajustar(corFundo: corDesligada)
    self.ajustar(corEtiqueta: corLigada)
  }

  required init?(coder decoder: NSCoder) {
    super.init(coder: decoder)
    self.ajustar(corFundo: corDesligada)
    self.ajustar(corEtiqueta: corLigada)
  }

  override func awakeFromNib() {
    self.ajustar(corFundo: corDesligada)
    self.ajustar(corEtiqueta: corLigada)
  }


  func ajustar(corFundo:NSColor) {
    mainLayer.backgroundColor = corFundo.cgColor
  }


  func ajustar(corEtiqueta:NSColor) {
    etiqueta.textColor = corLigada
  }

}

The idea is to have a NSTextField centered on the view that this class represents.

Xcode crashes trying to install the constraints with this message.

2019-06-26 06:08:42.341770+0100 Failed to set (contentViewController) user defined inspected property on (NSWindow): Constraint improperly relates anchors of incompatible types:


Solution

  • addConstraint(_:):

    The constraint must involve only views that are within scope of the receiving view.

    Add the view before adding the constraints.