Почему Core Animation имеет задержку по сравнению с Core Graphics?IOS

Программируем под IOS
Ответить
Anonymous
 Почему Core Animation имеет задержку по сравнению с Core Graphics?

Сообщение Anonymous »

Я пытаюсь реализовать собственный UISlider на устройстве iOS.
Во-первых, ThumbSlider располагается на обоих концах, и желаемое поведение выглядит следующим образом: Когда ThumbSlider перемещается влево или верно, TopView между ними должен расширяться или сжиматься одновременно.
Приведенное выше представление работает правильно, когда TopView реализован как UIView.
TopView как UIView
Аналогично, он также хорошо работает при использовании базовой графики.
TopView в качестве базовой графики
Однако , когда TopView реализован с использованием базовой анимации, между ThumbSlider и анимацией возникает заметная задержка.
TopView как базовая анимация
Такое поведение совершенно отличается от того, что я ожидал. Хотя я понимаю, что UIView, вероятно, оптимизирован для такого рода операций, я не могу понять, почему Core Animation вводит задержку по сравнению с Core Graphics.
Вот мои последние вопросы:
  • Почему Core Animation отрисовывается медленнее, чем UIView?
    Почему Core Graphics (на базе ЦП) быстрее, чем Core Animation?
final class EditSliderBar: UIControl {
enum Constants {
static let sliderWidth: CGFloat = 16
}

// MARK: - UI Components
private let lowerThumbSlider = EditSlider(tintColor: .systemYellow)
private let upperThumbSlider = EditSlider(tintColor: .systemYellow)
private let topView = UIView()
private let topLayer = CALayer()
weak var currentHighlightedThumbSlider: EditSlider?

private var previousLocation: CGPoint = .zero
private var minimumValue: Double = 0
private var maximumValue: Double = 100

...

private(set) var lowerValue: Double = 0.0 {
didSet {
updateSliderFrame(lowerThumbSlider)
}
}

private(set) var upperValue: Double = 100 {
didSet {
updateSliderFrame(upperThumbSlider)
}
}

...

// MARK: - UIControl
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
let location = touch.location(in: self)
defer { previousLocation = location }

if lowerSlider.contain(point: location) {
lowerSlider.isHightlighted = true
currentHighlightedSlider = lowerSlider
} else if upperSlider.contain(point: location) {
upperSlider.isHightlighted = true
currentHighlightedSlider = upperSlider
}

return lowerSlider.isHightlighted || upperSlider.isHightlighted
}

override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
let location = touch.location(in: self)
defer { previousLocation = location }

guard let slider = currentHighlightedThumbSlider else { return false }

let sliderDeltaValue = deltaValue(from: previousLocation, to: location)

if slider === lowerThumbSlider {
self.lowerValue = updatedLowerValue(moved: sliderDeltaValue)
} else if slider === upperThumbSlider {
self.upperValue = updatedUpperValue(moved: sliderDeltaValue)
}
sendActions(for: .valueChanged)
return true
}

override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
...
}

// MARK: - LayoutSubviews
override func layoutSubviews() {
super.layoutSubviews()
updateSliderFrames()
}

// MARK: - Draw
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }

let maskedRect = CGRect(
x: lowerSlider.center.x,
y: 0,
width: upperThumbSlider.center.x - lowerThumbSlider.center.x,
height: 5
)

context.setFillColor(UIColor.systemYellow.cgColor)
context.fill(maskedRect)
}
}

// MARK: - Private Methotds
private extension EditSliderBar {
func updateSliderFrames() {
updateSliderFrame(lowerThumbSlider)
updateSliderFrame(upperThumbSlider)
}

func updateSliderFrame(_ slider: EditSlider) {
let width = Constants.sliderWidth

let leading = slider === lowerThumbSlider ? leading(of: lowerValue) : leading(of: upperValue)

slider.frame = CGRect(
x: leading,
y: 0,
width: width,
height: bounds.height
)
setNeedsDisplay()

/// Core Animation
updateTopLayer()
/// Core Graphics
setNeedsDisplay()
/// UIView
updateTopView()
}

// Core Animation
func updateTopLayer() {
topLayer.frame = CGRect(
x: lowerThumbSlider.center.x,
y: 0,
width: upperThumbSlider.frame.maxX - lowerThumbSlider.center.x,
height: 5
)
topLayer.backgroundColor = UIColor.systemYellow.cgColor
}

// UIView
func updateTopView() {
topView.frame = CGRect(
x: lowerSlider.center.x,
y: 0,
width: upperThumbSlider.frame.maxX - lowerThumbSlider.center.x,
height: 5
)
topView.backgroundColor = UIColor.systemYellow
}

func updatedLowerValue(moved delta: Double) -> Double {
return (lowerValue + delta).bound(lower: minimumValue, upper: upperValue - gapBetweenSliders)
}

func updatedUpperValue(moved delta: Double) -> Double {
return (upperValue + delta).bound(lower: lowerValue + gapBetweenSliders, upper: maximumValue)
}

func deltaValue(from previous: CGPoint, to current: CGPoint) -> Double {
let deltaLocation = Double(current.x - previous.x)

return (maximumValue - minimumValue) * deltaLocation / Double(totalLength)
}

func leading(of value: Double) -> Double {
return totalLength * value / maximumValue
}
}


Подробнее здесь: https://stackoverflow.com/questions/792 ... e-graphics
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»