Получить положение кнопки элемента панели навигации в Swift - PullRequest
0 голосов
/ 16 января 2020

Я хочу получить позицию (точку) моего элемента навигации, который представляет собой кнопку. Если я смогу получить эту точку, я смогу добавить круг-ориентир в свое приложение. Но я не могу понять эту точку правильно.

let point = searchBarButton.center

или

let point = view.convert(CGPoint(x: searchBarButton.center.x, y: searchBarButton.center.y + UIApplication.shared.statusBarFrame.height), from: view)

y Точка была рассчитана правильно, когда я добавил высоту строки состояния. Но точка x всегда имеет значение 20, и это не имеет смысла. Так как же правильно получить x точку?

Вот мой код и снимок экрана моего приложения.

class ViewController: UIViewController {

    let searchBarButton = UIButton()

    // MARK: - viewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()

        configureNavigationBarItems()

        let added_view: UIView = navigationController?.view ?? view
        let point = added_view.convert(CGPoint(x: searchBarButton.center.x, y: searchBarButton.center.y + UIApplication.shared.statusBarFrame.height), from: added_view)
        addCircle(point: point)

    }

    func configureNavigationBarItems() {

        searchBarButton.setImage(UIImage(named: "icon_search_border"), for: .normal)
        searchBarButton.frame = CGRect.init(x: 0, y: 0, width: 40, height: 40)
        let searchBarButtonItem = UIBarButtonItem.init(customView: searchBarButton)

        self.navigationItem.setRightBarButton(searchBarButtonItem, animated: true)

    }

    func addCircle(point: CGPoint) {

        let overlayView = UIView(frame: self.view.bounds)
        overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        self.navigationController?.view.addSubview(overlayView)

        let circlePath = UIBezierPath(arcCenter: point,
                                      radius: 30,
                                      startAngle: 0.0,
                                      endAngle: 2.0 * .pi,
                                      clockwise: true)

        let path = CGMutablePath()
        path.addPath(circlePath.cgPath)
        path.addRect(overlayView.frame)

        let maskLayer = CAShapeLayer()
        maskLayer.path = path
        maskLayer.fillRule = .evenOdd

        overlayView.layer.mask = maskLayer
        overlayView.layer.masksToBounds = true

    }

}

screenshot

1 Ответ

0 голосов
/ 20 января 2020

Если вы хотите получить доступ к элементам навигационной панели, вы должны получить к ним доступ в viewDidAppear, и это ответ на мой вопрос. Это вдохновлено ответом @ jawadAli.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if let navigationBarSubviews = self.navigationController?.navigationBar.subviews {
        for view in navigationBarSubviews {

            if let findClass = NSClassFromString("_UINavigationBarContentView"),
                view.isKind(of: findClass),
                let barButtonView = self.navigationItem.rightBarButtonItem?.value(forKey: "view") as? UIView {

                let point = barButtonView.convert(barButtonView.center, to: view)
                addCircle(point: CGPoint(x: point.x, y: point.y + UIApplication.shared.statusBarFrame.height))
            }
        }
    }

}

enter image description here

...