9
votes

Obtenez NStextField Sommaire à l'échelle

Comment puis-je avoir l'échelle de texte pour adapter les limites que je l'ai donnée?


0 commentaires

3 Réponses :


21
votes

J'ai fait quelque chose comme ça dans le passé.

-(void)calcFontSizeToFitRect:(NSRect)r {
    float targetWidth = r.size.width - xMargin;
    float targetHeight = r.size.height - yMargin;

    // the strategy is to start with a small font size and go larger until I'm larger than one of the target sizes
    int i;
    for (i=minFontSize; i<maxFontSize; i++) {
        NSDictionary* attrs = [[NSDictionary alloc] initWithObjectsAndKeys:[NSFont fontWithName:currentFontName size:i], NSFontAttributeName, nil];
        NSSize strSize = [string sizeWithAttributes:attrs];
        [attrs release];
        if (strSize.width > targetWidth || strSize.height > targetHeight) break;
    }
    [self setCurrentFontSize:(i-1)];
}


1 commentaires

Toute solution pour les champs de texte multilignes? J'apprécierais!



0
votes

Cette solution appropriée de iOS fonctionne assez bien. Cependant, une chose à noter: Si vous en configurez-le de manière programmatique, vous devez initialiser votre nouveaufield avec un recttoire qui a une largeur et une hauteur, sinon les limites code> renvoie 0.

Voici aussi le Lien où j'ai trouvé cette solution: https://medium.com/@joncardasis/dynamic-text- Redimensionnement-in-Swift-3DA55887BEB3 P>

extension NSFont {
  /**
   Will return the best font conforming to the descriptor which will fit in the provided bounds.
   */
  static func bestFittingFontSize(for text: String, in bounds: CGRect, fontDescriptor: NSFontDescriptor, additionalAttributes: [NSAttributedString.Key: Any]? = nil) -> CGFloat {
    let constrainingDimension = min(bounds.width, bounds.height)
    let properBounds = CGRect(origin: .zero, size: bounds.size)
    var attributes = additionalAttributes ?? [:]

    let infiniteBounds = CGSize(width: CGFloat.infinity, height: CGFloat.infinity)
    var bestFontSize: CGFloat = constrainingDimension

    for fontSize in stride(from: bestFontSize, through: 0, by: -1) {
      let newFont = NSFont(descriptor: fontDescriptor, size: fontSize)
      attributes[.font] = newFont

      let currentFrame = text.boundingRect(with: infiniteBounds, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil)

      if properBounds.contains(currentFrame) {
        bestFontSize = fontSize
        break
      }
    }
    return bestFontSize
  }

  static func bestFittingFont(for text: String, in bounds: CGRect, fontDescriptor: NSFontDescriptor, additionalAttributes: [NSAttributedString.Key: Any]? = nil) -> NSFont {
    let bestSize = bestFittingFontSize(for: text, in: bounds, fontDescriptor: fontDescriptor, additionalAttributes: additionalAttributes)
    // TODO: Safely unwrap this later
    return NSFont(descriptor: fontDescriptor, size: bestSize)!
  }
}

extension NSTextField {
  /// Will auto resize the contained text to a font size which fits the frames bounds.
  /// Uses the pre-set font to dynamically determine the proper sizing
  func fitTextToBounds() {
    guard let currentFont = font else {
      return
    }
    let text = stringValue
    let bestFittingFont = NSFont.bestFittingFont(for: text, in: bounds, fontDescriptor: currentFont.fontDescriptor, additionalAttributes: basicStringAttributes)
    font = bestFittingFont
  }

  private var basicStringAttributes: [NSAttributedString.Key: Any] {
    var attribs = [NSAttributedString.Key: Any]()

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = self.alignment
    paragraphStyle.lineBreakMode = self.lineBreakMode
    attribs[.paragraphStyle] = paragraphStyle

    return attribs
  }
}


0 commentaires

-1
votes
For me label.adjustsFontSizeToFitWidth = true reduces the font size. 

with...


lazy var labelContainerView: UIView =
{   let view = UIView()
    return  view.labelContainerView(view: view, label)   }()


extension UIView {
func anchor(   top: NSLayoutYAxisAnchor?,
                    left: NSLayoutXAxisAnchor?,
                    bottom: NSLayoutYAxisAnchor?,
                    right: NSLayoutXAxisAnchor?,
                    paddingTop: CGFloat,
                    paddingLeft: CGFloat,
                    paddingBottom: CGFloat,
                    paddingRight: CGFloat,
                    width: CGFloat,
                    height: CGFloat     )

    {   translatesAutoresizingMaskIntoConstraints = false

        if let top = top {   self.topAnchor.constraint(equalTo: top, constant: paddingTop).isActive = true   }

        if let left = left {   self.leftAnchor.constraint(equalTo: left, constant: paddingLeft).isActive = true   }

        if let bottom = bottom {   self.bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true   }

        if let right = right {   self.rightAnchor.constraint(equalTo: right, constant: -paddingRight).isActive = true   }

        if width != 0 {   widthAnchor.constraint(equalToConstant: width).isActive = true   }

        if height != 0 {   heightAnchor.constraint(equalToConstant: height).isActive = true    }
    }
}


func labelContainerView(view: UIView, _ label: UILabel) -> UIView

    {   view.addSubview(label)
        label.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

        return view
    }
}

0 commentaires