使滚动视图内容重新居中 Swift

Recenter the scrollview content Swift

当用户当前位置超出屏幕框架时,我正在尝试重新居中滚动视图视图并移动框架。目前我有一个 PDF,我正在显示用户的当前位置,我正在计算框架和滚动视图 zoomScale 以在 PDF 视图上显示当前位置。我已经实现了这个功能。它工作完美,当用户移动时我已经用相同的逻辑绘制路径,但是当用户移动并离开屏幕时我被困在最后一点意味着从移动屏幕隐藏然后我们需要重新居中当前位置。

第一个密码:-

代码:-

override func viewDidLoad() {
    super.viewDidLoad()
    self.initPdfView()
    self.initCurrentLocation()
}

func initPdfView() {
    do {
        let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        if let path = paths.first {
            let fileURL = URL(fileURLWithPath: path).appendingPathComponent("MapBox")
            let document = try PDFDocument.init(at: fileURL)
            pdfController?.page = try document.page(0)
            pdfController?.scrollDelegates = self
            pdfController?.scrollView.layoutSubviews()
        }
    } catch {
        print(error.localizedDescription)
    }
}
   
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let visibleRect = CGRect.init(x: sender.contentOffset.x, y: sender.contentOffset.y, width: sender.contentSize.width*sender.zoomScale, height: sender.contentSize.height*sender.zoomScale)
    self.visibleScrollViewRect = visibleRect
    self.zooomLevel = sender.zoomScale
}

