Измените размер шрифта и рамки с помощью pinchGesture, когда textView isScrollEnabled = false

Я использовал pinchGesture для увеличения и уменьшения масштаба textView, используя приведенный ниже код.

добавил pinchGesture к textView

let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(self.handlePinch))
pinchGesture.delegate = self
view.addGestureRecognizer(pinchGesture)

делегировать

@IBAction func handlePinch(recognizer:UIPinchGestureRecognizer) {
    if let view = recognizer.view as? UITextView {
        view.transform = view.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
        recognizer.scale = 1
    }
}

Результат

введите здесь описание изображения введите здесь описание изображения

Вот возможное решение, которое я применил, но все еще не смог найти идеальное решение.

@IBAction func handlePinch(recognizer:UIPinchGestureRecognizer) {
    if let textView = recognizer.view as? UITextView {
        let font = textView.font!
        var pointSize = font.pointSize
        let fontName = font.fontName
        pointSize = ((recognizer.velocity > 0) ? 1 : -1) * 1 + pointSize;
        if (pointSize < 13) {
            pointSize = 13
        }
        if (pointSize > 100) {
            pointSize = 100
        }
        textView.font = UIFont(name: fontName, size: pointSize)
    }
}

Результат

введите описание изображения здесь

Используя вышеуказанное решение, я успешно могу увеличить размер шрифта, но рамка textView не обновляется, поэтому текст обрезается, потому что рамка textView меньше.

Ожидаемый результат

Шрифт увеличится, а кадр будет обновлен, поэтому он будет выглядеть как простое увеличение и уменьшение масштаба, но без размытия.

Ищем наилучшее возможное решение для увеличения размера шрифта с помощью фрейма, как это делают instagram и snapchat.

Спасибо.


person PinkeshGjr    schedule 12.01.2019    source источник
comment
Глядя на ваши комментарии в ответе, я предполагаю, что вы столкнулись с проблемой с UIFont и с тем, как реализованы векторы пользовательского шрифта. (Я знаю достаточно о создании пользовательского шрифта, чтобы быть опасным.) Две мысли: (1) Знаете ли вы, что ваши источники для решения на самом деле используют консервированный UIFont? Возможно ли, что они создали свой собственный шрифт - у них есть штат сотрудников и ресурсы для этого. (2) Если это не так, возможно ли, что они обходят UIFont, используя UIImage и анимируя? Удачи в выяснении этого.   -  person dfd    schedule 12.01.2019
comment
Нет, я просто хочу увеличивать и уменьшать масштаб textView без размытия шрифта.   -  person PinkeshGjr    schedule 12.01.2019
comment
Я понимаю. Но мне любопытно - вы делаете неверное предположение? Верите ли вы, что Instagram и SnapChat делают то, что, вы думаете,... анимируют изменение размера шрифта без размытия... неправильно? Если вы считаете, что ошибаетесь, то почему? Знаете ли вы - опять же, я знаю достаточно, чтобы быть опасным - внутренности UIFont до такой степени, что вы знаете, что это можно сделать? Это то, что я вижу, это ваше базовое предположение.   -  person dfd    schedule 12.01.2019
comment
Тогда как они могут реализовать такую ​​функциональность?   -  person PinkeshGjr    schedule 12.01.2019
comment
Смотрите мое редактирование моих комментариев и объедините их с моим первым комментарием. Возможно, они используют пользовательский UIFont — у них наверняка есть ресурсы для создания растеризованного алфавита, который может это сделать — или, может быть, они нашли более простой способ — использовать UIImage для расширения/сжатия текстового поля без размытия, а затем показывать готовое текстовое поле. Вы задаете отличный вопрос — я проголосовал за него — и я просто думаю нестандартно, потому что пока ни у кого нет ответа.   -  person dfd    schedule 12.01.2019


Ответы (3)


Вот код для изменения размера шрифта вместе с рамкой при увеличении/уменьшении масштаба с помощью UITextView и isScrollEnabled = false

@objc func pinchRecoginze(_ pinchGesture: UIPinchGestureRecognizer) {
   guard recognizer.view != nil, let view = recognizer.view else {return}

    if view is UITextView {
        let textView = view as! UITextView
        if recognizer.state == .began {
            let font = textView.font
            let pointSize = font!.pointSize
            recognizer.scale = pointSize * 0.1
        }
        if 1 <= recognizer.scale && recognizer.scale <= 10  {
            textView.font = UIFont(name: textView.font!.fontName, size: recognizer.scale * 10)
            let textViewSiSize = textView.intrinsicContentSize
            textView.bounds.size = textViewSiSize
        }
    }
}

