I have created small project with UIScrollView, UIView and UITextView (hierarchy is also the same.). UIView display as red color and UITextView display as blue color. Then I have added UIFont to with size 14 to UITextView.
Since i want to enalble zoom in/out feature for this, i have added UIScrollViewDelegate to this controller and override viewForZooming method. Then zoom in/out things are working fine except one thing.
When i Zoom IN the screen, i can see Fonts which are in side the UITextView are blurred. I want to keep the font quality according to zoom scale after zoom in finish . So i override scrollViewDidEndZooming and adjust the textView frame size it is not working. After google search i found some answers , but i tried them but couldn't find the solution and most of them are very old answers.
So I kindly requesting from you guys, please, help me to resolve this problem and i really appreciate your feedback and help . I have attached my source code and screenshot for your reference.
Code:
class ViewController: UIViewController {
var scrollView: UIScrollView!
var mainView: UIView!
var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView = UIScrollView(frame: .zero)
scrollView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(scrollView)
NSLayoutConstraint.activate([
scrollView.widthAnchor.constraint(equalTo: self.view.widthAnchor),
scrollView.heightAnchor.constraint(equalTo: self.view.heightAnchor),
])
mainView = UIView(frame: .zero)
mainView.translatesAutoresizingMaskIntoConstraints = false
mainView.backgroundColor = UIColor.red
scrollView.addSubview(mainView)
NSLayoutConstraint.activate([
mainView.widthAnchor.constraint(equalToConstant: 600),
mainView.heightAnchor.constraint(equalToConstant: 400),
mainView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
mainView.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor)
])
textView = UITextView(frame: .zero)
textView.translatesAutoresizingMaskIntoConstraints = false
textView.backgroundColor = UIColor.blue
textView.font = UIFont(name: "Thonburi", size: 14)
textView.text = "Hello World"
textView.textAlignment = .center
mainView.addSubview(textView)
NSLayoutConstraint.activate([
textView.widthAnchor.constraint(equalToConstant: 200),
textView.heightAnchor.constraint(equalToConstant: 40),
textView.centerXAnchor.constraint(equalTo: mainView.centerXAnchor),
textView.centerYAnchor.constraint(equalTo: mainView.centerYAnchor),
])
scrollView.pinchGestureRecognizer?.isEnabled = true
scrollView.maximumZoomScale = 12.0
scrollView.minimumZoomScale = 0.2
scrollView.delegate = self
}
}
extension ViewController: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
if let viewForZoom = scrollView.subviews.filter({$0.tag == 1}).first {
return viewForZoom
} else {
return scrollView.subviews.first
}
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
self.textView.frame = CGRect(origin: textView.frame.origin, size: CGSize(width: textView.frame.width*scale, height: textView.frame.height*scale))
}
}
Finally, I was able to fix this issue using contentScale , it should be update for UIView and layer of the UIView and subviews and sub-layers of the particular UIView. otherwise, it will not be working.
func scaleView( view: UIView, scale: CGFloat ){
view.contentScaleFactor = scale
for vi in view.subviews {
scaleView(view: vi, scale: scale)
}
}
func scaleLayer( layer: CALayer, scale: CGFloat ){
layer.contentsScale = scale
if layer.sublayers == nil {
return
}
for la in layer.sublayers! {
scaleLayer(layer: la, scale: scale)
}
}
We should call the above two methods for UITextView in scrollViewDidEndZooming (which is inherited from UIScrollViewDelegate) method.
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
scaleView(view: textView, scale: scale)
scaleLayer(layer: textView.layer, scale: scale)
}
But for the zoom-out feature, please don't set scale value directly then quality will lose. So need to keep the threshold value, it should be calculated according to your usage.