func initCurrentLocation() {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    
    if CLLocationManager.locationServicesEnabled() {
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startUpdatingLocation()
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
    self.currentLocation = locValue
}

截图:-

第一个屏幕截图中,我显示了用户的当前位置。

First Screenshot

第二个屏幕截图中,我在用户当前位置的帮助下绘制路径。

Second Screenshot

第三个屏幕截图中,当用户移动并离开屏幕时意味着从移动屏幕隐藏。

Third Screenshot

第二个密码:-

func initMapDataUserView() {
    guard let mapInfoJson = decodeMapInfo(with: "MapBoxUrl") else {
        return
    }
    
let position = CGPoint.init(x: mapInfoJson.rasterXYsize.first!, y: mapInfoJson.rasterXYsize.last!)
let pointerVal: UnsafePointer<Int8>? = NSString(string: mapInfoJson.projection).utf8String
let decoder = GeoDecode()
    decoder.fetchPdfCoordinateBounds(with: position, projection: pointerVal, initialTransform: mapInfoJson.geotransform) { coordinate, error in
        if let error = error {
            debugPrint(error)
        } else {
            guard let coordinate = coordinate else {
                return
            }
            self.coordinatesUserCurrentLocation = coordinate
            self.initCurrentLocation()
        }
      }
   }

  func initPdfView() {
    do {
        let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        if let path = paths.first {
            let fileURL = URL(fileURLWithPath: path).appendingPathComponent("MapBoxUrl")
            let document = try PDFDocument.init(at: fileURL)
            viewPDFController?.page = try document.page(0)
            viewPDFController?.scrollDelegates = self
            viewPDFController?.scrollView.layoutSubviews()
        }
    } catch {
        print(error.localizedDescription)
    }
}


func decodeMapInfo(with value: String) -> MapInfoJson? {
    do {
        guard let valueData = value.data(using: .utf8) else {
            return nil
        }
        let decodedResult = try JSONDecoder().decode(MapInfoJson.self, from: valueData)
        return decodedResult
    } catch {
        print("error: ", error)
    }
    return nil
}

extension MapPreviewViewController: scrollViewActions {

func scrollViewScroll(_ sender: UIScrollView) {
    let visibleRect = CGRect.init(x: sender.contentOffset.x, y: sender.contentOffset.y, width: sender.contentSize.width*sender.zoomScale, height: sender.contentSize.height*sender.zoomScale)
    self.visibleScrollViewRectUserScreen = visibleRect
    self.zooomLevelScrollView = sender.zoomScale
    if coordinatesUserCurrentLocation != nil {
        updateMarkerVisiblityOnPdfView()
      }
   }
}


extension MapPreviewViewController: CLLocationManagerDelegate {

func initCurrentLocation() {
    locationManagerUserTest.delegate = self
    locationManagerUserTest.desiredAccuracy = kCLLocationAccuracyBest
    locationManagerUserTest.requestAlwaysAuthorization()
    
    if CLLocationManager.locationServicesEnabled() {
        locationManagerUserTest.desiredAccuracy = kCLLocationAccuracyBest
        locationManagerUserTest.startUpdatingLocation()
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
    self.currentLocationUser = locValue
    updateMarkerVisiblityOnPdfView()
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    
}

func updateMarkerVisiblityOnPdfView() {
    guard let locValue: CLLocationCoordinate2D = self.currentLocationUser else { return }
    guard let coordinates = coordinatesUserCurrentLocation else { return }
    
    let yFactor = (locValue.longitude - coordinates.minY) / (coordinates.maxY - coordinates.minY)
    let xFactor = (coordinates.maxX - locValue.latitude) / (coordinates.maxX - coordinates.minX)
    
    var positionX: Double = 0.0
    var positionY: Double = 0.0
    
    positionX = (yFactor*Double(visibleScrollViewRectUserScreen!.size.width))/Double(self.zooomLevelScrollView!)
    positionY = (xFactor*Double(visibleScrollViewRectUserScreen!.size.height))/Double(self.zooomLevelScrollView!)
    
    if visibleScrollViewRectUserScreen!.size.width < 1.0 {
        positionX = (yFactor*Double(18))*Double(self.zooomLevelScrollView!)
        positionY = (xFactor*Double(18))*Double(self.zooomLevelScrollView!)
    }
    
    var indexOfExistingImageView: Int?
    
    for index in 0..<viewPDFController!.scrollView.subviews.count {
        if let imageview = viewPDFController!.scrollView.subviews[index] as? UIImageView {
            if imageview.image == currentmarkerImagView.image {
                indexOfExistingImageView = index
            }
        }
    }
    
    self.currentmarkerImagView.center = .init(x: positionX, y: positionY)
    self.viewPDFController!.scrollView.addSubview(currentmarkerImagView)
    self.viewPDFController!.scrollView.bringSubviewToFront(currentmarkerImagView)
    
   }
 }


public protocol scrollViewActions {
func scrollViewScroll(_ sender: UIScrollView)
}

public class PdfViewViewController: UIViewController {
public var scrollView: UIScrollView!
public var overlayView: UIView!
public var contentView: UIView!
public var scrollDelegates: scrollViewActions?

public override func viewDidLoad() {
    super.viewDidLoad()
     
    scrollView.delegate = self
    scrollView.contentInsetAdjustmentBehavior = .never
     }
  }

  extension PdfViewViewController: UIScrollViewDelegate {
 public func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollDelegates?.scrollViewScroll(scrollView)
}

public func scrollViewDidZoom(_ scrollView: UIScrollView) {
    scrollDelegates?.scrollViewScroll(scrollView)
}

public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    scrollDelegates?.scrollViewScroll(scrollView)
}

public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
}

public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
}

public func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
    }
}

更新的屏幕截图:

第一个屏幕截图中,我显示了用户的当前位置。

First Screenshot

第二个屏幕截图中,当用户移动并离开屏幕时意味着从移动屏幕隐藏。

Second Screenshot

问题:谁能解释一下当用户移动并离开屏幕时,如何使当前位置重新居中或移动滚动视图框架。

如有任何帮助,我们将不胜感激。

提前致谢。

嗯,显然,我们无法创建新项目,粘贴您发布的代码,然后 运行 它。

所以...希望这会有所帮助。

滚动视图的 .bounds 是其 .contentSize.

可见矩形

