                 _autoExposeIndicator.transform = CGAffineTransform(scaleX: scale, y: scale).translatedBy(x: -_autoFocusIndicator.bounds.width * 0.5 * (scale - 1.0), y: 0.0)
             }
             
-            
+            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(__animateHideAutoIndicators), object: nil)
             UIView.animate(withDuration: 0.1, animations: { [unowned self] in
                 self._autoFocusIndicator.alpha = 1.0
                 self._autoExposeIndicator.alpha = 1.0

        }
    }
    
    private func _animateContinuousIndicator(_ show: Bool, at point: CGPoint) {
        if show {
            guard _continuousIndicator.isHidden else { return }
            
            _continuousBeginning = Date()
            _continuousIndicator.isHidden = false
            _continuousIndicator.center = point
            _continuousIndicator.alpha = 0.0
            
            let scale: CGFloat = 1.2
            _continuousIndicator.transform = CGAffineTransform(scaleX: scale, y: scale)
            UIView.animate(withDuration: 0.1, animations: { [unowned self] in
                self._continuousIndicator.alpha = 1.0
            }, completion: { (finished) in
                if finished {
                    UIView.animate(withDuration: 0.25, animations: { [unowned self] in
                        self._continuousIndicator.transform = .identity
                    }, completion: { [unowned self] (finished) in
                        if finished {
                            self._twinkle(content: self._continuousIndicator)
                        }
                    })
                }
            })
        } else {
            guard !_continuousIndicator.isHidden else { return }
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + max(0.0, _graceTime - Date().timeIntervalSince(_continuousBeginning)), execute: { [unowned self] in
                self._untwinkle(content: self._continuousIndicator)
                UIView.animate(withDuration: 0.25, delay: 0.4, options: [], animations: { [unowned self] in
                    self._continuousIndicator.alpha = 0.0
                }, completion: { [unowned self] finished in
                    if finished {
                        self._continuousIndicator.isHidden = true
                    }
                })
            })
        }
    }
    
    private func _animateAutoIndicators(_ show: Bool, at point: CGPoint) {
        if show {
            _autoBeginning = Date()
            _autoFocusIndicator.isHidden = false
            _autoExposeIndicator.isHidden = false
            _autoFocusIndicator.alpha = 0.0
            _autoExposeIndicator.alpha = 0.0
            _autoFocusIndicator.center = point
            
            let scale: CGFloat = 1.5
            _autoFocusIndicator.transform = CGAffineTransform(scaleX: scale, y: scale)
            switch point.x {
            case 0...(bounds.width - _autoFocusIndicator.bounds.width * 0.5 - (_paddingOfFocusAndExpose + _autoExposeIndicator.bounds.width)):

            if device.focusMode != .continuousAutoFocus {
                let point = CGPoint(x: 0.5, y: 0.5)
                _focus(using: .continuousAutoFocus, exposure: .continuousAutoExposure, at: point)
            }
        }
    }
    
    @objc
    fileprivate func _handleTapToConfigureDevice(_ sender: UITapGestureRecognizer) {
        guard sender.state == .ended else { return }
        
        let location = sender.location(in: self)
        let point = previewLayer.captureDevicePointOfInterest(for: location)
        
        humanReadingInfos = []
        
        _focus(using: .autoFocus, exposure: .autoExpose, at: point)
        _animateIndicators(show: true, mode: .autoFocus, at: location)
    }
    
    @objc
    fileprivate func _handleLongPressToConfigureDevice(_ sender: UILongPressGestureRecognizer) {
        switch sender.state {
        case .possible: fallthrough
        case .began:
            let location = sender.location(in: self)
            let pointOfInterest = previewLayer.captureDevicePointOfInterest(for: location)
            // _lockFocusAndExpose(at: previewLayer.captureDevicePointOfInterest(for: location))
            _focus(using: .autoFocus, exposure: .autoExpose, at: pointOfInterest, monitorSubjectAreaChange: false)
            _animateScalingContinuousIndicator(at: location)
            humanReadingInfos = ["自动曝光/自动对焦锁定"]
        case .changed: break
            // print("Long press gesture is changing.")
        case .failed: fallthrough
        case .cancelled: fallthrough
        default:
            if let device = videoDevice {
                _animateAutoIndicators(true, at: _continuousIndicator.center, scale: _continuousIndicator.bounds.width / _autoFocusIndicator.bounds.width) { [unowned self] in
                    if device.focusMode == .locked {
                        self._pinAutoIndicators()
                    }
                }
            }
        }
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if context == &_deviceIsAdjustingFocusObserveContext && keyPath == "adjustingFocus" {
            if let adjustingFocus = change?[.newKey] as? Bool, let device = videoDevice {
                print("is adjusting focus: " + adjustingFocus.description)
                let location = previewLayer.pointForCaptureDevicePoint(ofInterest: device.focusPointOfInterest)
                if device.focusMode == .autoFocus {
                    if _focusLongPressGesture.state == .changed {
                        _animateScalingContinuousIndicator(at: location)
                    }
                } else {
                    _animateIndicators(show: adjustingFocus, mode: device.focusMode, at: location)
                }
            }
        } else if context == &_deviceFocusModeObserveContext && keyPath == "focusMode" {
            if let focusMode = change?[.newKey] as? Int, let device = videoDevice {
                print("new focus mode: " + focusMode.description)
                if AVCaptureFocusMode(rawValue: focusMode) == .locked && !device.isAdjustingFocus && _focusLongPressGesture.state != .changed {
                    _animateIndicators(show: true, mode: .locked, at: .zero)
                }
            }
        } else if context == &_deviceFlashActiveObserveContext && keyPath == "flashActive" {
            if let isFlashActive = change?[.newKey] as? Bool {
                print("new flash mode: " + isFlashActive.description)
                if isFlashActive {
                    humanReadingInfos = [[#imageLiteral(resourceName: "flash_auto")], humanReadingInfos].joined().reversed()
                }
            }
        } else {
