как переопределить fun c compareValueForKeyPath в Swift 5.2 - Xcode версии 11.5 - PullRequest
1 голос
/ 10 июля 2020

Я пытаюсь портировать эту интерактивную площадку на Swift 5.2 - Xcode Version 11.5 , но у меня все еще есть Method does not override any method from its superclass, и я все еще не понял как установить эту подпись метода. Класс, над которым я работаю, расширяет UIView от UIKit.

Я просмотрел Cmd+Shit+O заголовок NSKeyValueObserving.h и нашел:

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;

С тех пор я безуспешно пробовал:

    public override func observeValueForKeyPath(keyPath: String!, 
    ofObject object: AnyObject!, 
    change: [String : AnyObject]!, 
    context: UnsafeMutablePointer<()>)
    
    public override func observeValueForKeyPath(keyPath: String!, 
    ofObject object: AnyObject!, 
    change: [String : AnyObject]!, 
    context: UnsafeMutableRawPointer)
    
    public override func observeValueForKeyPath(keyPath: String!, 
    of object: Any?, 
    change: [NSKeyValueChangeKey : Any]?, 
    context: UnsafeMutableRawPointer?)

подробнее о классе, над которым я работаю

import UIKit
import XCPlayground

public class NewtonsCradle: UIView  {
    
    private let colors: [UIColor]
    private var balls: [UIView] = []
    
    private var animator: UIDynamicAnimator?
    private var ballsToAttachmentBehaviors: [UIView:UIAttachmentBehavior] = [:]
    private var snapBehavior: UISnapBehavior?
    
    public let collisionBehavior: UICollisionBehavior
    public let gravityBehavior: UIGravityBehavior
    public let itemBehavior: UIDynamicItemBehavior
    
    public init(colors: [UIColor]) {
        self.colors = colors
        collisionBehavior = UICollisionBehavior(items: [])
        gravityBehavior = UIGravityBehavior(items: [])
        itemBehavior = UIDynamicItemBehavior(items: [])
    
        super.init(frame: CGRect(x: 0, y: 0, width: 480, height: 320))
        backgroundColor = UIColor.white
        animator = UIDynamicAnimator(referenceView: self)
        animator?.addBehavior(collisionBehavior)
        animator?.addBehavior(gravityBehavior)
        animator?.addBehavior(itemBehavior)
        
        createBallViews()
    }
    
    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        for ball in balls {
            ball.removeObserver(self, forKeyPath: "center")
        }
    }

   /* SNIP */

   public override func observeValueForKeyPath(keyPath: String!, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if (keyPath == "center") {
            setNeedsDisplay()
        }
    }
  /* SNIP */

1 Ответ

1 голос
/ 10 июля 2020

Ваши переопределения должны выглядеть так. Для этого требуется, чтобы ваши параметры были необязательными.

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    // Do your work here.
}

Когда бы это ни происходило, посмотрите на определение этого метода по CMD+SHFT+O, чтобы просмотреть определение и убедиться, что ваши параметры соответствуют ожидаемым. Я считаю, что это более новая версия Swift, чем ваш вариант использования, однако она все равно должна применяться.

...