所以,如果我们举这个例子:

  • 创建一个 400x600“mapView”(作为 viewForZooming
  • origin: x: 240, y: 400
  • 添加一个 30x30 的“标记”子视图
  • 使用 200 x 300 帧的滚动视图(黄色背景)
  • 将 mapView 的所有 4 个边都约束到滚动视图的 .contentLayoutGuide

从 1.0 缩放开始看起来像这样(当然,滚动视图框架之外的所有内容都将被隐藏):

滚动视图将具有:

ContentSize: (400.0, 600.0)
Bounds:      (0.0, 0.0, 200.0, 300.0)

如果我们一直滚动到右下角,它将看起来像这样:

与:

ContentSize: (400.0, 600.0)
Bounds:      (200.0, 300.0, 200.0, 300.0)

如果我们放大到 2.0 缩放比例,我们得到:

ContentSize: (800.0, 1200.0)
Bounds:      (0.0, 0.0, 200.0, 300.0)

ContentSize: (800.0, 1200.0)
Bounds:      (600.0, 900.0, 200.0, 300.0)

如果我们放大到 3.0 缩放比例,我们得到:

ContentSize: (1200.0, 1800.0)
Bounds:      (0.0, 0.0, 200.0, 300.0)

ContentSize: (1200.0, 1800.0)
Bounds:      (1000.0, 1500.0, 200.0, 300.0)

如果我们将 out 缩放到 0.5 缩放比例:

ContentSize: (200.0, 300.0)
Bounds:      (0.0, 0.0, 200.0, 300.0)

第一个任务是找出“标记”是否可见...如果是,我们不需要做任何事情。如果它 可见(滚动到框架外),我们希望它居中。

所以,如果我们像这样滚动:

我们可以说:

let r = marker.frame
let isInside = scrollView.bounds.contains(r)

在这种情况下,isInside 将是 true

但是,如果标记 框架之外,如下所示:

我们要定义一个 CGRect 与滚动视图的边界相同的宽度和高度,以标记的中心为中心:

我们可以调用:

scrollView.scrollRectToVisible(r, animated: true)

当然,如果我们的标记视图靠近边缘,像这样:

这是最接近中心的位置。

虽然还不够...

标记视图的框架将始终是它自己的框架 - 它会在滚动视图的缩放比例发生变化时进行缩放。所以,我们需要考虑到这一点:

let r = marker.frame.applying(CGAffineTransform(scaleX: self.scrollView.zoomScale, y: self.scrollView.zoomScale))
let isInside = scrollView.bounds.contains(r)

这是一个完整的示例演示...我们创建了滚动视图大小两倍的“地图视图”,最小缩放:0.5,最大缩放:3.0,排列“标记”模式并使用两个按钮“如果需要突出显示并居中":

注意:仅示例代码 - 并非旨在“生产就绪”:

class CenterInScrollVC: UIViewController, UIScrollViewDelegate {
    
    let scrollView: UIScrollView = {
        let v = UIScrollView()
        return v
    }()
    
    // can be any type of view
    //  using a "Dashed Outline" so we can see its edges
    let mapView: DashView = {
        let v = DashView()
        v.backgroundColor = UIColor(white: 0.9, alpha: 0.5)
        v.color = .blue
        v.style = .border
        return v
    }()

    var mapMarkers: [UIView] = []
    var markerIndex: Int = 0
    
    // let's make the markers 40x40
    let markerSize: CGFloat = 40.0
    
    // percentage of one-half of marker that must be visible to NOT screll to center
    //  1.0 == entire marker must be visible
    //  0.5 == up to 1/4 of marker may be out of view
    //  <= 0.0 == only check that the Center of the marker is in view
    //  can be set to > 1.0 to require entire marker Plus some "padding"
    let pctVisible: CGFloat = 1.0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .systemBackground
        
        // a button to center the current marker (if needed)
        let btnA: UIButton = {
            let v = UIButton()
            v.backgroundColor = .systemRed
            v.setTitleColor(.white, for: .normal)
            v.setTitleColor(.lightGray, for: .highlighted)
            v.setTitle("Center Current if Needed", for: [])
            v.addTarget(self, action: #selector(btnATap(_:)), for: .touchUpInside)
            return v
        }()
        
        // a button to select the next marker, center if needed
        let btnB: UIButton = {
            let v = UIButton()
            v.backgroundColor = .systemRed
            v.setTitleColor(.white, for: .normal)
            v.setTitleColor(.lightGray, for: .highlighted)
            v.setTitle("Go To Marker - 2", for: [])
            v.addTarget(self, action: #selector(btnBTap(_:)), for: .touchUpInside)
            return v
        }()
        
        // add a view with a "+" marker to show the center of the scroll view
        let centerView: DashView = {
            let v = DashView()
            v.backgroundColor = .clear
            v.color = UIColor(red: 0.95, green: 0.2, blue: 1.0, alpha: 0.5)
            v.style = .centerMarker
            v.isUserInteractionEnabled = false
            return v
        }()
        
        [btnA, btnB, mapView, scrollView, centerView].forEach { v in
            v.translatesAutoresizingMaskIntoConstraints = false
        }
        
        [btnA, btnB, scrollView, centerView].forEach { v in
            view.addSubview(v)
        }

        scrollView.addSubview(mapView)
        
        let safeG = view.safeAreaLayoutGuide
        let contentG = scrollView.contentLayoutGuide
        let frameG = scrollView.frameLayoutGuide
        
        NSLayoutConstraint.activate([
            
            // buttons at the top
            btnA.topAnchor.constraint(equalTo: safeG.topAnchor, constant: 20.0),
            btnA.widthAnchor.constraint(equalTo: safeG.widthAnchor, multiplier: 0.7),
            btnA.centerXAnchor.constraint(equalTo: safeG.centerXAnchor),
            
            btnB.topAnchor.constraint(equalTo: btnA.bottomAnchor, constant: 20.0),
            btnB.widthAnchor.constraint(equalTo: btnA.widthAnchor),
            btnB.centerXAnchor.constraint(equalTo: safeG.centerXAnchor),
            
            // let's inset the scroll view to make it easier to distinguish
            scrollView.topAnchor.constraint(equalTo: btnB.bottomAnchor, constant: 40.0),
            scrollView.leadingAnchor.constraint(equalTo: safeG.leadingAnchor, constant: 40.0),
            scrollView.trailingAnchor.constraint(equalTo: safeG.trailingAnchor, constant: -40.0),
            scrollView.bottomAnchor.constraint(equalTo: safeG.bottomAnchor, constant: -40.0),
            
            // overlay "center lines" view
            centerView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            centerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            centerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
            centerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),

            // mapView Top/Leading/Trailing/Bottom to scroll view's CONTENT GUIDE
            mapView.topAnchor.constraint(equalTo: contentG.topAnchor, constant: 0.0),
            mapView.leadingAnchor.constraint(equalTo: contentG.leadingAnchor, constant: 0.0),
            mapView.trailingAnchor.constraint(equalTo: contentG.trailingAnchor, constant: 0.0),
            mapView.bottomAnchor.constraint(equalTo: contentG.bottomAnchor, constant: 0.0),
            
            // let's make the mapView twice as wide and tall as the scroll view
            mapView.widthAnchor.constraint(equalTo: frameG.widthAnchor, multiplier: 2.0),
            mapView.heightAnchor.constraint(equalTo: frameG.heightAnchor, multiplier: 2.0),
            
        ])
        
        // some example locations for the Markers
        let pcts: [[CGFloat]] = [
            
            [0.50, 0.50],
            
            [0.25, 0.50],
            [0.50, 0.25],
            [0.75, 0.50],
            [0.50, 0.75],

            [0.10, 0.15],
            [0.90, 0.15],
            [0.90, 0.85],
            [0.10, 0.85],
            
        ]
        for (i, p) in pcts.enumerated() {
            let v = UILabel()
            v.text = "\(i + 1)"
            v.textAlignment = .center
            v.textColor = .yellow
            v.backgroundColor = .systemBlue
            v.font = .systemFont(ofSize: 15.0, weight: .bold)
            v.translatesAutoresizingMaskIntoConstraints = false
            mapMarkers.append(v)
            mapView.addSubview(v)
            v.widthAnchor.constraint(equalToConstant: markerSize).isActive = true
            v.heightAnchor.constraint(equalTo: v.widthAnchor).isActive = true
            NSLayoutConstraint(item: v, attribute: .centerX, relatedBy: .equal, toItem: mapView, attribute: .trailing, multiplier: p[0], constant: 0.0).isActive = true
            NSLayoutConstraint(item: v, attribute: .centerY, relatedBy: .equal, toItem: mapView, attribute: .bottom, multiplier: p[1], constant: 0.0).isActive = true
        }
        
        scrollView.minimumZoomScale = 0.5
        scrollView.maximumZoomScale = 3.0
        scrollView.delegate = self
        
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // let's start with the scroll view zoomed out
        scrollView.zoomScale = scrollView.minimumZoomScale
        
        // highlight and center (if needed) the 1st marker
        markerIndex = 0
        let marker = mapMarkers[markerIndex % mapMarkers.count]
        highlightMarkerAndCenterIfNeeded(marker, animated: true)
    }

    @objc func btnATap(_ sender: Any?) {
        // to easily test "center if not visible" without changing the "current marker"
        let marker = mapMarkers[markerIndex % mapMarkers.count]
        highlightMarkerAndCenterIfNeeded(marker, animated: true)
    }
    
    @objc func btnBTap(_ sender: Any?) {
        // increment index to the next marker
        markerIndex += 1
        let marker = mapMarkers[markerIndex % mapMarkers.count]
        // center if needed
        highlightMarkerAndCenterIfNeeded(marker, animated: true)
        // update button title
        if let b = sender as? UIButton, let m = mapMarkers[(markerIndex + 1) % mapMarkers.count] as? UILabel, let t = m.text {
            b.setTitle("Go To Marker - \(t)", for: [])
        }
    }
    
    func highlightMarkerAndCenterIfNeeded(_ marker: UIView, animated: Bool) {
        
        // "un-highlight" all markers
        mapMarkers.forEach { v in
            v.backgroundColor = .systemBlue
        }
        // "highlight" the new marker
        marker.backgroundColor = .systemGreen

        // get the marker frame, scaled by zoom scale
        var r = marker.frame.applying(CGAffineTransform(scaleX: self.scrollView.zoomScale, y: self.scrollView.zoomScale))
        
        // inset the rect if we allow less-than-full marker visible
        if pctVisible > 0.0 {
            let iw: CGFloat = (1.0 - pctVisible) * r.width * 0.5
            let ih: CGFloat = (1.0 - pctVisible) * r.height * 0.5
            r = r.insetBy(dx: iw, dy: ih)
        }
        
        var isInside: Bool = true
        
        if pctVisible <= 0.0 {
            // check center point only
            isInside = self.scrollView.bounds.contains(CGPoint(x: r.midX, y: r.midY))
        } else {
            // check the rect
            isInside = self.scrollView.bounds.contains(r)
        }
        
        // if the marker rect (or point) IS inside the scroll view
        //  we don't do anything
        
        // if it's NOT inside the scroll view
        //  center it
        
        if !isInside {
            // create a rect using scroll view's bounds centered on marker's center
            let w: CGFloat = self.scrollView.bounds.width
            let h: CGFloat = self.scrollView.bounds.height
            r = CGRect(x: r.midX, y: r.midY, width: w, height: h).offsetBy(dx: -w * 0.5, dy: -h * 0.5)

            if animated {
                // let's slow down the animation a little
                UIView.animate(withDuration: 0.75, delay: 0.0, options: [.curveEaseInOut], animations: {
                    self.scrollView.scrollRectToVisible(r, animated: false)
                }, completion: nil)
            } else {
                self.scrollView.scrollRectToVisible(r, animated: false)
            }
        }
        
    }

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return mapView
    }
    
}

