Augmentez ou réduisez la taille de la police en douceur chaque fois que l'utilisateur redimensionne l'étiquette à l'aide d'un geste de pincement.
Remarque
extension String { func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: UIFont(name: font.fontName, size: font.pointSize)!], context: nil) return ceil(boundingBox.height) } func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height) let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: UIFont(name: font.fontName, size: font.pointSize)!], context: nil) return ceil(boundingBox.width) } } func resizeLabelToText(textLabel : UILabel) { let labelFont = textLabel.font let labelString = textLabel.text let labelWidth : CGFloat = labelString!.width(withConstrainedHeight: textLabel.frame.size.height, font: labelFont!) let labelHeight : CGFloat = labelString!.height(withConstrainedWidth: labelWidth, font: labelFont!) textLabel.frame = CGRect(x: textLabel.frame.origin.x, y: textLabel.frame.origin.y, width: labelWidth, height: labelHeight) textLabel.font = labelFont } func pinchedRecognize(_ pinchGesture: UIPinchGestureRecognizer) { guard pinchGesture.view != nil else {return} if (pinchGesture.view is UILabel) { let selectedTextLabel = pinchGesture.view as! UILabel if pinchGesture.state == .began || pinchGesture.state == .changed { let pinchScale = round(pinchGesture.scale * 1000) / 1000.0 if (pinchScale < 1) { selectedTextLabel.font = selectedTextLabel.font.withSize(selectedTextLabel.font.pointSize - pinchScale) } else { selectedTextLabel.font = selectedTextLabel.font.withSize(selectedTextLabel.font.pointSize + pinchScale) } resizeLabelToText(textLabel: selectedTextLabel) } } }
3 Réponses :
Appelez la méthode suivante à chaque fois après le changement de taille d'UILabel.
func labelSizeHasBeenChangedAfterPinch(_ label:UILabel, currentSize:CGSize){ let MAX = 25 let MIN = 8 let RATE = -1 for proposedFontSize in stride(from: MAX, to: MIN, by: RATE){ let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin) let attribute = [NSAttributedString.Key.font:UIFont.systemFont(ofSize: CGFloat(proposedFontSize))] // let context = IF NEEDED ... let rect = NSString(string: label.text ?? "").boundingRect(with: currentSize, options: options, attributes: attribute, context: nil) let labelSizeThatFitProposedFontSize = CGSize(width: rect.width , height: rect.height) if (currentSize.height > labelSizeThatFitProposedFontSize.height) && (currentSize.width > labelSizeThatFitProposedFontSize.width){ DispatchQueue.main.async { label.font = UIFont.systemFont(ofSize: CGFloat(proposedFontSize)) } break } } }
J'ai essayé cela mais ne fonctionne pas comme prévu. La police devient floue pendant le zoom par pincement et ne rend pas non plus une sortie correcte avec du texte multiligne.
J'ai résolu le problème avec le code suivant qui fonctionne très bien avec tous les aspects mentionnés en question, comme Snapchat et Instagram:
var pointSize: CGFloat = 0 @objc func pinchRecoginze(_ pinchGesture: UIPinchGestureRecognizer) { guard pinchGesture.view != nil else {return} let view = pinchGesture.view! if (pinchGesture.view is UILabel) { let textLabel = view as! UILabel if pinchGesture.state == .began { let font = textLabel.font pointSize = font!.pointSize pinchGesture.scale = textLabel.font!.pointSize * 0.1 } if 1 <= pinchGesture.scale && pinchGesture.scale <= 10 { textLabel.font = UIFont(name: textLabel.font!.fontName, size: pinchGesture.scale * 10) resizeLabelToText(textLabel: textLabel) } } } func resizeLabelToText(textLabel : UILabel) { let labelSize = textLabel.intrinsicContentSize textLabel.bounds.size = labelSize }
solution géniale
Vous devez modifier votre question pour inclure tout le code pertinent sous la forme d'un exemple minimal reproductible . Sans cela, votre question est considérée comme hors sujet ici sur SO
@FE_Tech Mise à jour des détails.