Меньший размер шрифта

Увеличьте масштаб, чтобы увеличить размер шрифта

Обновлен ответ на совместимость с UITextView

person Bhavik Modi    schedule 16.01.2019
comment
я также могу сделать то же самое, используя UILabel, поэтому я упомянул, что мне нужно добиться этого, используя textView с isScrollEnabled = false - person PinkeshGjr; 16.01.2019
comment
@PinkeshGjr Проверить обновленный ответ для UITextView - person Bhavik Modi; 16.01.2019
comment
попробуйте использовать несколько строк - person PinkeshGjr; 16.01.2019
comment
Я пробовал и тестировал несколько строк текста, и он отлично работает. Пожалуйста, дайте мне знать, если это не работает с вашей настройкой. - person Bhavik Modi; 16.01.2019

Вот изменение размера шрифта и рамки с помощью pinchGesture, когда textView isScrollEnabled = false.

@IBAction func handlePinch(recognizer:UIPinchGestureRecognizer) {
        if let view = recognizer.view {
            if view is UITextView {
                let textView = view as! UITextView
                if textView.font!.pointSize * recognizer.scale < 90 {
                    let font = UIFont(name: textView.font!.fontName, size: textView.font!.pointSize * recognizer.scale)
                    textView.font = font
                    let sizeToFit = textView.sizeThatFits(CGSize(width: UIScreen.main.bounds.size.width,
                                                                 height:CGFloat.greatestFiniteMagnitude))
                    textView.bounds.size = CGSize(width: textView.intrinsicContentSize.width,
                                                  height: sizeToFit.height)
                } else {
                    let sizeToFit = textView.sizeThatFits(CGSize(width: UIScreen.main.bounds.size.width,
                                                                 height:CGFloat.greatestFiniteMagnitude))
                    textView.bounds.size = CGSize(width: textView.intrinsicContentSize.width,
                                                  height: sizeToFit.height)
                }
                textView.setNeedsDisplay()
            } else {
                view.transform = view.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
            }
            recognizer.scale = 1
        }
    }
person PinkeshGjr    schedule 17.01.2019
comment
Это создает проблему расширения кадра при увеличении размера шрифта с масштабированием с помощью одной строки текста. - person Bhavik Modi; 21.01.2019
comment
@BhavikModi Как мы можем это исправить? - person PinkeshGjr; 21.01.2019
comment
Спасибо @BhavikModi - person PinkeshGjr; 21.01.2019

Что, если вы попытаетесь включить прокрутку в начале вашего метода handlePinch и снова отключить ее в конце сжатия?:

@IBAction func handlePinch(recognizer:UIPinchGestureRecognizer) {
  if let textView = recognizer.view as? UITextView {
    textView.isScrollingEnabled = true
    let font = textView.font!
    var pointSize = font.pointSize
    let fontName = font.fontName
    pointSize = ((recognizer.velocity > 0) ? 1 : -1) * 1 + pointSize;
    if (pointSize < 13) {
        pointSize = 13
    }
    if (pointSize > 100) {
        pointSize = 100
    }
    textView.font = UIFont(name: fontName, size: pointSize)
    let width = view.frame.size.width
    textView.frame.size = textView.sizeThatFits(CGSize(width: width, height: CGFloat.greatestFiniteMagnitude))
    textView.isScrollingEnabled = false
  }
}
person emrepun    schedule 12.01.2019
comment
Да, но это не изменит фрейм textView, поэтому при увеличении шрифта он не будет виден, потому что фрейм textView такой же, как и старый - person PinkeshGjr; 12.01.2019
comment
Я отредактировал свой ответ, что, если вы вызовете sizeToFit в textView после изменения шрифта? - person emrepun; 12.01.2019
comment
textView.sizeToFit() не будет увеличивать ширину - person PinkeshGjr; 12.01.2019
comment
Да, вы правы, я считаю, что это можно решить с помощью метода sizeThatFit. Можете ли вы проверить мой обновленный ответ? - person emrepun; 12.01.2019
comment
Да, но это обходной путь только потому, что когда уровень масштабирования достигает ширины основного вида, положение текста изменится, поэтому оно не будет выглядеть как увеличение-уменьшение масштаба. - person PinkeshGjr; 12.01.2019
comment
Что, если вы анимируете этот процесс? Можешь попробовать? Это все еще не было бы идеально, но, возможно, выглядело бы хорошо. - person emrepun; 12.01.2019
comment
Нет, я хочу, чтобы это выглядело очень просто, как увеличение, уменьшение, но оно не должно быть размытым. - person PinkeshGjr; 12.01.2019