Edit -- 如代码注释中所述,任何视图都可用于 viewForZooming,但这里是我使用的 DashView 的代码:

class DashView: UIView {
    // border or
    // vertical and horizontal center lines or
    // two lines forming a + in the center
    enum Style: Int {
        case border
        case centerLines
        case centerMarker
    }
    
    public var style: Style = .border {
        didSet {
            setNeedsLayout()
        }
    }

    // solid or dashed
    public var solid: Bool = false
    
    // line color
    public var color: UIColor = .yellow {
        didSet {
            dashLayer.strokeColor = color.cgColor
        }
    }
    
    private let dashLayer = CAShapeLayer()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    private func commonInit() {
        layer.addSublayer(dashLayer)
        dashLayer.strokeColor = color.cgColor
        dashLayer.fillColor = UIColor.clear.cgColor
        dashLayer.lineWidth = 2
        
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        var bez = UIBezierPath()
        switch style {
        case .border:
            bez = UIBezierPath(rect: bounds)
            dashLayer.lineDashPattern = [10, 10]

        case .centerLines:
            bez.move(to: CGPoint(x: bounds.midX, y: bounds.minY))
            bez.addLine(to: CGPoint(x: bounds.midX, y: bounds.maxY))
            bez.move(to: CGPoint(x: bounds.minX, y: bounds.midY))
            bez.addLine(to: CGPoint(x: bounds.maxX, y: bounds.midY))
            dashLayer.lineDashPattern = [10, 10]

        case .centerMarker:
            bez.move(to: CGPoint(x: bounds.midX, y: bounds.midY - 40.0))
            bez.addLine(to: CGPoint(x: bounds.midX, y: bounds.midY + 40.0))
            bez.move(to: CGPoint(x: bounds.midX - 40.0, y: bounds.midY))
            bez.addLine(to: CGPoint(x: bounds.midX + 40.0, y: bounds.midY))
            dashLayer.lineDashPattern = []
        }
        if solid {
            dashLayer.lineDashPattern = []
        }
        dashLayer.path = bez.cgPath
    }
}

我找到了检查和设置 pdf 滚动视图中心的解决方案。

Code:-

 func getCurrentLocMakerOutSideFrameOrNot() {
    var visibleRect = CGRect.init(x: 0, y: 0, width: 0, height: 0)
    visibleRect.origin = scrollView.contentOffset
    visibleRect.size = scrollView.bounds.size
     
    if !visibleRect.intersects(currentmarkerImagView.frame) {
        print("Outer View")
        guard let locValue: CLLocationCoordinate2D = self.currentLocation else { return }
        guard let coordinates = coordinates else { return }
        
        let yFactor = (locValue.longitude - coordinates.minY) / (coordinates.maxY - coordinates.minY)
        let xFactor = (coordinates.maxX - locValue.latitude) / (coordinates.maxX - coordinates.minX)
        
        var positionX: Double = 0.0
        var positionY: Double = 0.0
        
        positionX = (yFactor*Double(visibleScrollViewRectView!.size.width))/Double(self.zooomLevelView!)
        positionY = (xFactor*Double(visibleScrollViewRectView!.size.height))/Double(self.zooomLevelView!)
        
        if visibleScrollViewRectView!.size.width < 1.0 {
            positionX = (yFactor*Double(18))*Double(self.zooomLevelView!)
            positionY = (xFactor*Double(18))*Double(self.zooomLevelView!)
        }

        let centerPoint = CGPoint(x: positionX-190, y: positionY-295)

        UIView.animate(withDuration: 2.5, animations: {
              scrollView.setContentOffset(centerPoint, animated: false)
              scrollView.setZoomScale(self.pdfController!.scrollView.zoomScale/2, animated: false)
         })
    }
}